     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: 30/11/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[EA69]              	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[846C]              	mov	[mem_1m_1k], cx
   171 00000017 8916[866C]              	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 v2 - diskinit.s - 26/01/2020
   216                              <1> ; Last Modification: 11/10/2021
   217                              <1> ; ----------------------------------------------------------------------------
   218                              <1> ;
   219                              <1> ; Retro UNIX 386 v1 Kernel - DISKINIT.INC (04/02/2016)
   220                              <1> 
   221                              <1> ; DISK I/O SYSTEM INITIALIZATION - Erdogan Tan (Retro UNIX 386 v1 project)
   222                              <1> 
   223                              <1> ; ///////// DISK I/O SYSTEM STRUCTURE INITIALIZATION ///////////////
   224                              <1> 
   225                              <1> 	; 11/10/2021
   226                              <1> 	; 11/04/2021 - Retro UNIX 386 v2
   227                              <1> 	; 09/07/2016 - TRDOS 386 v2, 'diskinit.s'
   228                              <1> 
   229                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
   230                              <1> ;L0:
   231                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
   232                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
   233 00000072 BA7F00              <1> 	mov	dx, 7Fh
   234                              <1> L1:	
   235 00000075 FEC2                <1> 	inc	dl
   236 00000077 B441                <1> 	mov	ah, 41h ; Check extensions present
   237                              <1> 			; Phoenix EDD v1.1 - EDD v3
   238 00000079 BBAA55              <1> 	mov	bx, 55AAh
   239 0000007C CD13                <1> 	int 	13h
   240 0000007E 721A                <1> 	jc	short L2
   241                              <1> 
   242 00000080 81FB55AA            <1> 	cmp	bx, 0AA55h
   243 00000084 7514                <1> 	jne	short L2
   244 00000086 FE06[ED69]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
   245 0000008A 8816[EC69]          <1>         mov     [last_drv], dl  ; last hard disk number
   246 0000008E BB[7069]            <1> 	mov	bx, hd0_type - 80h
   247 00000091 01D3                <1> 	add	bx, dx	 
   248 00000093 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
   249                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
   250                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
   251                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
   252                              <1>                          ;            (EDD) ready (DPTE ready)
   253                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
   254                              <1>                          ;            (EDD-3)
   255                              <1> 			 ; Bit 4 to 15 - 0, Reserved
   256 00000095 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
   257 00000098 72DB                <1> 	jb	short L1
   258                              <1> L2:
   259                              <1> 	; 23/11/2014
   260                              <1> 	; 19/11/2014
   261 0000009A 30D2                <1> 	xor	dl, dl  ; 0
   262                              <1> 	; 04/02/2016 (esi -> si)
   263 0000009C BE[EE69]            <1> 	mov	si, fd0_type
   264                              <1> L3:
   265                              <1> 	; 14/01/2015
   266 0000009F 8816[EB69]          <1> 	mov	[drv], dl
   267                              <1> 	;
   268 000000A3 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   269 000000A5 CD13                <1> 	int	13h	
   270 000000A7 7210                <1> 	jc	short L4
   271                              <1> 		; BL = drive type (for floppy drives)
   272                              <1> 		; DL = number of floppy drives
   273                              <1> 		;		
   274                              <1> 		; ES:DI = Address of DPT from BIOS
   275                              <1> 		;
   276 000000A9 881C                <1> 	mov	[si], bl ;  Drive type
   277                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
   278                              <1> 	; 14/01/2015
   279 000000AB E8B701              <1> 	call	set_disk_parms
   280                              <1> 	; 10/12/2014
   281 000000AE 81FE[EE69]          <1> 	cmp	si, fd0_type
   282 000000B2 7705                <1> 	ja	short L4
   283 000000B4 46                  <1> 	inc	si ; fd1_type
   284 000000B5 B201                <1> 	mov	dl, 1
   285 000000B7 EBE6                <1> 	jmp	short L3
   286                              <1> L4:
   287                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
   288 000000B9 B27F                <1> 	mov	dl, 7Fh
   289                              <1> 	; 24/12/2014 (Temporary)
   290 000000BB 803E[ED69]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
   291 000000C0 0F879000            <1>         ja      L10       ; yes, all fixed disk operations
   292                              <1> 			  ; will be performed according to
   293                              <1> 			  ; present EDD specification
   294                              <1> L6:
   295 000000C4 FEC2                <1> 	inc 	dl
   296 000000C6 8816[EB69]          <1>         mov     [drv], dl
   297 000000CA 8816[EC69]          <1>         mov     [last_drv], dl ; 14/01/2015
   298 000000CE B408                <1> 	mov 	ah, 08h   ; Return drive parameters
   299 000000D0 CD13                <1> 	int	13h	  ; (conventional function)
   300 000000D2 0F828101            <1>         jc      L13	  ; fixed disk drive not ready
   301 000000D6 8816[ED69]          <1>         mov     [hdc], dl ; number of drives
   302                              <1> 	;; 14/01/2013
   303                              <1> 	;;push	cx
   304 000000DA E88801              <1> 	call	set_disk_parms
   305                              <1> 	;;pop	cx
   306                              <1> 	;
   307                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   308 000000DD 8A16[EB69]          <1>         mov     dl, [drv]
   309 000000E1 BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   310 000000E4 80FA80              <1> 	cmp	dl, 80h
   311 000000E7 7603                <1> 	jna	short L7
   312 000000E9 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   313                              <1> L7:	
   314 000000EC 31C0                <1> 	xor	ax, ax
   315 000000EE 8ED8                <1> 	mov	ds, ax
   316 000000F0 8B37                <1>         mov     si, [bx]
   317 000000F2 8B4702              <1>         mov     ax, [bx+2] 
   318 000000F5 8ED8                <1> 	mov	ds, ax
   319 000000F7 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   320 000000FA 0F855501            <1>         jne     L12 ; invalid FDPT
   321 000000FE BF0000              <1> 	mov	di, HD0_DPT
   322 00000101 80FA80              <1> 	cmp	dl, 80h
   323 00000104 7603                <1> 	jna	short L8
   324 00000106 BF2000              <1> 	mov	di, HD1_DPT 
   325                              <1> L8:
   326                              <1> 	; 30/12/2014
   327 00000109 B80090              <1> 	mov	ax, DPT_SEGM
   328 0000010C 8EC0                <1> 	mov	es, ax
   329                              <1> 	; 24/12/2014
   330 0000010E B90800              <1> 	mov	cx, 8
   331 00000111 F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   332 00000113 8CC8                <1> 	mov	ax, cs
   333 00000115 8ED8                <1> 	mov	ds, ax
   334                              <1> 	; 02/02/2015
   335 00000117 8A0E[EB69]          <1>         mov     cl, [drv]
   336 0000011B 88CB                <1> 	mov	bl, cl
   337 0000011D B8F001              <1> 	mov	ax, 1F0h
   338 00000120 80E301              <1> 	and	bl, 1
   339 00000123 7406                <1> 	jz	short L9
   340 00000125 C0E304              <1> 	shl	bl, 4
   341 00000128 2D8000              <1> 	sub	ax, 1F0h-170h
   342                              <1> L9:
   343 0000012B AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   344 0000012C 050602              <1> 	add	ax, 206h
   345 0000012F AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   346 00000130 88D8                <1> 	mov	al, bl
   347 00000132 04A0                <1> 	add	al, 0A0h
   348 00000134 AA                  <1> 	stosb	; Device/Head Register upper nibble
   349                              <1> 	;
   350 00000135 FE06[EB69]          <1> 	inc	byte [drv]
   351 00000139 BB[7069]            <1> 	mov	bx, hd0_type - 80h
   352 0000013C 01CB                <1> 	add	bx, cx
   353 0000013E 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   354 00000141 A0[ED69]            <1> 	mov	al, [hdc]
   355 00000144 FEC8                <1> 	dec	al
   356 00000146 0F840D01            <1>         jz      L13
   357 0000014A 80FA80              <1> 	cmp	dl, 80h
   358 0000014D 0F8673FF            <1>         jna     L6
   359 00000151 E90301              <1>         jmp     L13
   360                              <1> L10:
   361 00000154 FEC2                <1> 	inc 	dl
   362                              <1> 	; 25/12/2014
   363 00000156 8816[EB69]          <1> 	mov	[drv], dl
   364 0000015A B408                <1> 	mov 	ah, 08h ; Return drive parameters
   365 0000015C CD13                <1> 	int	13h	; (conventional function)
   366 0000015E 0F82F500            <1>         jc      L13
   367                              <1> 	; 14/01/2015
   368 00000162 8A16[EB69]          <1> 	mov	dl, [drv]
   369 00000166 52                  <1> 	push	dx
   370 00000167 51                  <1> 	push	cx
   371 00000168 E8FA00              <1> 	call	set_disk_parms
   372 0000016B 59                  <1> 	pop	cx
   373 0000016C 5A                  <1> 	pop	dx
   374                              <1> 	; 11/04/2021 - Retro UNIX 386 v2
   375                              <1> 	; 06/07/2016 (BugFix for >64K kernel files)
   376                              <1> 	; 04/02/2016 (esi -> si)
   377                              <1> 	;mov	si, _end ; 30 byte temporary buffer address
   378                              <1> 	;		 ; at the '_end' of kernel.
   379                              <1> 	;mov	word [si], 30
   380                              <1> 	; 06/07/2016
   381 0000016D BE[5000]            <1> 	mov	si, _int13h_48h_buffer
   382                              <1> 	; 09/07/2016
   383 00000170 B81E00              <1> 	mov	ax, 001Eh
   384 00000173 8824                <1> 	mov	[si], ah ; 0
   385 00000175 46                  <1> 	inc	si
   386 00000176 8904                <1> 	mov	word [si], ax
   387                              <1>  	; word [si] = 30
   388                              <1> 	;
   389 00000178 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   390 0000017A CD13                <1> 	int	13h
   391 0000017C 0F82D700            <1>         jc      L13
   392                              <1> 	; 04/02/2016 (ebx -> bx)
   393                              <1> 	; 14/01/2015
   394 00000180 29DB                <1> 	sub	bx, bx
   395 00000182 88D3                <1> 	mov	bl, dl
   396 00000184 80EB80              <1> 	sub	bl, 80h
   397 00000187 81C3[F069]          <1> 	add	bx, hd0_type
   398 0000018B 8A07                <1> 	mov 	al, [bx]
   399 0000018D 0C80                <1> 	or	al, 80h
   400 0000018F 8807                <1> 	mov 	[bx], al	
   401 00000191 81EB[EE69]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   402                              <1> 	;add	bx, drv.status
   403                              <1> 	;mov	[bx], al
   404 00000195 8887[3A6A]          <1> 	mov	[bx+drv.status], al ; 11/10/2021
   405                              <1> 	; 04/02/2016 (eax -> ax)
   406 00000199 8B4410              <1> 	mov	ax, [si+16]
   407 0000019C 854412              <1> 	test	ax, [si+18]
   408 0000019F 740F                <1> 	jz	short L10_A0h 
   409                              <1> 			; 'CHS only' disks on EDD system 
   410                              <1> 			;  are reported with ZERO disk size
   411                              <1> 	;sub	bx, drv.status
   412 000001A1 C1E302              <1> 	shl	bx, 2
   413 000001A4 81C3[1E6A]          <1> 	add	bx, drv.size ; disk size (in sectors)
   414 000001A8 8907                <1> 	mov	[bx], ax
   415 000001AA 8B4412              <1> 	mov	ax, [si+18]
   416                              <1> 	; 18/04/2021
   417 000001AD 894702              <1> 	mov	[bx+2], ax
   418                              <1> 
   419                              <1> L10_A0h: ; Jump here to fix a ZERO (LBA) disk size problem 
   420                              <1> 	 ; for CHS disks (28/02/2015)
   421                              <1> 	; 30/12/2014
   422 000001B0 BF0000              <1> 	mov	di, HD0_DPT
   423 000001B3 88D0                <1> 	mov	al, dl
   424 000001B5 83E003              <1> 	and 	ax, 3
   425 000001B8 C0E005              <1> 	shl	al, 5 ; *32
   426 000001BB 01C7                <1> 	add 	di, ax
   427 000001BD B80090              <1> 	mov	ax, DPT_SEGM
   428 000001C0 8EC0                <1> 	mov	es, ax
   429                              <1> 	;
   430 000001C2 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   431 000001C4 88CC                <1> 	mov	ah, cl	
   432 000001C6 C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   433 000001C9 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   434 000001CA AB                  <1> 	stosw		
   435 000001CB 88F0                <1> 	mov	al, dh	; max. head number
   436 000001CD FEC0                <1> 	inc	al
   437 000001CF AA                  <1> 	stosb		; logical heads (limits 256)
   438 000001D0 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   439 000001D2 AA                  <1> 	stosb
   440 000001D3 8A440C              <1> 	mov	al, [si+12]
   441 000001D6 AA                  <1> 	stosb		 ; physical sectors per track
   442 000001D7 31C0                <1>  	xor	ax, ax
   443                              <1> 	;dec	ax	 ; 02/01/2015 
   444 000001D9 AB                  <1> 	stosw		 ; precompensation (obsolete)
   445                              <1> 	;xor	al, al	 ; 02/01/2015	
   446 000001DA AA                  <1> 	stosb		 ; reserved
   447 000001DB B008                <1> 	mov	al, 8	 ; drive control byte
   448                              <1> 		         ; (do not disable retries, 
   449                              <1> 			 ; more than 8 heads)
   450 000001DD AA                  <1> 	stosb
   451 000001DE 8B4404              <1> 	mov	ax, [si+4]
   452 000001E1 AB                  <1> 	stosw		 ; physical number of cylinders	
   453                              <1> 	;push	ax	 ; 02/01/2015
   454 000001E2 8A4408              <1> 	mov	al, [si+8]
   455 000001E5 AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   456 000001E6 29C0                <1> 	sub 	ax, ax
   457                              <1> 	;pop	ax	 ; 02/01/2015	
   458 000001E8 AB                  <1> 	stosw		 ; landing zone (obsolete)
   459 000001E9 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   460 000001EB 243F                <1> 	and 	al, 3Fh	
   461 000001ED AA                  <1> 	stosb
   462                              <1> 	;sub	al, al	 ; checksum
   463                              <1> 	;stosb
   464                              <1> 	;
   465 000001EE 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   466 000001F1 AD                  <1> 	lodsw
   467 000001F2 50                  <1> 	push	ax	 ; (BIOS) DPTE offset
   468 000001F3 AD                  <1> 	lodsw
   469 000001F4 50                  <1> 	push	ax	 ; (BIOS) DPTE segment
   470                              <1> 	;
   471                              <1> 	; checksum calculation
   472 000001F5 89FE                <1> 	mov	si, di
   473 000001F7 06                  <1> 	push	es
   474 000001F8 1F                  <1> 	pop	ds
   475                              <1> 	;mov	cx, 16
   476 000001F9 B90F00              <1> 	mov 	cx, 15
   477 000001FC 29CE                <1> 	sub	si, cx
   478 000001FE 30E4                <1> 	xor	ah, ah
   479                              <1> 	;del	cl
   480                              <1> L11:		
   481 00000200 AC                  <1> 	lodsb
   482 00000201 00C4                <1> 	add	ah, al
   483 00000203 E2FB                <1> 	loop	L11
   484                              <1> 	;
   485 00000205 88E0                <1> 	mov	al, ah
   486 00000207 F6D8                <1> 	neg	al	; -x+x = 0
   487 00000209 AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   488                              <1> 	;
   489 0000020A 1F                  <1> 	pop	ds	; (BIOS) DPTE segment
   490 0000020B 5E                  <1> 	pop	si	; (BIOS) DPTE offset	
   491                              <1> 	;
   492                              <1> 	; 23/02/2015
   493 0000020C 57                  <1> 	push	di
   494                              <1> 	; ES:DI points to DPTE (FDPTE) location
   495                              <1> 	;mov	cx, 8
   496 0000020D B108                <1> 	mov	cl, 8
   497 0000020F F3A5                <1> 	rep	movsw	
   498                              <1> 	;
   499                              <1> 	; 23/02/2015
   500                              <1> 	; (P)ATA drive and LBA validation
   501                              <1> 	; (invalidating SATA drives and setting
   502                              <1> 	; CHS type I/O for old type fixed disks)
   503 00000211 5B                  <1> 	pop	bx
   504 00000212 8CC8                <1> 	mov	ax, cs
   505 00000214 8ED8                <1> 	mov	ds, ax
   506 00000216 268B07              <1> 	mov	ax, [es:bx]
   507 00000219 3DF001              <1> 	cmp	ax, 1F0h
   508 0000021C 7418                <1> 	je	short L11a
   509 0000021E 3D7001              <1> 	cmp	ax, 170h
   510 00000221 7413                <1> 	je	short L11a
   511                              <1> 	; invalidation 
   512                              <1> 	; (because base port address is not 1F0h or 170h)
   513 00000223 30FF                <1> 	xor	bh, bh
   514 00000225 88D3                <1> 	mov	bl, dl
   515 00000227 80EB80              <1> 	sub	bl, 80h
   516 0000022A C687[F069]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   517 0000022F 808F[3C6A]F0        <1>         or      byte [bx+drv.status+2], 0F0h ; (failure sign)
   518 00000234 EB14                <1> 	jmp	short L11b
   519                              <1> L11a:	
   520                              <1> 	; LBA validation
   521 00000236 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   522 0000023A A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   523 0000023C 750C                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   524                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   525 0000023E 28FF                <1> 	sub	bh, bh
   526 00000240 88D3                <1> 	mov	bl, dl
   527 00000242 80EB80              <1> 	sub	bl, 80h ; 26/02/2015
   528 00000245 80A7[3C6A]FE        <1>         and     byte [bx+drv.status+2], 0FEh ; clear bit 0
   529                              <1> 				; bit 0 = LBA ready bit
   530                              <1> 	; 'diskio' procedure will check this bit !
   531                              <1> L11b:
   532 0000024A 3A16[EC69]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   533 0000024E 7307                <1>         jnb     short L13
   534 00000250 E901FF              <1>         jmp     L10
   535                              <1> L12:
   536                              <1> 	; Restore data registers
   537 00000253 8CC8                <1> 	mov	ax, cs
   538 00000255 8ED8                <1> 	mov	ds, ax	
   539                              <1> L13:
   540                              <1> 	; 13/12/2014
   541 00000257 0E                  <1> 	push	cs
   542 00000258 07                  <1> 	pop	es
   543                              <1> L14:
   544 00000259 B411                <1> 	mov 	ah, 11h
   545 0000025B CD16                <1> 	int 	16h
   546                              <1> 	;jz 	short L15 ; no keys in keyboard buffer
   547                              <1> 	; 11/04/2021
   548 0000025D 744C                <1> 	jz	short L16
   549                              <1> 	;
   550 0000025F B010                <1> 	mov	al, 10h
   551 00000261 CD16                <1> 	int 	16h
   552 00000263 EBF4                <1> 	jmp 	short L14
   553                              <1> ;L15:
   554                              <1> ; //////
   555                              <1> ;	; 24/11/2014
   556                              <1> ;	; 19/11/2014
   557                              <1> ;	; 14/11/2014
   558                              <1> ;	; Temporary code for disk searching code check
   559                              <1> ;	;
   560                              <1> ;	; This code will show existing (usable) drives and also
   561                              <1> ;	; will show EDD interface support status for hard disks		
   562                              <1> ;	; (If status bit 7 is 1, Identify Device info is ready,
   563                              <1> ;	; no need to get it again in protected mode...) 
   564                              <1> ;	;	
   565                              <1> ;	; 13/11/2014
   566                              <1> ;	mov	bx, 7
   567                              <1> ;	mov	ah, 0Eh
   568                              <1> ;	mov	al, [fd0_type]
   569                              <1> ;	and	al, al
   570                              <1> ;	jz	short L15a
   571                              <1> ;	mov	dl, al
   572                              <1> ;	mov	al, 'F'
   573                              <1> ;	int 	10h
   574                              <1> ;	mov	al, 'D'
   575                              <1> ;	int 	10h
   576                              <1> ;	mov	al, '0'
   577                              <1> ;	int 	10h
   578                              <1> ;	mov	al, ' '
   579                              <1> ;	int	10h
   580                              <1> ;	call	L15c
   581                              <1> ;	mov	al, ' '
   582                              <1> ;	int	10h
   583                              <1> ;	;
   584                              <1> ;	mov	al, [fd1_type]
   585                              <1> ;	and	al, al
   586                              <1> ;	jz	short L15a
   587                              <1> ;	mov	dl, al
   588                              <1> ;	mov	al, 'F'
   589                              <1> ;	int 	10h
   590                              <1> ;	mov	al, 'D'
   591                              <1> ;	int 	10h
   592                              <1> ;	mov	al, '1'
   593                              <1> ;	int 	10h
   594                              <1> ;	mov	al, ' '
   595                              <1> ;	int	10h
   596                              <1> ;	call	L15c
   597                              <1> ;	mov	al, ' '
   598                              <1> ;	int	10h
   599                              <1> ;	mov	al, ' '
   600                              <1> ;	int	10h
   601                              <1> ;L15a:
   602                              <1> ;	mov	al, [hd0_type]
   603                              <1> ;	and	al, al
   604                              <1> ;	jz	short L15b
   605                              <1> ;	mov	dl, al
   606                              <1> ;	mov	al, 'H'
   607                              <1> ;	int 	10h
   608                              <1> ;	mov	al, 'D'
   609                              <1> ;	int 	10h
   610                              <1> ;	mov	al, '0'
   611                              <1> ;	int 	10h
   612                              <1> ;	mov	al, ' '
   613                              <1> ;	int 	10h
   614                              <1> ;	call	L15c
   615                              <1> ;	mov	al, ' '
   616                              <1> ;	int	10h
   617                              <1> ;	;
   618                              <1> ;	mov	al, [hd1_type]
   619                              <1> ;	and	al, al
   620                              <1> ;	jz	short L15b
   621                              <1> ;	mov	dl, al
   622                              <1> ;	mov	al, 'H'
   623                              <1> ;	int 	10h
   624                              <1> ;	mov	al, 'D'
   625                              <1> ;	int 	10h
   626                              <1> ;	mov	al, '1'
   627                              <1> ;	int 	10h
   628                              <1> ;	mov	al, ' '
   629                              <1> ;	int 	10h
   630                              <1> ;	call	L15c
   631                              <1> ;	mov	al, ' '
   632                              <1> ;	int	10h
   633                              <1> ;	;
   634                              <1> ;	mov	al, [hd2_type]
   635                              <1> ;	and	al, al
   636                              <1> ;	jz	short L15b
   637                              <1> ;	mov	dl, al
   638                              <1> ;	mov	al, 'H'
   639                              <1> ;	int 	10h
   640                              <1> ;	mov	al, 'D'
   641                              <1> ;	int 	10h
   642                              <1> ;	mov	al, '2'
   643                              <1> ;	int 	10h
   644                              <1> ;	mov	al, ' '
   645                              <1> ;	int 	10h
   646                              <1> ;	call	L15c
   647                              <1> ;	mov	al, ' '
   648                              <1> ;	int	10h
   649                              <1> ;	;
   650                              <1> ;	mov	al, [hd3_type]
   651                              <1> ;	and	al, al
   652                              <1> ;	jz	short L15b
   653                              <1> ;	mov	dl, al
   654                              <1> ;	mov	al, 'H'
   655                              <1> ;	int 	10h
   656                              <1> ;	mov	al, 'D'
   657                              <1> ;	int 	10h
   658                              <1> ;	mov	al, '3'
   659                              <1> ;	int 	10h
   660                              <1> ;	mov	al, ' '
   661                              <1> ;	int 	10h
   662                              <1> ;	call	L15c
   663                              <1> ;	mov	al, ' '
   664                              <1> ;	int	10h
   665                              <1> ;	;
   666                              <1> ;L15b:
   667                              <1> ;	mov	al, 0Dh
   668                              <1> ;	int 	10h	
   669                              <1> ;	mov	al, 0Ah
   670                              <1> ;	int 	10h
   671                              <1> ;	;;xor	ah, ah
   672                              <1> ;	;;int 	16h	
   673                              <1> ;	;
   674                              <1> ;       jmp     L16  ; jmp short L16
   675                              <1> ;       ;
   676                              <1> ;L15c:
   677                              <1> ;	mov	dh, dl
   678                              <1> ;	shr	dh, 4
   679                              <1> ;	add	dh, 30h
   680                              <1> ;	and	dl, 15
   681                              <1> ;	add	dl, 30h
   682                              <1> ;	mov	al, dh
   683                              <1> ;	int	10h
   684                              <1> ;	mov	al, dl
   685                              <1> ;	int	10h
   686                              <1> ;	retn
   687                              <1> ;	;
   688                              <1> ;	; end of temporary code for disk searching code check
   689                              <1> 
   690                              <1> ; //////
   691                              <1> 
   692                              <1> set_disk_parms:
   693                              <1> 	; 11/10/2021 - Retro UNIX 386 v2
   694                              <1> 	; 04/02/2016 (ebx -> bx)
   695                              <1> 	; 10/07/2015
   696                              <1> 	; 14/01/2015
   697                              <1> 	;push	bx
   698 00000265 28FF                <1> 	sub	bh, bh
   699 00000267 8A1E[EB69]          <1> 	mov	bl, [drv]
   700 0000026B 80FB80              <1> 	cmp	bl, 80h
   701 0000026E 7203                <1> 	jb	short sdp0
   702 00000270 80EB7E              <1> 	sub	bl, 7Eh
   703                              <1> sdp0:	
   704                              <1> 	;add	bx, drv.status
   705                              <1>   	;mov	byte [bx], 80h ; 'Present' flag
   706 00000273 C687[3A6A]80        <1> 	mov	byte [bx+drv.status], 80h
   707                              <1> 	;
   708 00000278 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   709 0000027A 88CC                <1> 	mov	ah, cl ; 
   710 0000027C C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   711                              <1> 	;sub	bx, drv.status
   712 0000027F D0E3                <1> 	shl	bl, 1
   713                              <1> 	;add	bx, drv.cylinders
   714 00000281 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count
   715                              <1> 	;mov	[bx], ax
   716 00000282 8987[F469]          <1> 	mov	[bx+drv.cylinders], ax
   717 00000286 50                  <1> 	push	ax ; ** cylinders
   718                              <1> 	;sub	bx, drv.cylinders
   719                              <1> 	;add	bx, drv.heads
   720 00000287 30E4                <1> 	xor	ah, ah
   721 00000289 88F0                <1> 	mov	al, dh ; heads
   722 0000028B 40                  <1> 	inc	ax
   723                              <1> 	;mov	[bx], ax
   724 0000028C 8987[026A]          <1>         mov	[bx+drv.heads], ax
   725                              <1> 	;sub	bx, drv.heads
   726                              <1>         ;add	bx, drv.spt
   727                              <1> 	;xor	ch, ch
   728                              <1> 	;and	cl, 3Fh	; sectors (bits 0-6)
   729 00000290 83E13F              <1> 	and	cx, 03Fh
   730                              <1> 	;mov	[bx], cx
   731 00000293 898F[106A]          <1>         mov	[bx+drv.spt], cx
   732                              <1> 	;sub	bx, drv.spt
   733 00000297 D1E3                <1> 	shl	bx, 1
   734 00000299 81C3[1E6A]          <1> 	add	bx, drv.size ; disk size (in sectors)
   735                              <1> 	; LBA size = cylinders * heads * secpertrack
   736 0000029D F7E1                <1> 	mul	cx 
   737 0000029F 89C2                <1> 	mov	dx, ax	; heads*spt	
   738 000002A1 58                  <1> 	pop	ax ; ** cylinders
   739 000002A2 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   740 000002A3 F7E2                <1> 	mul	dx ; cylinders * (heads*spt)
   741 000002A5 8907                <1> 	mov	[bx], ax
   742 000002A7 895702              <1> 	mov	[bx+2], dx
   743                              <1> 	;
   744                              <1> 	;pop	bx
   745 000002AA C3                  <1> 	retn
   746                              <1> 
   747                              <1> ;align 2
   748                              <1> 
   749                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   750                              <1> ;heads	   :  dw 0, 0, 0, 0, 0, 0
   751                              <1> ;spt	   :  dw 0, 0, 0, 0, 0, 0
   752                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   753                              <1> 
   754                              <1> ;last_drv:
   755                              <1> ;	db  0
   756                              <1> ;drv_status:
   757                              <1> ;	db  0,0,0,0,0,0
   758                              <1> ;	db  0
   759                              <1> 
   760                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   761                              <1> 
   762                              <1> L16:
   763                                  _L0:	
   764                                  	; 10/11/2014
   765 000002AB FA                           	cli	; Disable interrupts (clear interrupt flag)
   766                                  		; Reset Interrupt MASK Registers (Master&Slave)
   767                                  	;mov	al, 0FFh	; mask off all interrupts
   768                                  	;out	21h, al		; on master PIC (8259)
   769                                  	;jmp 	$+2  ; (delay)
   770                                  	;out	0A1h, al	; on slave PIC (8259)
   771                                  	;
   772                                  	; Disable NMI 
   773 000002AC B080                    	mov   	al, 80h 
   774 000002AE E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   775                                  	;23/02/2015
   776 000002B0 90                      	nop			;
   777                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   778                                  				; for preventing unknown state (!?)
   779                                  	;
   780                                   	; 20/08/2014
   781                                  	; Moving the kernel 64 KB back (to physical address 0)
   782                                  	; DS = CS = 1000h
   783                                  	; 05/11/2014
   784 000002B1 31C0                    	xor	ax, ax
   785 000002B3 8EC0                    	mov	es, ax ; ES = 0
   786                                  	;
   787 000002B5 B90040                  	mov	cx, (KEND - KLOAD)/4
   788 000002B8 31F6                    	xor	si, si
   789 000002BA 31FF                    	xor	di, di
   790 000002BC F366A5                  	rep	movsd
   791                                  	;
   792 000002BF 06                      	push	es ; 0
   793 000002C0 68[C402]                	push	L17
   794 000002C3 CB                      	retf
   795                                  	;
   796                                  L17:
   797                                  	; Turn off the floppy drive motor
   798 000002C4 BAF203                          mov     dx, 3F2h
   799 000002C7 EE                              out     dx, al ; 0 ; 31/12/2013
   800                                  
   801                                  	; Enable access to memory above one megabyte
   802                                  L18:
   803 000002C8 E464                    	in	al, 64h
   804 000002CA A802                    	test	al, 2
   805 000002CC 75FA                            jnz     short L18
   806 000002CE B0D1                    	mov	al, 0D1h	; Write output port
   807 000002D0 E664                    	out	64h, al
   808                                  L19:
   809 000002D2 E464                    	in	al, 64h
   810 000002D4 A802                    	test	al, 2
   811 000002D6 75FA                            jnz     short L19
   812 000002D8 B0DF                    	mov	al, 0DFh	; Enable A20 line
   813 000002DA E660                    	out	60h, al
   814                                  ;L20:
   815                                  	;
   816                                  	; Load global descriptor table register
   817                                  
   818                                          ;mov     ax, cs
   819                                          ;mov     ds, ax
   820                                  
   821 000002DC 2E0F0116[1067]                  lgdt    [cs:gdtd]
   822                                  
   823 000002E2 0F20C0                          mov     eax, cr0
   824                                  	; or 	eax, 1
   825 000002E5 40                      	inc     ax
   826 000002E6 0F22C0                  	mov     cr0, eax
   827                                  
   828                                  	; Jump to 32 bit code
   829                                  	
   830 000002E9 66                      	db 66h 			; Prefix for 32-bit
   831 000002EA EA                      	db 0EAh 		; Opcode for far jump
   832 000002EB [F1020000]              	dd StartPM 		; Offset to start, 32-bit
   833                                  				; (1000h:StartPM = StartPM + 10000h)
   834 000002EF 0800                    	dw KCODE		; This is the selector for CODE32_DESCRIPTOR,
   835                                  				; assuming that StartPM resides in code32
   836                                  
   837                                  [BITS 32] 
   838                                  
   839                                  StartPM:
   840                                  	; Kernel Base Address = 0 ; 30/12/2013
   841 000002F1 66B81000                	mov ax, KDATA           ; Save data segment identifier
   842 000002F5 8ED8                            mov ds, ax              ; Move a valid data segment into DS register
   843 000002F7 8EC0                           	mov es, ax              ; Move data segment into ES register
   844 000002F9 8EE0                           	mov fs, ax              ; Move data segment into FS register
   845 000002FB 8EE8                          	mov gs, ax              ; Move data segment into GS register
   846 000002FD 8ED0                            mov ss, ax              ; Move data segment into SS register
   847 000002FF BC00000900                      mov esp, 90000h         ; Move the stack pointer to 090000h
   848                                  
   849                                  clear_bss: ; Clear uninitialized data area
   850                                  	; 11/03/2015
   851 00000304 31C0                    	xor  eax, eax ; 0
   852 00000306 B93F050000              	mov  ecx, (bss_end - bss_start)/4
   853                                  	;shr ecx, 2 ; bss section is already aligned for double words
   854 0000030B BF[906C0000]            	mov  edi, bss_start	
   855 00000310 F3AB                    	rep  stosd  		
   856                                  
   857                                  memory_init:
   858                                  	; Initialize memory allocation table and page tables
   859                                  	; 16/11/2014
   860                                  	; 15/11/2014
   861                                  	; 07/11/2014
   862                                  	; 06/11/2014
   863                                  	; 05/11/2014
   864                                  	; 04/11/2014
   865                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   866                                  	;
   867                                  ;	xor	eax, eax
   868                                  ;	xor 	ecx, ecx
   869 00000312 B108                    	mov	cl, 8
   870 00000314 BF00001000              	mov	edi, MEM_ALLOC_TBL	
   871 00000319 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   872                                  				   ; for the first 1 MB memory
   873                                  	;
   874 0000031B 668B0D[846C0000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   875                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   876 00000322 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   877 00000326 890D[006F0000]          	mov	[free_pages], ecx
   878 0000032C 668B15[866C0000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   879                                  				   ; between 16 MB and 4 GB.	
   880 00000333 6609D2                  	or	dx, dx
   881 00000336 7413                    	jz	short mi_0
   882                                  	;
   883 00000338 6689D0                  	mov	ax, dx
   884 0000033B C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   885 0000033E 0105[006F0000]          	add	[free_pages], eax
   886 00000344 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   887 00000349 EB07                    	jmp	short mi_1
   888                                  mi_0:
   889 0000034B 6689C8                  	mov	ax, cx
   890 0000034E 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   891                                  mi_1:
   892 00000352 A3[FC6E0000]            	mov	[memory_size], eax ; Total available memory in pages
   893                                  				   ; 1 alloc. tbl. bit = 1 memory page
   894                                  				   ; 32 allocation bits = 32 mem. pages   
   895                                  	;
   896 00000357 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   897 0000035C C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   898                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   899                                  				   ;  --> x M.A.T. pages, if y = 0
   900 0000035F 66A3[106F0000]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   901 00000365 C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   902                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   903 00000368 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   904                                  	; Set/Calculate Kernel's Page Directory Address
   905 0000036A 81C300001000            	add	ebx, MEM_ALLOC_TBL
   906 00000370 891D[F86E0000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   907                                  				   ; just after the last M.A.T. page
   908                                  	;
   909 00000376 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   910 00000379 A3[086F0000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   911                                  	;			   ; (allocation status search must be 
   912                                  				   ; stopped after here)	
   913 0000037E 31C0                    	xor	eax, eax
   914 00000380 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   915 00000381 6651                    	push	cx
   916 00000383 C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   917                                  				   ; count of 32 allocation bits
   918 00000386 F3AB                    	rep	stosd
   919 00000388 6659                    	pop	cx
   920 0000038A 40                      	inc	eax		   ; 0	
   921 0000038B 80E11F                  	and	cl, 31		   ; remain bits
   922 0000038E 7412                    	jz	short mi_4
   923 00000390 8907                    	mov	[edi], eax	   ; reset	
   924                                  mi_2:
   925 00000392 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   926 00000395 FEC9                    	dec	cl
   927 00000397 7404                    	jz	short mi_3
   928 00000399 FEC0                    	inc	al
   929 0000039B EBF5                    	jmp	short mi_2
   930                                  mi_3:
   931 0000039D 28C0                    	sub	al, al	   	   ; 0
   932 0000039F 83C704                  	add	edi, 4		   ; 15/11/2014
   933                                  mi_4:
   934 000003A2 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   935 000003A5 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   936                                  	;	
   937 000003A7 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   938                                  	;	
   939 000003AC 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   940 000003AE 7406                    	jz	short mi_5	  ; jump if EDI points to 
   941                                  				  ;         end of first 16 MB	
   942 000003B0 D1E9                    	shr	ecx, 1		  ; convert to dword count
   943 000003B2 D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   944 000003B4 F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   945                                  				  ; (memory hole under 16 MB)
   946                                  mi_5:
   947 000003B6 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   948 000003B9 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   949 000003BB 9C                      	pushf			  ; 16/11/2014		
   950 000003BC 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   951 000003BD F3AB                    	rep	stosd
   952 000003BF 40                      	inc	eax		  ; 0
   953 000003C0 9D                      	popf			  ; 16/11/2014
   954 000003C1 7305                    	jnc	short mi_6
   955 000003C3 6648                    	dec	ax		  ; eax = 0000FFFFh
   956 000003C5 AB                      	stosd
   957 000003C6 6640                    	inc	ax		  ; 0		
   958                                  mi_6:
   959 000003C8 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   960 000003CA 730A                    	jnb	short mi_7	  ; end of memory allocation table
   961                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   962 000003CC 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   963 000003CE 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   964 000003D0 D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   965 000003D2 D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   966 000003D4 F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   967                                  mi_7:
   968                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   969 000003D6 BA00001000              	mov	edx, MEM_ALLOC_TBL
   970                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   971                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   972 000003DB 668B0D[106F0000]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   973 000003E2 89D7                    	mov	edi, edx
   974 000003E4 C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   975                                  				  ; byte offset in M.A.T.
   976                                  				  ; (1 M.A.T. byte points to 
   977                                  				  ;	      32768 bytes)
   978                                  				  ; Note: MEM_ALLOC_TBL address 
   979                                  				  ; must be aligned on 128 KB 
   980                                  				  ; boundary!
   981 000003E7 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   982                                  	; eax = 0
   983 000003E9 290D[006F0000]          	sub	[free_pages], ecx ; 07/11/2014
   984                                  mi_8:
   985 000003EF 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   986                                  	;dec	bl
   987 000003F2 FEC9                    	dec	cl
   988 000003F4 7404                    	jz	short mi_9
   989 000003F6 FEC0                    	inc	al
   990 000003F8 EBF5                    	jmp	short mi_8
   991                                  mi_9:
   992                                  	;
   993                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   994                                  	;		(allocate pages for system page tables)
   995                                  
   996                                  	; edx = MEM_ALLOC_TBL
   997 000003FA 8B0D[FC6E0000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   998 00000400 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   999 00000406 C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
  1000                                  				 ; page table count (PDE count)
  1001                                  	;
  1002 00000409 51                      	push	ecx		 ; (**) PDE count (<= 1024)
  1003                                  	;
  1004 0000040A 41                      	inc	ecx		 ; +1 for kernel page directory	
  1005                                  	;
  1006 0000040B 290D[006F0000]          	sub	[free_pages], ecx ; 07/11/2014
  1007                                  	;
  1008 00000411 8B35[F86E0000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
  1009 00000417 C1EE0C                  	shr	esi, 12		 ; convert to page number
  1010                                  mi_10:
  1011 0000041A 89F0                    	mov	eax, esi	 ; allocation bit offset		 
  1012 0000041C 89C3                    	mov	ebx, eax
  1013 0000041E C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
  1014 00000421 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
  1015                                  				 ;   to align on dword boundary
  1016 00000424 83E01F                  	and	eax, 31		 ; set allocation bit position 
  1017                                  				 ;  (bit 0 to bit 31)
  1018                                  	;
  1019 00000427 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
  1020                                  	;
  1021 00000429 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
  1022                                  	;
  1023 0000042C 46                      	inc	esi		 ; next page table
  1024 0000042D E2EB                    	loop	mi_10		 ; allocate next kernel page table 
  1025                                  				 ; (ecx = page table count + 1)		
  1026                                  	;
  1027 0000042F 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
  1028                                  	;
  1029                                  	; Initialize Kernel Page Directory and Kernel Page Tables
  1030                                  	;
  1031                                  	; Initialize Kernel's Page Directory
  1032 00000430 8B3D[F86E0000]          	mov	edi, [k_page_dir]
  1033 00000436 89F8                    	mov	eax, edi
  1034 00000438 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
  1035                                  		     	      ; supervisor + read&write + present
  1036 0000043A 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
  1037                                  mi_11:
  1038 0000043C 0500100000              	add	eax, 4096	; Add page size (PGSZ)
  1039                                  			        ; EAX points to next page table
  1040 00000441 AB                      	stosd
  1041 00000442 E2F8                    	loop	mi_11
  1042 00000444 29C0                    	sub	eax, eax	; Empty PDE
  1043 00000446 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
  1044 0000044A 29D1                    	sub	ecx, edx
  1045 0000044C 7402                    	jz	short mi_12
  1046 0000044E F3AB                    	rep	stosd 		; clear remain (empty) PDEs
  1047                                  	;
  1048                                  	; Initialization of Kernel's Page Directory is OK, here.
  1049                                  mi_12:
  1050                                  	; Initialize Kernel's Page Tables
  1051                                  	;
  1052                                  	; (EDI points to address of page table 0)
  1053                                  	; eax = 0
  1054 00000450 8B0D[FC6E0000]          	mov	ecx, [memory_size] ; memory size in pages
  1055 00000456 89CA                    	mov	edx, ecx	; (***)
  1056 00000458 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
  1057                                  			     ; supervisor + read&write + present 	
  1058                                  mi_13:
  1059 0000045A AB                      	stosd
  1060 0000045B 0500100000              	add	eax, 4096	
  1061 00000460 E2F8                    	loop	mi_13	
  1062 00000462 6681E2FF03              	and	dx, 1023	; (***)
  1063 00000467 740B                    	jz	short mi_14
  1064 00000469 66B90004                	mov	cx, 1024	
  1065 0000046D 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
  1066 00000470 31C0                    	xor	eax, eax
  1067 00000472 F3AB                    	rep	stosd		; clear remain (empty) PTEs 
  1068                                  				; of the last page table
  1069                                  mi_14:
  1070                                  	;  Initialization of Kernel's Page Tables is OK, here.
  1071                                  	;
  1072 00000474 89F8                    	mov	eax, edi	; end of the last page table page
  1073                                  			        ; (beginging of user space pages)
  1074 00000476 C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
  1075 00000479 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
  1076                                  				; aligning on dword boundary	
  1077                                  	 
  1078 0000047B A3[0C6F0000]            	mov	[first_page], eax
  1079 00000480 A3[046F0000]            	mov	[next_page], eax ; The first free page pointer
  1080                                  				 ; for user programs
  1081                                  				 ; (Offset in Mem. Alloc. Tbl.)	
  1082                                  	;
  1083                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
  1084                                  	;
  1085                                  	
  1086                                  	; Enable paging
  1087                                  	;
  1088 00000485 A1[F86E0000]                    mov     eax, [k_page_dir]
  1089 0000048A 0F22D8                  	mov	cr3, eax
  1090 0000048D 0F20C0                  	mov	eax, cr0
  1091 00000490 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
  1092 00000495 0F22C0                  	mov	cr0, eax
  1093                                          ;jmp    KCODE:StartPMP
  1094                                  
  1095 00000498 EA                      	db 0EAh 		; Opcode for far jump
  1096 00000499 [9F040000]                      dd StartPMP		; 32 bit offset
  1097 0000049D 0800                    	dw KCODE		; kernel code segment descriptor
  1098                                  
  1099                                  
  1100                                  StartPMP:
  1101                                  	; 06/11//2014
  1102                                  	; Clear video page 0
  1103                                  	;
  1104                                  	; Temporary Code
  1105                                  	;
  1106 0000049F B9E8030000              	mov	ecx, 80*25/2
  1107 000004A4 BF00800B00              	mov	edi, 0B8000h
  1108 000004A9 31C0                    	xor	eax, eax	; black background, black fore color
  1109 000004AB F3AB                    	rep	stosd
  1110                                  	
  1111                                  	; 19/08/2014
  1112                                  	; Kernel Base Address = 0
  1113                                  	; It is mapped to (physically) 0 in the page table.
  1114                                  	; So, here is exactly 'StartPMP' address.
  1115                                  	;
  1116                                  	;;mov	ah, 4Eh	; Red background, yellow forecolor
  1117                                  	;;mov	esi, msgPM
  1118                                  	;; 14/08/2015 (kernel version message will appear
  1119                                  	;;	       when protected mode and paging is enabled)
  1120 000004AD B40B                    	mov	ah, 0Bh ; Black background, light cyan forecolor
  1121 000004AF BE[506A0000]            	mov	esi, msgKVER
  1122 000004B4 BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
  1123                                  	; 20/08/2014
  1124 000004B9 E892010000              	call	printk
  1125                                  
  1126                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
  1127                                  	; // Set IRQ offsets
  1128                                  	;
  1129                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
  1130                                  	;
  1131                                  					;; ICW1
  1132 000004BE B011                    	mov	al, 11h			; Initialization sequence
  1133 000004C0 E620                    	out	20h, al			; 	8259A-1
  1134                                  	; jmp 	$+2
  1135 000004C2 E6A0                    	out	0A0h, al		; 	8259A-2
  1136                                  					;; ICW2
  1137 000004C4 B020                    	mov	al, 20h			; Start of hardware ints (20h)
  1138 000004C6 E621                    	out	21h, al			;	for 8259A-1
  1139                                  	; jmp 	$+2
  1140 000004C8 B028                    	mov	al, 28h			; Start of hardware ints (28h)
  1141 000004CA E6A1                    	out	0A1h, al		; 	for 8259A-2
  1142                                  					;
  1143 000004CC B004                    	mov	al, 04h			;; ICW3
  1144 000004CE E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
  1145                                  	; jmp 	$+2
  1146 000004D0 B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
  1147 000004D2 E6A1                    	out	0A1h, al		;
  1148                                  					;; ICW4
  1149 000004D4 B001                    	mov	al, 01h	 		;
  1150 000004D6 E621                    	out	21h, al			; 	8086 mode, normal EOI	
  1151                                  	; jmp 	$+2
  1152 000004D8 E6A1                    	out	0A1h, al		;	for both chips.
  1153                                  
  1154                                  	;mov	al, 0FFh	; mask off all interrupts for now
  1155                                  	;out	21h, al
  1156                                  	;; jmp 	$+2
  1157                                  	;out	0A1h, al
  1158                                  
  1159                                  	; 02/04/2015
  1160                                  	; 26/03/2015 System call (INT 30h) modification
  1161                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
  1162                                  	;
  1163                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
  1164                                  	;  setup_idt:
  1165                                  	;
  1166                                          ;; 16/02/2015
  1167                                  	;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1168                                  	; 21/08/2014 (timer_int)
  1169 000004DA BE[1C670000]            	mov	esi, ilist
  1170 000004DF 8D3D[906C0000]          	lea	edi, [idt]
  1171                                  	; 26/03/2015
  1172 000004E5 B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
  1173                                  	; 02/04/2015
  1174 000004EA BB00000800              	mov	ebx,  80000h
  1175                                  rp_sidt1:
  1176 000004EF AD                      	lodsd
  1177 000004F0 89C2                    	mov	edx, eax
  1178 000004F2 66BA008E                	mov	dx, 8E00h
  1179 000004F6 6689C3                  	mov	bx, ax
  1180 000004F9 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
  1181                                         			        ; /* interrupt gate - dpl=0, present */
  1182 000004FB AB                      	stosd	; selector & offset bits 0-15 	
  1183 000004FC 89D0                    	mov	eax, edx
  1184 000004FE AB                      	stosd	; attributes & offset bits 16-23
  1185 000004FF E2EE                    	loop	rp_sidt1
  1186 00000501 B110                    	mov	cl, 16        ; 16 software interrupts (INT 30h to INT 3Fh)
  1187                                  rp_sidt2:
  1188 00000503 AD                      	lodsd
  1189 00000504 21C0                    	and	eax, eax
  1190 00000506 7413                    	jz	short rp_sidt3
  1191 00000508 89C2                    	mov	edx, eax
  1192 0000050A 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1193 0000050E 6689C3                  	mov	bx, ax
  1194 00000511 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1195 00000513 AB                      	stosd
  1196 00000514 89D0                    	mov	eax, edx
  1197 00000516 AB                      	stosd
  1198 00000517 E2EA                    	loop	rp_sidt2
  1199 00000519 EB16                    	jmp	short sidt_OK
  1200                                  rp_sidt3:
  1201 0000051B B8[7A090000]            	mov	eax, ignore_int
  1202 00000520 89C2                    	mov	edx, eax
  1203 00000522 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1204 00000526 6689C3                  	mov	bx, ax
  1205 00000529 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1206                                  rp_sidt4:
  1207 0000052B AB                      	stosd
  1208 0000052C 92                      	xchg	eax, edx
  1209 0000052D AB                      	stosd
  1210 0000052E 92                      	xchg	edx, eax
  1211 0000052F E2FA                    	loop	rp_sidt4
  1212                                  sidt_OK: 
  1213 00000531 0F011D[16670000]        	lidt 	[idtd]
  1214                                  	;
  1215                                  	; TSS descriptor setup ; 24/03/2015
  1216 00000538 B8[906E0000]            	mov	eax, task_state_segment
  1217 0000053D 66A3[0A670000]          	mov	[gdt_tss0], ax
  1218 00000543 C1C010                  	rol	eax, 16
  1219 00000546 A2[0C670000]            	mov	[gdt_tss1], al
  1220 0000054B 8825[0F670000]          	mov	[gdt_tss2], ah
  1221 00000551 66C705[F66E0000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
  1222 00000559 00                 
  1223                                  		; 
  1224                                  		; IO Map Base address (When this address points
  1225                                  		; to end of the TSS, CPU does not use IO port 
  1226                                  		; permission bit map for RING 3 IO permissions, 
  1227                                  		; access to any IO ports in ring 3 will be forbidden.)
  1228                                   		;
  1229                                  	;mov	[tss.esp0], esp ; TSS offset 4
  1230                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
  1231 0000055A 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
  1232                                  			 ; occurs (or a system call -software INT- is requested)
  1233                                  			 ; while cpu running in ring 3 (in user mode).				
  1234                                  			 ; (Kernel stack pointer and segment will be loaded
  1235                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
  1236 0000055E 0F00D8                  	ltr	ax  ; Load task register
  1237                                  	;
  1238                                  esp0_set0:
  1239                                  	; 30/07/2015
  1240 00000561 8B0D[FC6E0000]          	mov 	ecx, [memory_size] ; memory size in pages
  1241 00000567 C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
  1242 0000056A 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
  1243                                  			  ; (kernel mode virtual address)
  1244 00000570 7605                    	jna	short esp0_set1
  1245                                  	;
  1246                                  	; If available memory > CORE (end of the 1st 4 MB)
  1247                                  	; set stack pointer to CORE
  1248                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
  1249                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
  1250 00000572 B900004000              	mov	ecx, CORE
  1251                                  esp0_set1:
  1252 00000577 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
  1253                                  esp0_set_ok:
  1254                                  	; 30/07/2015 (**tss.esp0**) 
  1255 00000579 8925[946E0000]          	mov	[tss.esp0], esp
  1256 0000057F 66C705[986E0000]10-             mov     word [tss.ss0], KDATA
  1257 00000587 00                 
  1258                                  	; 14/08/2015
  1259                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
  1260                                  	;
  1261                                  	;cli	; Disable interrupts (for CPU)
  1262                                  	;    (CPU will not handle hardware interrupts, except NMI!)
  1263                                  	;
  1264 00000588 30C0                    	xor	al, al		; Enable all hardware interrupts!
  1265 0000058A E621                    	out	21h, al		; (IBM PC-AT compatibility)
  1266 0000058C EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
  1267 0000058E E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
  1268                                  				; (Even if related hardware component
  1269                                  				;  does not exist!)
  1270                                  	; Enable NMI 
  1271 00000590 B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
  1272 00000592 E670                    	out  	70h, al
  1273                                  	; 23/02/2015
  1274 00000594 90                      	nop
  1275 00000595 E471                    	in	al, 71h		; read in 71h just after writing out to 70h
  1276                                  				; for preventing unknown state (!?)
  1277                                  	;
  1278                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
  1279                                  	;
  1280                                  	; 02/09/2014
  1281 00000597 6631DB                  	xor	bx, bx
  1282 0000059A 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
  1283 0000059E E88E0F0000              	call	set_cpos
  1284                                  	;
  1285                                  	; 06/11/2014
  1286                                  	; Temporary Code
  1287                                  	;
  1288 000005A3 E8BE110000              	call	memory_info
  1289                                  	; 14/08/2015
  1290                                  	;call getch ; 28/02/2015
  1291                                  drv_init:
  1292 000005A8 FB                      	sti	; Enable Interrupts 
  1293                                  	; 06/02/2015
  1294 000005A9 8B15[F0690000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
  1295 000005AF 668B1D[EE690000]        	mov	bx, [fd0_type] ; fd0, fd1
  1296                                  	; 22/02/2015
  1297 000005B6 6621DB                  	and	bx, bx
  1298 000005B9 751B                    	jnz	short di1
  1299                                  	;
  1300 000005BB 09D2                    	or 	edx, edx
  1301 000005BD 7529                    	jnz	short di2
  1302                                  	;
  1303                                  setup_error:
  1304 000005BF BE[396B0000]            	mov 	esi, setup_error_msg
  1305                                  psem:	
  1306 000005C4 AC                      	lodsb
  1307 000005C5 08C0                    	or	al, al
  1308                                  	;jz	short haltx ; 22/02/2015
  1309 000005C7 7426                    	jz	short di3
  1310 000005C9 56                      	push	esi
  1311 000005CA 31DB                    	xor	ebx, ebx ; 0
  1312                                  			; Video page 0 (bl=0)
  1313 000005CC B407                    	mov	ah, 07h ; Black background, 
  1314                                  			; light gray forecolor
  1315 000005CE E83A0E0000              	call	write_tty
  1316 000005D3 5E                      	pop	esi
  1317 000005D4 EBEE                    	jmp	short psem
  1318                                  
  1319                                  di1:
  1320                                  	; supress 'jmp short T6'
  1321                                  	;  (activate fdc motor control code)
  1322 000005D6 66C705[D1060000]90-     	mov	word [T5], 9090h ; nop
  1323 000005DE 90                 
  1324                                  	;
  1325                                  	;mov	ax, int_0Eh	; IRQ 6 handler
  1326                                  	;mov	di, 0Eh*4	; IRQ 6 vector
  1327                                  	;stosw
  1328                                  	;mov 	ax, cs
  1329                                  	;stosw
  1330                                  	;; 16/02/2015
  1331                                          ;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1332                                  	;
  1333 000005DF E8D4200000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
  1334                                  	;
  1335 000005E4 09D2                    	or	edx, edx
  1336 000005E6 7407                            jz      short di3
  1337                                  di2:
  1338 000005E8 E811210000              	call   	DISK_SETUP	; Initialize Fixed Disks
  1339 000005ED 72D0                            jc      short setup_error
  1340                                  di3:
  1341 000005EF E846110000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
  1342                                  	;
  1343 000005F4 E83D600000              	call	display_disks ; 07/03/2015  (Temporary)
  1344                                  ;haltx:
  1345                                  	; 14/08/2015
  1346                                  	;call	getch ; 22/02/2015
  1347 000005F9 FB                      	sti	; Enable interrupts (for CPU)
  1348                                  	; 14/08/2015
  1349                                  	;mov 	ecx, 0FFFFFFFh
  1350                                  	; 22/11/2021
  1351 000005FA B9FFFF2F00              	mov 	ecx, 02FFFFFh	
  1352                                  md_info_msg_wait:
  1353 000005FF 51                      	push 	ecx
  1354 00000600 B001                    	mov	al, 1
  1355 00000602 8A25[266F0000]          	mov 	ah, [ptty] ; active (current) video page
  1356 00000608 E8665D0000              	call	getc_n
  1357 0000060D 59                      	pop	ecx
  1358 0000060E 7502                    	jnz	short md_info_msg_ok
  1359 00000610 E2ED                    	loop	md_info_msg_wait
  1360                                  md_info_msg_ok:
  1361                                  	; 30/06/2015
  1362 00000612 E80C2E0000              	call	sys_init
  1363                                  	;
  1364                                  	;jmp 	cpu_reset ; 22/02/2015
  1365                                  hang:  
  1366                                  	; 23/02/2015
  1367                                  	;sti			; Enable interrupts
  1368 00000617 F4                      	hlt
  1369                                  	;
  1370                                  	;nop
  1371                                  	;; 03/12/2014
  1372                                  	;; 28/08/2014
  1373                                  	;mov	ah, 11h
  1374                                  	;call	getc
  1375                                  	;jz      _c8
  1376                                  	;
  1377                                  	; 23/02/2015
  1378                                  	; 06/02/2015
  1379                                  	; 07/09/2014
  1380 00000618 31DB                    	xor	ebx, ebx
  1381 0000061A 8A1D[266F0000]          	mov	bl, [ptty]	; active_page
  1382 00000620 89DE                    	mov	esi, ebx
  1383 00000622 66D1E6                  	shl 	si, 1
  1384 00000625 81C6[286F0000]          	add	esi, ttychr
  1385 0000062B 668B06                  	mov	ax, [esi]
  1386 0000062E 6621C0                  	and	ax, ax
  1387                                  	;jz	short _c8
  1388 00000631 74E4                    	jz	short hang
  1389 00000633 66C7060000              	mov	word [esi], 0
  1390 00000638 80FB03                  	cmp	bl, 3		; Video page 3
  1391                                  	;jb	short _c8
  1392 0000063B 72DA                    	jb	short hang
  1393                                  	;	
  1394                                  	; 02/09/2014
  1395 0000063D B40E                    	mov	ah, 0Eh		; Yellow character 
  1396                                  				; on black background
  1397                                  	; 30/11/2021 (32 bit reg push-pop)
  1398                                  	; 07/09/2014
  1399                                  nxtl:
  1400 0000063F 53                      	push	ebx
  1401                                  	;
  1402                                  	;xor	ebx, ebx	; bl = 0 (video page 0)
  1403                                  				; bh = 0 (video mode)
  1404                                  				; Retro UNIX 386 v1 - Video Mode 0
  1405                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
  1406 00000640 50                      	push	eax
  1407 00000641 E8C70D0000              	call 	write_tty
  1408 00000646 58                      	pop	eax
  1409                                  	;pop	bx
  1410 00000647 5B                      	pop	ebx
  1411 00000648 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
  1412                                  	;jne	short _c8
  1413 0000064A 75CB                    	jne	short hang
  1414 0000064C B00A                    	mov	al, 0Ah		; next line
  1415 0000064E EBEF                    	jmp	short nxtl
  1416                                  	
  1417                                  ;_c8:
  1418                                  ;	; 25/08/2014
  1419                                  ;	cli				; Disable interrupts
  1420                                  ;	mov	al, [scounter + 1]
  1421                                  ;	and	al, al
  1422                                  ;	jnz	hang
  1423                                  ;	call	rtc_p
  1424                                  ;	jmp     hang
  1425                                  
  1426                                  
  1427                                  	; 27/08/2014
  1428                                  	; 20/08/2014
  1429                                  printk:
  1430                                          ;mov    edi, [scr_row]
  1431                                  pkl:
  1432 00000650 AC                      	lodsb
  1433 00000651 08C0                    	or 	al, al
  1434 00000653 7404                    	jz	short pkr
  1435 00000655 66AB                    	stosw
  1436 00000657 EBF7                    	jmp	short pkl
  1437                                  pkr:
  1438 00000659 C3                      	retn
  1439                                  
  1440                                  ; 25/07/2015
  1441                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
  1442                                  ; 17/02/2015
  1443                                  ; 06/02/2015 (unix386.s)
  1444                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
  1445                                  ;
  1446                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
  1447                                  ;
  1448                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
  1449                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
  1450                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
  1451                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
  1452                                  ;									       :
  1453                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
  1454                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
  1455                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
  1456                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
  1457                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
  1458                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
  1459                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
  1460                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
  1461                                  ;-------------------------------------------------------------------------------
  1462                                  ;
  1463                                  
  1464                                  timer_int:	; IRQ 0
  1465                                  ;int_08h:	; Timer
  1466                                  	; 14/10/2015
  1467                                  	; Here, we are simulating system call entry (for task switch)
  1468                                  	; (If multitasking is enabled, 
  1469                                  	; 'clock' procedure may jump to 'sysrelease')
  1470 0000065A 1E                      	push	ds
  1471 0000065B 06                      	push	es
  1472 0000065C 0FA0                    	push	fs
  1473 0000065E 0FA8                    	push	gs
  1474 00000660 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1475 00000661 66B91000                	mov     cx, KDATA
  1476 00000665 8ED9                            mov     ds, cx
  1477 00000667 8EC1                            mov     es, cx
  1478 00000669 8EE1                            mov     fs, cx
  1479 0000066B 8EE9                            mov     gs, cx
  1480                                  	;
  1481 0000066D 0F20D9                  	mov	ecx, cr3
  1482 00000670 890D[0F070000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1483                                  	;
  1484 00000676 3B0D[F86E0000]          	cmp 	ecx, [k_page_dir]
  1485 0000067C 741F                    	je	short T3
  1486                                  	;
  1487                                  	; timer interrupt has been occurred while OS is in user mode
  1488 0000067E A3[F46F0000]            	mov 	[u.r0], eax
  1489 00000683 89E1                    	mov	ecx, esp
  1490 00000685 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1491 00000688 890D[EC6F0000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1492 0000068E 8925[F06F0000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1493                                  	;
  1494 00000694 8B0D[F86E0000]          	mov	ecx, [k_page_dir]
  1495 0000069A 0F22D9                  	mov	cr3, ecx
  1496                                  T3:
  1497 0000069D FB                      	sti				; INTERRUPTS BACK ON
  1498 0000069E 66FF05[746F0000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
  1499 000006A5 7507                    	JNZ	short T4		; GO TO TEST_DAY
  1500 000006A7 66FF05[766F0000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
  1501                                  T4:					; TEST_DAY
  1502 000006AE 66833D[766F0000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
  1503 000006B6 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1504 000006B8 66813D[746F0000]B0-     	CMP	word [TIMER_LOW],0B0H
  1505 000006C0 00                 
  1506 000006C1 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1507                                  
  1508                                  ;-----	TIMER HAS GONE 24 HOURS
  1509                                  	;;SUB	AX,AX
  1510                                  	;MOV	[TIMER_HIGH],AX
  1511                                  	;MOV	[TIMER_LOW],AX
  1512 000006C3 29C0                    	sub	eax, eax
  1513 000006C5 A3[746F0000]            	mov	[TIMER_LH], eax
  1514                                  	;	
  1515 000006CA C605[786F0000]01        	MOV	byte [TIMER_OFL],1
  1516                                  
  1517                                  ;-----	TEST FOR DISKETTE TIME OUT
  1518                                  
  1519                                  T5:
  1520                                  	; 23/12/2014
  1521 000006D1 EB1D                    	jmp	short T6		; will be replaced with nop, nop
  1522                                  					; (9090h) if a floppy disk
  1523                                  					; is detected.
  1524                                  	;mov	al,[CS:MOTOR_COUNT]
  1525 000006D3 A0[7B6F0000]            	mov	al, [MOTOR_COUNT]
  1526 000006D8 FEC8                    	dec	al
  1527                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1528 000006DA A2[7B6F0000]            	mov	[MOTOR_COUNT], al
  1529                                  	;mov	[ORG_MOTOR_COUNT], al
  1530 000006DF 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
  1531 000006E1 B0F0                    	mov 	al,0F0h
  1532                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
  1533 000006E3 2005[7A6F0000]          	and	[MOTOR_STATUS], al
  1534                                  	;and	[ORG_MOTOR_STATUS], al
  1535 000006E9 B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
  1536                                  					; bit 2 = enable controller
  1537                                  					;	1 = normal operation
  1538                                  					;	0 = reset	
  1539                                  					; bit 0, 1 = drive select
  1540                                  					; bit 4-7 = motor running bits 
  1541 000006EB 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
  1542 000006EF EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
  1543                                  T6:	
  1544                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
  1545                                  					; TIMER TICK INTERRUPT
  1546                                  	;;inc	word [wait_count] ;;27/02/2015
  1547                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
  1548                                  	;;;;cli
  1549                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
  1550 000006F0 FF15[0B070000]          	call	[x_timer] ; 14/05/2015
  1551                                  T7:
  1552                                  	; 14/10/2015
  1553 000006F6 B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  1554 000006F8 FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  1555 000006F9 E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  1556                                  	;
  1557 000006FB A1[0F070000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1558 00000700 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1559                                  	;
  1560 00000703 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1561                                  	;
  1562 00000704 0FA9                    	pop	gs
  1563 00000706 0FA1                    	pop	fs
  1564 00000708 07                      	pop	es
  1565 00000709 1F                      	pop	ds
  1566 0000070A CF                      	iretd	; return from interrupt
  1567                                  
  1568                                  
  1569                                  ; ////////////////
  1570                                  
  1571                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
  1572                                  x_timer:
  1573 0000070B [13070000]              	dd 	u_timer			; 14/05/2015
  1574                                  	;dd	clock
  1575                                  
  1576                                  ; 14/10/2015
  1577 0000070F 00000000                cr3reg: dd 0
  1578                                  
  1579                                  	; 06/02/2015
  1580                                  	; 07/09/2014
  1581                                  	; 21/08/2014
  1582                                  u_timer:
  1583                                  ;timer_int:	; IRQ 0
  1584                                  	; 06/02/2015
  1585                                  	;push	eax
  1586                                  	;push	edx
  1587                                  	;push	ecx
  1588                                  	;push	ebx
  1589                                  	;push	ds
  1590                                  	;push	es
  1591                                  	;mov	eax, KDATA
  1592                                  	;mov	ds, ax
  1593                                  	;mov	es, ax
  1594 00000713 FF05[3C6F0000]          	inc	dword [tcount]
  1595 00000719 BB[C26A0000]            	mov	ebx, tcountstr + 4
  1596 0000071E 66A1[3C6F0000]          	mov	ax, [tcount]
  1597 00000724 B90A000000              	mov	ecx, 10
  1598                                  rp_divtcnt:
  1599 00000729 31D2                    	xor	edx, edx
  1600 0000072B F7F1                    	div	ecx
  1601 0000072D 80C230                  	add	dl, 30h
  1602 00000730 8813                    	mov	[ebx], dl
  1603 00000732 6609C0                  	or	ax, ax
  1604 00000735 7403                    	jz	short print_lzero
  1605 00000737 4B                      	dec	ebx
  1606 00000738 EBEF                    	jmp	short rp_divtcnt
  1607                                  print_lzero:
  1608 0000073A 81FB[BE6A0000]          	cmp	ebx, tcountstr
  1609 00000740 7606                    	jna	short print_tcount
  1610 00000742 4B                      	dec	ebx
  1611 00000743 C60330                   	mov	byte [ebx], 30h
  1612 00000746 EBF2                    	jmp	short print_lzero
  1613                                  print_tcount:
  1614 00000748 56                      	push	esi
  1615 00000749 57                      	push	edi
  1616 0000074A BE[9A6A0000]            	mov	esi, timer_msg ; Timer interrupt message
  1617                                  	; 07/09/2014
  1618 0000074F 66BB0100                	mov	bx, 1		; Video page 1
  1619                                  ptmsg:
  1620 00000753 AC                      	lodsb
  1621 00000754 08C0                    	or	al, al
  1622 00000756 740F                    	jz	short ptmsg_ok
  1623 00000758 56                      	push	esi
  1624 00000759 6653                    	push	bx
  1625 0000075B B42F                            mov     ah,  2Fh ; Green background, white forecolor
  1626 0000075D E8AB0C0000              	call 	write_tty
  1627 00000762 665B                    	pop	bx
  1628 00000764 5E                      	pop	esi
  1629 00000765 EBEC                    	jmp	short ptmsg
  1630                                  	;; 27/08/2014
  1631                                  	;mov     edi, 0B8000h + 0A0h ; Row 1
  1632                                  	;call	printk
  1633                                  	;
  1634                                  ptmsg_ok:
  1635                                  	; 07/09/2014
  1636 00000767 6631D2                  	xor	dx, dx		; column 0, row 0
  1637 0000076A E8C20D0000              	call	set_cpos	; set cursor position to 0,0 
  1638                                  	; 23/02/2015
  1639                                  	; 25/08/2014
  1640                                  	;mov	ebx, scounter		; (seconds counter)
  1641                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1642                                  ;	dec	byte [scounter+1]
  1643                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1644                                  ;	jns	short u_timer_retn
  1645                                  	; 26/02/2015
  1646                                  ;	call	rtc_p
  1647                                  ;	mov	ebx, scounter		; (seconds counter)
  1648                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1649                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1650                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1651                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1652                                  ;	mov	byte [ebx], 5
  1653                                  ;	inc	byte [ebx+1] ; 19
  1654                                  ;;timer_eoi:
  1655                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1656                                  ;;	out	20h, al	; 8259 PORT
  1657                                  	;
  1658                                  ;u_timer_retn:  ; 06/02/2015
  1659 0000076F 5F                      	pop	edi
  1660 00000770 5E                      	pop	esi
  1661                                  	;pop	es
  1662                                  	;pop	ds
  1663                                  	;pop	ebx
  1664                                  	;pop	ecx
  1665                                  	;pop	edx
  1666                                  	;pop	eax
  1667                                  	;iret
  1668 00000771 C3                      	retn	; 06/02/2015
  1669                                  
  1670                                  	; 28/08/2014
  1671                                  irq0:
  1672 00000772 6A00                            push 	dword 0
  1673 00000774 EB48                    	jmp	short which_irq
  1674                                  irq1:
  1675 00000776 6A01                            push 	dword 1
  1676 00000778 EB44                    	jmp	short which_irq
  1677                                  irq2:
  1678 0000077A 6A02                            push 	dword 2
  1679 0000077C EB40                    	jmp	short which_irq
  1680                                  irq3:
  1681                                  	; 20/11/2015
  1682                                  	; 24/10/2015
  1683 0000077E 2EFF15[713B0000]        	call	dword [cs:com2_irq3]
  1684 00000785 6A03                    	push 	dword 3
  1685 00000787 EB35                    	jmp	short which_irq
  1686                                  irq4:
  1687                                  	; 20/11/2015
  1688                                  	; 24/10/2015
  1689 00000789 2EFF15[6D3B0000]        	call	dword [cs:com1_irq4]
  1690 00000790 6A04                            push 	dword 4
  1691 00000792 EB2A                    	jmp	short which_irq
  1692                                  irq5:
  1693 00000794 6A05                            push 	dword 5
  1694 00000796 EB26                    	jmp	short which_irq
  1695                                  irq6:
  1696 00000798 6A06                            push 	dword 6
  1697 0000079A EB22                    	jmp	short which_irq
  1698                                  irq7:
  1699 0000079C 6A07                            push 	dword 7
  1700 0000079E EB1E                    	jmp	short which_irq
  1701                                  irq8:
  1702 000007A0 6A08                            push 	dword 8
  1703 000007A2 EB1A                    	jmp	short which_irq
  1704                                  irq9:
  1705 000007A4 6A09                            push 	dword 9
  1706 000007A6 EB16                    	jmp	short which_irq
  1707                                  irq10:
  1708 000007A8 6A0A                            push 	dword 10
  1709 000007AA EB12                    	jmp	short which_irq
  1710                                  irq11:
  1711 000007AC 6A0B                            push 	dword 11
  1712 000007AE EB0E                    	jmp	short which_irq
  1713                                  irq12:
  1714 000007B0 6A0C                            push 	dword 12
  1715 000007B2 EB0A                    	jmp	short which_irq
  1716                                  irq13:
  1717 000007B4 6A0D                            push 	dword 13
  1718 000007B6 EB06                    	jmp	short which_irq
  1719                                  irq14:
  1720 000007B8 6A0E                            push 	dword 14
  1721 000007BA EB02                    	jmp	short which_irq
  1722                                  irq15:
  1723 000007BC 6A0F                            push 	dword 15
  1724                                  	;jmp	short which_irq
  1725                                  
  1726                                  	; 19/10/2015
  1727                                  	; 29/08/2014
  1728                                  	; 21/08/2014
  1729                                  which_irq:
  1730 000007BE 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1731 000007C1 53                      	push	ebx
  1732 000007C2 56                      	push	esi
  1733 000007C3 57                      	push	edi
  1734 000007C4 1E                      	push 	ds
  1735 000007C5 06                      	push 	es
  1736                                  	;
  1737 000007C6 88C3                    	mov	bl, al
  1738                                  	;
  1739 000007C8 B810000000              	mov	eax, KDATA
  1740 000007CD 8ED8                    	mov	ds, ax
  1741 000007CF 8EC0                    	mov	es, ax
  1742                                  	; 19/10/2015
  1743 000007D1 FC                      	cld
  1744                                          ; 27/08/2014
  1745 000007D2 8105[486A0000]A000-             add     dword [scr_row], 0A0h
  1746 000007DA 0000               
  1747                                  	;
  1748 000007DC B417                    	mov	ah, 17h	; blue (1) background, 
  1749                                  			; light gray (7) forecolor
  1750 000007DE 8B3D[486A0000]                  mov     edi, [scr_row]
  1751 000007E4 B049                    	mov	al, 'I'
  1752 000007E6 66AB                    	stosw
  1753 000007E8 B052                    	mov	al, 'R'
  1754 000007EA 66AB                    	stosw
  1755 000007EC B051                    	mov	al, 'Q'
  1756 000007EE 66AB                    	stosw
  1757 000007F0 B020                    	mov	al, ' '
  1758 000007F2 66AB                    	stosw
  1759 000007F4 88D8                    	mov	al, bl
  1760 000007F6 3C0A                    	cmp	al, 10
  1761 000007F8 7208                    	jb	short iix
  1762 000007FA B031                    	mov	al, '1'
  1763 000007FC 66AB                    	stosw
  1764 000007FE 88D8                    	mov	al, bl
  1765 00000800 2C0A                    	sub	al, 10
  1766                                  iix:
  1767 00000802 0430                    	add	al, '0'
  1768 00000804 66AB                    	stosw
  1769 00000806 B020                    	mov	al, ' '
  1770 00000808 66AB                    	stosw
  1771 0000080A B021                    	mov	al, '!'
  1772 0000080C 66AB                    	stosw
  1773 0000080E B020                    	mov	al, ' '
  1774 00000810 66AB                    	stosw
  1775                                  	; 23/02/2015
  1776 00000812 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1777 00000815 0F868D010000            	jna	iiret
  1778 0000081B B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1779 0000081D E6A0                    	out	0A0h, al ; the 2nd 8259
  1780 0000081F E984010000              	jmp     iiret
  1781                                  	;
  1782                                  	; 22/08/2014
  1783                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1784                                  	;out	20h, al	; 8259 PORT
  1785                                  	;
  1786                                  	;pop	es
  1787                                  	;pop	ds
  1788                                  	;pop	edi
  1789                                  	;pop	esi
  1790                                  	;pop	ebx
  1791                                  	;pop 	eax
  1792                                  	;iret
  1793                                  
  1794                                  	; 02/04/2015
  1795                                  	; 25/08/2014
  1796                                  exc0:
  1797 00000824 6A00                            push 	dword 0
  1798 00000826 E990000000                      jmp     cpu_except
  1799                                  exc1:
  1800 0000082B 6A01                            push 	dword 1
  1801 0000082D E989000000                      jmp     cpu_except
  1802                                  exc2:
  1803 00000832 6A02                            push 	dword 2
  1804 00000834 E982000000                      jmp     cpu_except
  1805                                  exc3:
  1806 00000839 6A03                            push 	dword 3
  1807 0000083B EB7E                            jmp     cpu_except
  1808                                  exc4:
  1809 0000083D 6A04                            push 	dword 4
  1810 0000083F EB7A                            jmp     cpu_except
  1811                                  exc5:
  1812 00000841 6A05                            push 	dword 5
  1813 00000843 EB76                            jmp     cpu_except
  1814                                  exc6:
  1815 00000845 6A06                            push 	dword 6
  1816 00000847 EB72                            jmp     cpu_except
  1817                                  exc7:
  1818 00000849 6A07                            push 	dword 7
  1819 0000084B EB6E                            jmp     cpu_except
  1820                                  exc8:
  1821                                  	; [esp] = Error code
  1822 0000084D 6A08                            push 	dword 8
  1823 0000084F EB5C                            jmp     cpu_except_en
  1824                                  exc9:
  1825 00000851 6A09                            push 	dword 9
  1826 00000853 EB66                            jmp     cpu_except
  1827                                  exc10:
  1828                                  	; [esp] = Error code
  1829 00000855 6A0A                            push 	dword 10
  1830 00000857 EB54                            jmp     cpu_except_en
  1831                                  exc11:
  1832                                  	; [esp] = Error code
  1833 00000859 6A0B                            push 	dword 11
  1834 0000085B EB50                            jmp     cpu_except_en
  1835                                  exc12:
  1836                                  	; [esp] = Error code
  1837 0000085D 6A0C                            push 	dword 12
  1838 0000085F EB4C                            jmp     cpu_except_en
  1839                                  exc13:
  1840                                  	; [esp] = Error code
  1841 00000861 6A0D                            push 	dword 13
  1842 00000863 EB48                            jmp     cpu_except_en
  1843                                  exc14:
  1844                                  	; [esp] = Error code
  1845 00000865 6A0E                            push 	dword 14
  1846 00000867 EB44                    	jmp	short cpu_except_en
  1847                                  exc15:
  1848 00000869 6A0F                            push 	dword 15
  1849 0000086B EB4E                            jmp     cpu_except
  1850                                  exc16:
  1851 0000086D 6A10                            push 	dword 16
  1852 0000086F EB4A                            jmp     cpu_except
  1853                                  exc17:
  1854                                  	; [esp] = Error code
  1855 00000871 6A11                            push 	dword 17
  1856 00000873 EB38                    	jmp	short cpu_except_en
  1857                                  exc18:
  1858 00000875 6A12                            push 	dword 18
  1859 00000877 EB42                    	jmp	short cpu_except
  1860                                  exc19:
  1861 00000879 6A13                            push 	dword 19
  1862 0000087B EB3E                    	jmp	short cpu_except
  1863                                  exc20:
  1864 0000087D 6A14                            push 	dword 20
  1865 0000087F EB3A                    	jmp	short cpu_except
  1866                                  exc21:
  1867 00000881 6A15                            push 	dword 21
  1868 00000883 EB36                    	jmp	short cpu_except
  1869                                  exc22:
  1870 00000885 6A16                            push 	dword 22
  1871 00000887 EB32                    	jmp	short cpu_except
  1872                                  exc23:
  1873 00000889 6A17                            push 	dword 23
  1874 0000088B EB2E                    	jmp	short cpu_except
  1875                                  exc24:
  1876 0000088D 6A18                            push 	dword 24
  1877 0000088F EB2A                    	jmp	short cpu_except
  1878                                  exc25:
  1879 00000891 6A19                            push 	dword 25
  1880 00000893 EB26                    	jmp	short cpu_except
  1881                                  exc26:
  1882 00000895 6A1A                            push 	dword 26
  1883 00000897 EB22                    	jmp	short cpu_except
  1884                                  exc27:
  1885 00000899 6A1B                            push 	dword 27
  1886 0000089B EB1E                    	jmp	short cpu_except
  1887                                  exc28:
  1888 0000089D 6A1C                            push 	dword 28
  1889 0000089F EB1A                    	jmp	short cpu_except
  1890                                  exc29:
  1891 000008A1 6A1D                            push 	dword 29
  1892 000008A3 EB16                    	jmp	short cpu_except
  1893                                  exc30:
  1894 000008A5 6A1E                            push 	dword 30
  1895 000008A7 EB04                    	jmp	short cpu_except_en
  1896                                  exc31:
  1897 000008A9 6A1F                            push 	dword 31
  1898 000008AB EB0E                            jmp     short cpu_except
  1899                                  
  1900                                  	; 19/10/2015
  1901                                  	; 19/09/2015
  1902                                  	; 01/09/2015
  1903                                  	; 28/08/2015
  1904                                  	; 28/08/2014
  1905                                  cpu_except_en:
  1906 000008AD 87442404                	xchg	eax, [esp+4] ; Error code
  1907 000008B1 36A3[80810000]          	mov	[ss:error_code], eax
  1908 000008B7 58                      	pop	eax  ; Exception number
  1909 000008B8 870424                  	xchg	eax, [esp]
  1910                                  		; eax = eax before exception
  1911                                  		; [esp] -> exception number
  1912                                  		; [esp+4] -> EIP to return
  1913                                  	; 19/10/2015
  1914                                  	; 19/09/2015
  1915                                  	; 01/09/2015
  1916                                  	; 28/08/2015
  1917                                  	; 29/08/2014
  1918                                  	; 28/08/2014
  1919                                  	; 25/08/2014
  1920                                  	; 21/08/2014
  1921                                  cpu_except:	; CPU Exceptions
  1922 000008BB FC                      	cld
  1923 000008BC 870424                  	xchg	eax, [esp] 
  1924                                  		; eax = Exception number
  1925                                  		; [esp] = eax (before exception)	
  1926 000008BF 53                      	push	ebx
  1927 000008C0 56                      	push	esi
  1928 000008C1 57                      	push	edi
  1929 000008C2 1E                      	push 	ds
  1930 000008C3 06                      	push 	es
  1931                                  	; 28/08/2015
  1932 000008C4 66BB1000                	mov	bx, KDATA
  1933 000008C8 8EDB                    	mov	ds, bx
  1934 000008CA 8EC3                    	mov	es, bx
  1935 000008CC 0F20DB                  	mov	ebx, cr3
  1936 000008CF 53                      	push	ebx ; (*) page directory
  1937                                  	; 19/10/2015
  1938 000008D0 FC                      	cld
  1939                                  	; 25/03/2015
  1940 000008D1 8B1D[F86E0000]          	mov	ebx, [k_page_dir]
  1941 000008D7 0F22DB                  	mov	cr3, ebx
  1942                                  	; 28/08/2015
  1943 000008DA 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1944 000008DD 7512                    	jne	short cpu_except_nfp
  1945 000008DF E8F5280000              	call	page_fault_handler
  1946 000008E4 21C0                    	and 	eax, eax
  1947 000008E6 0F84B8000000                    jz	iiretp ; 01/09/2015
  1948 000008EC B80E000000              	mov	eax, 0Eh ; 14
  1949                                  cpu_except_nfp:
  1950                                  	; 02/04/2015
  1951 000008F1 BB[17060000]            	mov	ebx, hang
  1952 000008F6 875C241C                	xchg	ebx, [esp+28]
  1953                                  		; EIP (points to instruction which faults)
  1954                                  	  	; New EIP (hang)
  1955 000008FA 891D[84810000]          	mov	[FaultOffset], ebx
  1956 00000900 C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1957 00000908 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1958                                  	;
  1959 00000910 88C4                    	mov	ah, al
  1960 00000912 240F                    	and	al, 0Fh
  1961 00000914 3C09                    	cmp	al, 9
  1962 00000916 7602                    	jna	short h1ok
  1963 00000918 0407                    	add	al, 'A'-':'
  1964                                  h1ok:
  1965 0000091A D0EC                    	shr	ah, 1
  1966 0000091C D0EC                    	shr	ah, 1
  1967 0000091E D0EC                    	shr	ah, 1
  1968 00000920 D0EC                    	shr	ah, 1
  1969 00000922 80FC09                  	cmp	ah, 9
  1970 00000925 7603                    	jna	short h2ok
  1971 00000927 80C407                  	add	ah, 'A'-':'
  1972                                  h2ok:	
  1973 0000092A 86E0                    	xchg 	ah, al	
  1974 0000092C 66053030                	add	ax, '00'
  1975 00000930 66A3[D66A0000]          	mov	[excnstr], ax
  1976                                  	;
  1977                                  	; 29/08/2014
  1978 00000936 A1[84810000]            	mov	eax, [FaultOffset]
  1979 0000093B 51                      	push	ecx
  1980 0000093C 52                      	push	edx
  1981 0000093D 89E3                    	mov	ebx, esp
  1982                                  	; 28/08/2015
  1983 0000093F B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1984                                  			  ; to hexadecimal string
  1985                                  	;mov	ecx, 10	    ; divisor to convert	
  1986                                  			    ; binary number to decimal string
  1987                                  b2d1:
  1988 00000944 31D2                    	xor	edx, edx
  1989 00000946 F7F1                    	div	ecx
  1990 00000948 6652                    	push	dx
  1991 0000094A 39C8                    	cmp	eax, ecx
  1992 0000094C 73F6                    	jnb	short b2d1
  1993 0000094E BF[E16A0000]            	mov	edi, EIPstr ; EIP value
  1994                                  			    ; points to instruction which faults	
  1995                                  	; 28/08/2015
  1996 00000953 89C2                    	mov	edx, eax
  1997                                  b2d2:
  1998                                  	;add	al, '0'
  1999 00000955 8A82[22180000]          	mov	al, [edx+hexchrs]
  2000 0000095B AA                      	stosb		    ; write hexadecimal digit to its place	
  2001 0000095C 39E3                    	cmp	ebx, esp
  2002 0000095E 7606                    	jna	short b2d3
  2003 00000960 6658                    	pop	ax
  2004 00000962 88C2                    	mov	dl, al
  2005 00000964 EBEF                    	jmp	short b2d2
  2006                                  b2d3:
  2007 00000966 B068                    	mov 	al, 'h' ; 28/08/2015
  2008 00000968 AA                      	stosb
  2009 00000969 B020                    	mov	al, 20h	    ; space
  2010 0000096B AA                      	stosb
  2011 0000096C 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  2012 0000096E AA                      	stosb
  2013                                  	;
  2014 0000096F 5A                      	pop	edx
  2015 00000970 59                      	pop	ecx
  2016                                  	;
  2017 00000971 B44F                    	mov	ah, 4Fh	; red (4) background, 
  2018                                  			; white (F) forecolor
  2019 00000973 BE[C66A0000]            	mov	esi, exc_msg ; message offset
  2020                                  	;
  2021 00000978 EB11                    	jmp	short piemsg
  2022                                  	;
  2023                                          ;add    dword [scr_row], 0A0h
  2024                                          ;mov    edi, [scr_row]
  2025                                          ;
  2026                                  	;call 	printk
  2027                                  	;
  2028                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2029                                  	;out	20h, al	; 8259 PORT
  2030                                  	;
  2031                                  	;pop	es
  2032                                  	;pop	ds
  2033                                  	;pop	edi
  2034                                  	;pop	esi
  2035                                  	;pop 	eax
  2036                                  	;iret
  2037                                  	
  2038                                  	; 28/08/2015
  2039                                  	; 23/02/2015
  2040                                  	; 20/08/2014
  2041                                  ignore_int:
  2042 0000097A 50                      	push	eax
  2043 0000097B 53                      	push	ebx ; 23/02/2015
  2044 0000097C 56                      	push	esi
  2045 0000097D 57                      	push	edi
  2046 0000097E 1E                      	push 	ds
  2047 0000097F 06                      	push 	es
  2048                                  	; 28/08/2015
  2049 00000980 0F20D8                  	mov	eax, cr3
  2050 00000983 50                      	push	eax ; (*) page directory
  2051                                  	;
  2052 00000984 B467                    	mov	ah, 67h	; brown (6) background, 
  2053                                  			; light gray (7) forecolor
  2054 00000986 BE[846A0000]            	mov	esi, int_msg ; message offset
  2055                                  piemsg:
  2056                                          ; 27/08/2014
  2057 0000098B 8105[486A0000]A000-             add     dword [scr_row], 0A0h
  2058 00000993 0000               
  2059 00000995 8B3D[486A0000]                  mov     edi, [scr_row]
  2060                                          ;
  2061 0000099B E8B0FCFFFF              	call 	printk
  2062                                  	;
  2063                                  	; 23/02/2015
  2064 000009A0 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2065 000009A2 E6A0                    	out	0A0h, al ; the 2nd 8259
  2066                                  iiretp: ; 01/09/2015
  2067                                  	; 28/08/2015
  2068 000009A4 58                      	pop	eax ; (*) page directory
  2069 000009A5 0F22D8                  	mov	cr3, eax
  2070                                  	;
  2071                                  iiret:
  2072                                  	; 22/08/2014
  2073 000009A8 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2074 000009AA E620                    	out	20h, al	; 8259 PORT
  2075                                  	;
  2076 000009AC 07                      	pop	es
  2077 000009AD 1F                      	pop	ds
  2078 000009AE 5F                      	pop	edi
  2079 000009AF 5E                      	pop	esi
  2080 000009B0 5B                      	pop	ebx ; 29/08/2014
  2081 000009B1 58                      	pop 	eax
  2082 000009B2 CF                      	iretd
  2083                                  
  2084                                  	; 26/02/2015
  2085                                  	; 07/09/2014
  2086                                  	; 25/08/2014
  2087                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  2088                                  	; 22/08/2014
  2089 000009B3 50                      	push	eax
  2090 000009B4 53                      	push	ebx ; 29/08/2014
  2091 000009B5 56                      	push	esi
  2092 000009B6 57                      	push	edi
  2093 000009B7 1E                      	push 	ds
  2094 000009B8 06                      	push 	es
  2095                                  	;
  2096 000009B9 B810000000              	mov	eax, KDATA
  2097 000009BE 8ED8                    	mov	ds, ax
  2098 000009C0 8EC0                    	mov	es, ax
  2099                                  	;
  2100                                  	; 25/08/2014
  2101 000009C2 E884000000              	call	rtc_p
  2102                                  	;
  2103                                  	; 22/02/2015 - dsectpm.s
  2104                                  	; [ source: http://wiki.osdev.org/RTC ]
  2105                                  	; read status register C to complete procedure
  2106                                  	;(it is needed to get a next IRQ 8) 
  2107 000009C7 B00C                    	mov	al, 0Ch ; 
  2108 000009C9 E670                    	out	70h, al ; select register C
  2109 000009CB 90                      	nop
  2110 000009CC E471                    	in	al, 71h ; just throw away contents
  2111                                  	; 22/02/2015
  2112 000009CE B020                    	MOV	AL,EOI		; END OF INTERRUPT
  2113 000009D0 E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  2114                                  	;
  2115 000009D2 EBD4                    	jmp	short iiret	
  2116                                  
  2117                                  	; 22/08/2014
  2118                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  2119                                  	; (INT 1Ah)
  2120                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  2121                                  time_of_day:
  2122 000009D4 E866010000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  2123 000009D9 726F                            jc      short rtc_retn 
  2124 000009DB B000                    	mov	al, CMOS_SECONDS
  2125 000009DD E845010000              	call	CMOS_READ
  2126 000009E2 A2[6C6F0000]            	mov	[time_seconds], al 
  2127 000009E7 B002                    	mov	al, CMOS_MINUTES
  2128 000009E9 E839010000              	call	CMOS_READ
  2129 000009EE A2[6D6F0000]            	mov	[time_minutes], al 
  2130 000009F3 B004                    	mov	al, CMOS_HOURS
  2131 000009F5 E82D010000              	call	CMOS_READ
  2132 000009FA A2[6E6F0000]                    mov     [time_hours], al
  2133 000009FF B006                    	mov	al, CMOS_DAY_WEEK 
  2134 00000A01 E821010000              	call	CMOS_READ
  2135 00000A06 A2[6F6F0000]            	mov	[date_wday], al
  2136 00000A0B B007                     	mov	al, CMOS_DAY_MONTH
  2137 00000A0D E815010000              	call	CMOS_READ
  2138 00000A12 A2[706F0000]            	mov	[date_day], al
  2139 00000A17 B008                    	mov	al, CMOS_MONTH
  2140 00000A19 E809010000              	call	CMOS_READ
  2141 00000A1E A2[716F0000]            	mov	[date_month], al
  2142 00000A23 B009                    	mov	al, CMOS_YEAR
  2143 00000A25 E8FD000000              	call	CMOS_READ
  2144 00000A2A A2[726F0000]            	mov	[date_year], al
  2145 00000A2F B032                    	mov	al, CMOS_CENTURY
  2146 00000A31 E8F1000000              	call	CMOS_READ
  2147 00000A36 A2[736F0000]            	mov	[date_century], al
  2148                                  	;
  2149 00000A3B B000                    	mov	al, CMOS_SECONDS
  2150 00000A3D E8E5000000              	call 	CMOS_READ
  2151 00000A42 3A05[6C6F0000]          	cmp	al, [time_seconds]
  2152 00000A48 758A                    	jne	short time_of_day
  2153                                  
  2154                                  rtc_retn:
  2155 00000A4A C3                      	retn
  2156                                  
  2157                                  rtc_p:	
  2158                                  	; 07/09/2014
  2159                                  	; 29/08/2014
  2160                                  	; 27/08/2014
  2161                                  	; 25/08/2014
  2162                                   	; Print Real Time Clock content
  2163                                  	;
  2164                                  	;
  2165 00000A4B E884FFFFFF              	call	time_of_day
  2166 00000A50 72F8                    	jc	short rtc_retn
  2167                                  	;
  2168 00000A52 3A05[386B0000]          	cmp	al, [ptime_seconds]
  2169 00000A58 74F0                            je      short rtc_retn ; 29/08/2014
  2170                                  	;
  2171 00000A5A A2[386B0000]            	mov	[ptime_seconds], al
  2172                                  	;
  2173 00000A5F A0[736F0000]            	mov	al, [date_century]
  2174 00000A64 E8F1000000              	call	bcd_to_ascii
  2175 00000A69 66A3[056B0000]          	mov	[datestr+6], ax
  2176 00000A6F A0[726F0000]            	mov	al, [date_year]
  2177 00000A74 E8E1000000              	call	bcd_to_ascii
  2178 00000A79 66A3[076B0000]          	mov	[datestr+8], ax
  2179 00000A7F A0[716F0000]            	mov	al, [date_month]
  2180 00000A84 E8D1000000              	call	bcd_to_ascii
  2181 00000A89 66A3[026B0000]          	mov	[datestr+3], ax
  2182 00000A8F A0[706F0000]            	mov	al, [date_day]
  2183 00000A94 E8C1000000              	call	bcd_to_ascii
  2184 00000A99 66A3[FF6A0000]          	mov	[datestr], ax
  2185                                  	;
  2186 00000A9F 0FB61D[6F6F0000]        	movzx	ebx, byte [date_wday]
  2187 00000AA6 C0E302                  	shl 	bl, 2
  2188 00000AA9 81C3[186B0000]          	add	ebx, daytmp
  2189 00000AAF 8B03                    	mov	eax, [ebx]
  2190 00000AB1 A3[0A6B0000]            	mov	[daystr], eax
  2191                                  	;
  2192 00000AB6 A0[6E6F0000]            	mov	al, [time_hours]
  2193 00000ABB E89A000000              	call	bcd_to_ascii
  2194 00000AC0 66A3[0E6B0000]          	mov	[timestr], ax
  2195 00000AC6 A0[6D6F0000]            	mov	al, [time_minutes]
  2196 00000ACB E88A000000              	call	bcd_to_ascii
  2197 00000AD0 66A3[116B0000]          	mov	[timestr+3], ax
  2198 00000AD6 A0[6C6F0000]            	mov	al, [time_seconds]
  2199 00000ADB E87A000000              	call	bcd_to_ascii
  2200 00000AE0 66A3[146B0000]          	mov	[timestr+6], ax
  2201                                  	;		
  2202 00000AE6 BE[ED6A0000]            	mov	esi, rtc_msg ; message offset
  2203                                  	; 23/02/2015
  2204 00000AEB 52                      	push	edx
  2205 00000AEC 51                      	push	ecx
  2206                                  	; 07/09/2014
  2207 00000AED 66BB0200                	mov	bx, 2		; Video page 2
  2208                                  prtmsg:
  2209 00000AF1 AC                      	lodsb
  2210 00000AF2 08C0                    	or	al, al
  2211 00000AF4 740F                    	jz	short prtmsg_ok
  2212 00000AF6 56                      	push	esi
  2213 00000AF7 6653                    	push	bx
  2214 00000AF9 B43F                            mov	ah, 3Fh	; cyan (6) background, 
  2215                                  			; white (F) forecolor
  2216 00000AFB E80D090000              	call 	write_tty
  2217 00000B00 665B                    	pop	bx
  2218 00000B02 5E                      	pop	esi
  2219 00000B03 EBEC                    	jmp	short prtmsg
  2220                                  	;
  2221                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  2222                                  	;call	printk
  2223                                  prtmsg_ok:
  2224                                  	; 07/09/2014
  2225 00000B05 6631D2                  	xor	dx, dx		; column 0, row 0
  2226 00000B08 E8240A0000              	call	set_cpos	; set curspor position to 0,0 
  2227                                  	; 23/02/2015
  2228 00000B0D 59                      	pop	ecx
  2229 00000B0E 5A                      	pop	edx
  2230 00000B0F C3                      	retn
  2231                                  
  2232                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2233                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2234                                  default_irq7:
  2235 00000B10 6650                    	push	ax
  2236 00000B12 B00B                    	mov	al, 0Bh  ; In-Service register
  2237 00000B14 E620                    	out	20h, al
  2238 00000B16 EB00                            jmp short $+2
  2239 00000B18 EB00                    	jmp short $+2
  2240 00000B1A E420                    	in	al, 20h
  2241 00000B1C 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  2242 00000B1E 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  2243 00000B20 B020                            mov     al, 20h ; EOI
  2244 00000B22 E620                    	out	20h, al 
  2245                                  irq7_iret:
  2246 00000B24 6658                    	pop	ax
  2247 00000B26 CF                      	iretd
  2248                                  	
  2249                                  	; 22/08/2014
  2250                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
  2251                                  CMOS_READ:
  2252 00000B27 9C                      	pushf		; SAVE INTERRUPT ENABLE STATUS AND FLAGS
  2253 00000B28 D0C0                    	rol	al, 1	; MOVE NMI BIT TO LOW POSITION
  2254 00000B2A F9                      	stc		; FORCE NMI BIT ON IN CARRY FLAG
  2255 00000B2B D0D8                    	rcr	al, 1	; HIGH BIT ON TO DISABLE NMI - OLD IN CY
  2256 00000B2D FA                      	cli		; DISABLE INTERRUPTS
  2257 00000B2E E670                    	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
  2258 00000B30 90                      	nop		; I/O DELAY
  2259 00000B31 E471                    	in	al, CMOS_DATA	; READ THE REQUESTED CMOS LOCATION
  2260 00000B33 6650                    	push	ax	; SAVE (AH) REGISTER VALUE AND CMOS BYTE
  2261                                  	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
  2262                                  		     ; ----- 10/06/85 (test4.asm)
  2263 00000B35 B01E                    	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
  2264                                  	;mov	al, CMOS_REG_D*2 ; GET ADDRESS OF DEFAULT LOCATION
  2265 00000B37 D0D8                    	rcr	al, 1	; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
  2266 00000B39 E670                    	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
  2267 00000B3B 6658                    	pop	ax	; RESTORE (AH) AND (AL), CMOS BYTE
  2268 00000B3D 9D                      	popf	
  2269 00000B3E C3                      	retn		; RETURN WITH FLAGS RESTORED
  2270                                  
  2271                                  	; 22/08/2014
  2272                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
  2273                                  UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
  2274 00000B3F 51                      	push	ecx
  2275 00000B40 B9FFFF0000              	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
  2276                                  		; mov cx, 800	
  2277                                  UPD_10:
  2278 00000B45 B00A                    	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
  2279 00000B47 FA                      	cli				; NO TIMER INTERRUPTS DURING UPDATES
  2280 00000B48 E8DAFFFFFF              	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
  2281 00000B4D A880                    	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
  2282 00000B4F 7406                    	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
  2283 00000B51 FB                      	sti				; ALLOW INTERRUPTS WHILE WAITING
  2284 00000B52 E2F1                    	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
  2285 00000B54 31C0                    	xor	eax, eax		; CLEAR RESULTS IF ERROR
  2286                                  		; xor ax, ax
  2287 00000B56 F9                      	stc				; SET CARRY FOR ERROR
  2288                                  UPD_90:
  2289 00000B57 59                      	pop	ecx			; RESTORE CALLERS REGISTER
  2290 00000B58 FA                      	cli				; INTERRUPTS OFF DURING SET
  2291 00000B59 C3                      	retn				; RETURN WITH CY FLAG SET
  2292                                  
  2293                                  bcd_to_ascii:
  2294                                  	; 25/08/2014
  2295                                  	; INPUT ->
  2296                                  	;	al = Packed BCD number
  2297                                  	; OUTPUT ->
  2298                                  	;	ax  = ASCII word/number
  2299                                  	;
  2300                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  2301                                  	;
  2302 00000B5A D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  2303                                  					; AH = AL / 10h
  2304                                  					; AL = AL MOD 10h
  2305 00000B5C 660D3030                	or ax,'00'                      ; Make it ASCII based
  2306                                  
  2307 00000B60 86E0                            xchg ah, al 
  2308                                  	
  2309 00000B62 C3                      	retn	
  2310                                  	
  2311                                  
  2312                                  %include 'keyboard.s' ; 07/03/2015
  2313                              <1> ; Retro UNIX 386 v1 Kernel - KEYBOARD.INC
  2314                              <1> ; Last Modification: 17/10/2015
  2315                              <1> ;		    (Keyboard Data is in 'KYBDATA.INC')	
  2316                              <1> ;
  2317                              <1> ; ///////// KEYBOARD FUNCTIONS (PROCEDURES) ///////////////
  2318                              <1> 
  2319                              <1> ; 30/06/2015
  2320                              <1> ; 11/03/2015
  2321                              <1> ; 28/02/2015
  2322                              <1> ; 25/02/2015
  2323                              <1> ; 20/02/2015
  2324                              <1> ; 18/02/2015
  2325                              <1> ; 03/12/2014
  2326                              <1> ; 07/09/2014
  2327                              <1> ; KEYBOARD INTERRUPT HANDLER
  2328                              <1> ; (kb_int - Retro UNIX 8086 v1 - U0.ASM, 30/06/2014)
  2329                              <1> 
  2330                              <1> ;getch:
  2331                              <1> ;	; 18/02/2015
  2332                              <1> ;	; This routine will be replaced with Retro UNIX 386
  2333                              <1> ;	; version of Retro UNIX 8086 getch (tty input)
  2334                              <1> ;	; routine, later... (multi tasking ability)
  2335                              <1> ;	; 28/02/2015
  2336                              <1> ;	sti	; enable interrupts
  2337                              <1> ;	;
  2338                              <1> ;	;push	esi
  2339                              <1> ;	;push	ebx
  2340                              <1> ;	;xor	ebx, ebx
  2341                              <1> ;	;mov	bl, [ptty]  ; active_page
  2342                              <1> ;	;mov	esi, ebx
  2343                              <1> ;	;shl 	si, 1
  2344                              <1> ;	;add	esi, ttychr
  2345                              <1> ;getch_1:
  2346                              <1> ;	;mov	ax, [esi]
  2347                              <1> ;	mov	ax, [ttychr] ; video page 0 (tty0)
  2348                              <1> ;	and	ax, ax
  2349                              <1> ;	jz	short getch_2
  2350                              <1> ;	mov	word [ttychr], 0
  2351                              <1> ;	;mov	word [esi], 0
  2352                              <1> ;	;pop	ebx
  2353                              <1> ;	;pop	esi
  2354                              <1> ;	retn
  2355                              <1> ;getch_2:
  2356                              <1> ;	hlt	; not proper for multi tasking!
  2357                              <1> ;		; (temporary halt for now)
  2358                              <1> ;		; 'sleep' on tty 
  2359                              <1> ;		; will (must) be located here		
  2360                              <1> ;	nop
  2361                              <1> ;	jmp	short getch_1
  2362                              <1> 
  2363                              <1> keyb_int:
  2364                              <1> 	; 30/06/2015
  2365                              <1> 	; 25/02/2015
  2366                              <1> 	; 20/02/2015
  2367                              <1> 	; 03/12/2014 (getc_int - INT 16h modifications)
  2368                              <1> 	; 07/09/2014 - Retro UNIX 386 v1
  2369                              <1> 	; 30/06/2014
  2370                              <1> 	; 10/05/2013	
  2371                              <1>       	; Retro Unix 8086 v1 feature only!
  2372                              <1> 	; 03/03/2014
  2373                              <1> 	
  2374 00000B63 1E                  <1> 	push	ds
  2375 00000B64 53                  <1> 	push	ebx
  2376 00000B65 50                  <1> 	push	eax
  2377                              <1> 	;
  2378 00000B66 66B81000            <1> 	mov	ax, KDATA
  2379 00000B6A 8ED8                <1> 	mov	ds, ax
  2380                              <1> 	;
  2381 00000B6C 9C                  <1> 	pushfd
  2382 00000B6D 0E                  <1> 	push	cs
  2383 00000B6E E823020000          <1> 	call	kb_int  ; int_09h
  2384                              <1> 	;
  2385 00000B73 B411                <1> 	mov	ah, 11h	 ; 03/12/2014	
  2386                              <1> 	;call	getc
  2387 00000B75 E856000000          <1> 	call	int_16h ; 30/06/2015
  2388 00000B7A 7450                <1> 	jz	short keyb_int4
  2389                              <1> 	;
  2390 00000B7C B410                <1> 	mov	ah, 10h	 ; 03/12/2014
  2391                              <1> 	;call	getc
  2392 00000B7E E84D000000          <1> 	call	int_16h ; 30/06/2015
  2393                              <1> 	;
  2394                              <1> 	; 20/02/2015
  2395 00000B83 0FB61D[266F0000]    <1>         movzx   ebx, byte [ptty]  ; active_page
  2396                              <1> 	;
  2397 00000B8A 20C0                <1> 	and 	al, al
  2398 00000B8C 751E                <1> 	jnz	short keyb_int1
  2399                              <1> 	;
  2400 00000B8E 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  2401 00000B91 7219                <1> 	jb	short keyb_int1
  2402 00000B93 80FC6F              <1> 	cmp	ah, 6Fh  ; ALT + F8 key	
  2403 00000B96 7714                <1> 	ja	short keyb_int1
  2404                              <1> 	;
  2405 00000B98 88D8                <1> 	mov	al, bl
  2406 00000B9A 0468                <1> 	add	al, 68h
  2407 00000B9C 38E0                <1> 	cmp	al, ah
  2408 00000B9E 7409                <1> 	je	short keyb_int0
  2409 00000BA0 88E0                <1> 	mov	al, ah
  2410 00000BA2 2C68                <1> 	sub	al, 68h
  2411 00000BA4 E8520B0000          <1> 	call	tty_sw
  2412                              <1> 	;movzx	ebx, [ptty]  ; active_page
  2413                              <1> keyb_int0: ; 30/06/2015
  2414 00000BA9 6631C0              <1> 	xor	ax, ax
  2415                              <1> keyb_int1:
  2416 00000BAC D0E3                <1> 	shl	bl, 1
  2417 00000BAE 81C3[286F0000]      <1> 	add	ebx, ttychr
  2418                              <1> 	;
  2419 00000BB4 6609C0              <1> 	or	ax, ax
  2420 00000BB7 7406                <1> 	jz	short keyb_int2
  2421                              <1> 	;
  2422 00000BB9 66833B00            <1> 	cmp 	word [ebx], 0
  2423 00000BBD 7703                <1>         ja      short keyb_int3 
  2424                              <1> keyb_int2:
  2425 00000BBF 668903              <1>         mov	[ebx], ax  ; Save ascii code
  2426                              <1> 				; and scan code of the character
  2427                              <1> 				; for current tty (or last tty
  2428                              <1> 				; just before tty switch).
  2429                              <1> keyb_int3:
  2430 00000BC2 A0[266F0000]        <1>         mov     al, [ptty]
  2431 00000BC7 E824450000          <1> 	call	wakeup
  2432                              <1> 	;
  2433                              <1> keyb_int4:
  2434 00000BCC 58                  <1> 	pop	eax
  2435 00000BCD 5B                  <1> 	pop	ebx
  2436 00000BCE 1F                  <1> 	pop	ds
  2437 00000BCF CF                  <1> 	iret
  2438                              <1> 
  2439                              <1> ; 18/02/2015
  2440                              <1> ; REMINDER: Only 'keyb_int' (IRQ 9) must call getc.
  2441                              <1> ; 'keyb_int' always handles 'getc' at 1st and puts the
  2442                              <1> ; scancode and ascii code of the character 
  2443                              <1> ; in the tty input (ttychr) buffer. 
  2444                              <1> ; Test procedures must call 'getch' for tty input
  2445                              <1> ; otherwise, 'getc' will not be able to return to the caller
  2446                              <1> ; due to infinite (key press) waiting loop.
  2447                              <1> ; 
  2448                              <1> ; 03/12/2014
  2449                              <1> ; 26/08/2014
  2450                              <1> ; KEYBOARD I/O
  2451                              <1> ; (INT_16h - Retro UNIX 8086 v1 - U9.ASM, 30/06/2014)
  2452                              <1> 
  2453                              <1> ;NOTE: 'k0' to 'k7' are name of OPMASK registers.
  2454                              <1> ;	(The reason of using '_k' labels!!!) (27/08/2014)    
  2455                              <1> ;NOTE: 'NOT' keyword is '~' unary operator in NASM.
  2456                              <1> ;	('NOT LC_HC' --> '~LC_HC') (bit reversing operator)
  2457                              <1> 
  2458                              <1> int_16h: ; 30/06/2015
  2459                              <1> ;getc:
  2460 00000BD0 9C                  <1> 	pushfd	; 28/08/2014
  2461 00000BD1 0E                  <1> 	push 	cs
  2462 00000BD2 E801000000          <1> 	call 	getc_int
  2463 00000BD7 C3                  <1> 	retn	
  2464                              <1> 
  2465                              <1> getc_int:
  2466                              <1> 	; 28/02/2015
  2467                              <1> 	; 03/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2468                              <1> 	;	      instead of pc-at bios - 1985-)
  2469                              <1> 	; 28/08/2014 (_k1d)
  2470                              <1> 	; 30/06/2014
  2471                              <1> 	; 03/03/2014
  2472                              <1> 	; 28/02/2014
  2473                              <1> 	; Derived from "KEYBOARD_IO_1" procedure of IBM "pc-xt-286" 
  2474                              <1> 	; rombios source code (21/04/1986)
  2475                              <1> 	;	 'keybd.asm', INT 16H, KEYBOARD_IO
  2476                              <1> 	;
  2477                              <1> 	; KYBD --- 03/06/86  KEYBOARD BIOS
  2478                              <1> 	;
  2479                              <1> 	;--- INT 16 H -----------------------------------------------------------------
  2480                              <1> 	; KEYBOARD I/O								      :
  2481                              <1> 	;	THESE ROUTINES PROVIDE READ KEYBOARD SUPPORT			      :
  2482                              <1> 	; INPUT									      :
  2483                              <1> 	;	(AH)= 00H  READ THE NEXT ASCII CHARACTER ENTERED FROM THE KEYBOARD,   :
  2484                              <1> 	;		   RETURN THE RESULT IN (AL), SCAN CODE IN (AH).              :
  2485                              <1> 	;		   THIS IS THE COMPATIBLE READ INTERFACE, EQUIVALENT TO THE   :
  2486                              <1> 	;                  STANDARD PC OR PCAT KEYBOARD				      :	
  2487                              <1> 	;-----------------------------------------------------------------------------:
  2488                              <1> 	;	(AH)= 01H  SET THE ZERO FLAG TO INDICATE IF AN ASCII CHARACTER IS     :
  2489                              <1> 	;		   AVAILABLE TO BE READ FROM THE KEYBOARD BUFFER.	      :
  2490                              <1> 	;		   (ZF)= 1 -- NO CODE AVAILABLE			              :
  2491                              <1> 	;		   (ZF)= 0 -- CODE IS AVAILABLE  (AX)= CHARACTER              :
  2492                              <1> 	;		   IF (ZF)= 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS :
  2493                              <1> 	;		   IN (AX), AND THE ENTRY REMAINS IN THE BUFFER.              :
  2494                              <1> 	;		   THIS WILL RETURN ONLY PC/PCAT KEYBOARD COMPATIBLE CODES    :
  2495                              <1> 	;-----------------------------------------------------------------------------:	
  2496                              <1> 	;	(AH)= 02H  RETURN THE CURRENT SHIFT STATUS IN AL REGISTER             :
  2497                              <1> 	;		   THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE        :
  2498                              <1> 	;		   EQUATES FOR @KB_FLAG		                              :
  2499                              <1> 	;-----------------------------------------------------------------------------:	
  2500                              <1> 	;	(AH)= 03H  SET TYPAMATIC RATE AND DELAY                               :
  2501                              <1> 	;	      (AL) = 05H                                                      :
  2502                              <1> 	;	      (BL) = TYPAMATIC RATE (BITS 5 - 7 MUST BE RESET TO 0)           :
  2503                              <1> 	;		       							      :
  2504                              <1> 	;                     REGISTER     RATE      REGISTER     RATE                :
  2505                              <1> 	;                      VALUE     SELECTED     VALUE     SELECTED              :
  2506                              <1> 	;                     --------------------------------------------            :
  2507                              <1> 	;			00H        30.0        10H        7.5                 :
  2508                              <1> 	;			01H        26.7        11H        6.7                 :
  2509                              <1> 	;			02H        24.0        12H        6.0                 :
  2510                              <1> 	;			03H        21.8        13H        5.5                 :
  2511                              <1> 	;			04H        20.0        14H        5.0                 :
  2512                              <1> 	;			05H        18.5        15H        4.6                 :
  2513                              <1> 	;			06H        17.1        16H        4.3                 :
  2514                              <1> 	;			07H        16.0        17H        4.0                 :
  2515                              <1> 	;			08H        15.0        18H        3.7                 :
  2516                              <1> 	;			09H        13.3        19H        3.3                 :
  2517                              <1> 	;			0AH        12.0        1AH        3.0                 :
  2518                              <1> 	;			0BH        10.9        1BH        2.7                 :
  2519                              <1>         ;			0CH        10.0        1CH        2.5                 :
  2520                              <1> 	;			0DH         9.2        1DH        2.3                 :
  2521                              <1> 	;			0EH         8.6        1EH        2.1                 :
  2522                              <1> 	;			0FH         8.0        1FH        2.0                 :
  2523                              <1> 	;									      :
  2524                              <1> 	;	      (BH) = TYPAMATIC DELAY  (BITS 2 - 7 MUST BE RESET TO 0)         :
  2525                              <1> 	;		       							      :
  2526                              <1> 	;                     REGISTER     DELAY                                      :
  2527                              <1> 	;                      VALUE       VALUE                                      :
  2528                              <1> 	;                     ------------------                                      :
  2529                              <1> 	;			00H        250 ms                                     :
  2530                              <1> 	;			01H        500 ms                                     :
  2531                              <1> 	;			02H        750 ms                                     :
  2532                              <1> 	;			03H       1000 ms                                     :
  2533                              <1> 	;-----------------------------------------------------------------------------:
  2534                              <1> 	;	(AH)= 05H  PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD    :
  2535                              <1> 	;		   BUFFER AS IF STRUCK FROM KEYBOARD                          :
  2536                              <1> 	;		   ENTRY:  (CL) = ASCII CHARACTER		              :
  2537                              <1> 	;		           (CH) = SCAN CODE                                   :
  2538                              <1> 	;		   EXIT:   (AH) = 00H = SUCCESSFUL OPERATION                  :
  2539                              <1> 	;		           (AL) = 01H = UNSUCCESSFUL - BUFFER FULL            :
  2540                              <1> 	;		   FLAGS:  CARRY IF ERROR                                     :
  2541                              <1> 	;-----------------------------------------------------------------------------:		
  2542                              <1> 	;	(AH)= 10H  EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD,         :
  2543                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=0                            :
  2544                              <1> 	;-----------------------------------------------------------------------------:
  2545                              <1> 	;	(AH)= 11H  EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,           :
  2546                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=1                            :
  2547                              <1> 	;-----------------------------------------------------------------------------:	
  2548                              <1> 	;	(AH)= 12H  RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER            :
  2549                              <1> 	;		   AL = BITS FROM KB_FLAG, AH = BITS FOR LEFT AND RIGHT       :
  2550                              <1> 	;		   CTL AND ALT KEYS FROM KB_FLAG_1 AND KB_FLAG_3              :
  2551                              <1> 	; OUTPUT					                              :
  2552                              <1> 	;	AS NOTED ABOVE, ONLY (AX) AND FLAGS CHANGED	                      :
  2553                              <1> 	;	ALL REGISTERS RETAINED		                                      :
  2554                              <1> 	;------------------------------------------------------------------------------
  2555                              <1> 	
  2556 00000BD8 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2557 00000BD9 1E                  <1> 	push	ds			; SAVE CURRENT DS
  2558 00000BDA 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
  2559                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
  2560 00000BDB 66BB1000            <1>         mov     bx, KDATA 
  2561 00000BDF 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
  2562 00000BE1 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
  2563 00000BE3 7439                <1> 	jz	short _K1		; ASCII_READ
  2564 00000BE5 FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
  2565 00000BE7 7452                <1>         jz      short _K2               ; ASCII_STATUS
  2566 00000BE9 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
  2567 00000BEB 0F8485000000        <1>         jz      _K3                     ; SHIFT STATUS
  2568 00000BF1 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
  2569 00000BF3 0F8484000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
  2570 00000BF9 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
  2571 00000BFC 0F84A1000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
  2572                              <1> _KIO1:	
  2573 00000C02 80EC0B              <1> 	sub	ah, 11			; AH =  10H
  2574 00000C05 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
  2575 00000C07 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
  2576 00000C09 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
  2577 00000C0B FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
  2578 00000C0D 7449                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
  2579                              <1> _KIO_EXIT:
  2580                              <1> 	;pop	ecx			; RECOVER REGISTER
  2581 00000C0F 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2582 00000C10 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2583 00000C11 CF                  <1> 	iretd				; INVALID COMMAND, EXIT
  2584                              <1> 
  2585                              <1> 	;-----	ASCII CHARACTER
  2586                              <1> _K1E:	
  2587 00000C12 E8B9000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
  2588 00000C17 E82E010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2589 00000C1C EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
  2590                              <1> _K1:	
  2591 00000C1E E8AD000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
  2592 00000C23 E82D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2593 00000C28 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
  2594                              <1> _K1A:
  2595 00000C2A EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
  2596                              <1> 
  2597                              <1> 	;-----	ASCII STATUS
  2598                              <1> _K2E:	
  2599 00000C2C E8EA000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
  2600 00000C31 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2601 00000C33 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2602 00000C34 E811010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2603 00000C39 EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
  2604                              <1> _K2:	
  2605 00000C3B E8DB000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
  2606 00000C40 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2607 00000C42 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2608 00000C43 E80D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2609 00000C48 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
  2610 00000C4A 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
  2611 00000C4B E880000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
  2612 00000C50 EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
  2613                              <1> _K2A:
  2614 00000C52 9D                  <1> 	popf				; RESTORE ZF FROM TEST
  2615                              <1> _K2B:
  2616                              <1> 	;pop	ecx			; RECOVER REGISTER
  2617 00000C53 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2618 00000C54 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2619 00000C55 CA0400              <1> 	retf	4			; THROW AWAY (e)FLAGS
  2620                              <1> 
  2621                              <1> 	;-----	SHIFT STATUS
  2622                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
  2623 00000C58 8A25[24690000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2624 00000C5E 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2625                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2626                              <1> 	;shl	ah, cl			; BIT 7 POSITION
  2627 00000C61 C0E405              <1>         shl	ah, 5
  2628 00000C64 A0[24690000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2629 00000C69 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2630 00000C6B 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2631 00000C6D A0[26690000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2632 00000C72 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2633 00000C74 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2634                              <1> _K3:
  2635 00000C76 A0[23690000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2636 00000C7B EB92                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2637                              <1> 
  2638                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
  2639                              <1> _K300:
  2640 00000C7D 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
  2641 00000C7F 758E                <1> 	jne	short _KIO_EXIT		; NO, RETURN
  2642 00000C81 F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
  2643 00000C84 7589                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2644 00000C86 F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
  2645 00000C89 7584                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2646 00000C8B B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
  2647 00000C8D E8B6060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2648                              <1> 	;mov	cx, 5			; SHIFT COUNT
  2649                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
  2650 00000C92 C0E705              <1> 	shl	bh, 5
  2651 00000C95 88D8                <1> 	mov	al, bl			; PUT IN RATE
  2652 00000C97 08F8                <1> 	or	al, bh			; AND DELAY
  2653 00000C99 E8AA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2654 00000C9E E96CFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
  2655                              <1> 
  2656                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
  2657                              <1> _K500:
  2658 00000CA3 56                  <1> 	push	esi			; SAVE SI (esi)
  2659 00000CA4 FA                  <1> 	cli				; 
  2660 00000CA5 8B1D[34690000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
  2661 00000CAB 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
  2662 00000CAD E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
  2663 00000CB2 3B1D[30690000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
  2664 00000CB8 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
  2665 00000CBA 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
  2666 00000CBD 891D[34690000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
  2667 00000CC3 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
  2668 00000CC5 EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
  2669                              <1> _K502:
  2670 00000CC7 B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
  2671                              <1> _K504:
  2672 00000CC9 FB                  <1> 	sti				
  2673 00000CCA 5E                  <1> 	pop	esi			; RECOVER SI (esi)
  2674 00000CCB E93FFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
  2675                              <1> 
  2676                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
  2677                              <1> _K1S:
  2678 00000CD0 FA                  <1> 	cli	; 03/12/2014
  2679 00000CD1 8B1D[30690000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2680 00000CD7 3B1D[34690000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2681                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
  2682 00000CDD 750F                <1> 	jne	short _k1x ; 03/12/2014
  2683                              <1> 	;
  2684                              <1> 	; 03/12/2014
  2685                              <1> 	; 28/08/2014
  2686                              <1> 	; PERFORM OTHER FUNCTION ?? here !
  2687                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
  2688                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
  2689                              <1> _K1T:                                   ; ASCII READ
  2690 00000CDF FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
  2691 00000CE0 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
  2692                              <1> _K1U:	
  2693 00000CE1 FA                  <1> 	cli				; INTERRUPTS BACK OFF
  2694 00000CE2 8B1D[30690000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2695 00000CE8 3B1D[34690000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2696                              <1> _k1x:
  2697 00000CEE 53                  <1> 	push	ebx			; SAVE ADDRESS		
  2698 00000CEF 9C                  <1> 	pushf				; SAVE FLAGS
  2699 00000CF0 E80B070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2700 00000CF5 8A1D[25690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2701 00000CFB 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2702 00000CFD 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
  2703 00000D00 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
  2704 00000D02 E8A5060000          <1> 	call	SND_LED1
  2705 00000D07 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2706                              <1> _K1V:
  2707 00000D08 9D                  <1> 	popf				; RESTORE FLAGS
  2708 00000D09 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2709 00000D0A 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
  2710                              <1> 	;
  2711 00000D0C 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
  2712 00000D0F E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
  2713 00000D14 891D[30690000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
  2714 00000D1A C3                  <1> 	retn				; RETURN
  2715                              <1> 
  2716                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
  2717                              <1> _K2S:
  2718 00000D1B FA                  <1> 	cli				; INTERRUPTS OFF
  2719 00000D1C 8B1D[30690000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
  2720 00000D22 3B1D[34690000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
  2721 00000D28 668B03              <1> 	mov	ax, [ebx]
  2722 00000D2B 9C                  <1> 	pushf				; SAVE FLAGS
  2723 00000D2C 6650                <1> 	push	ax			; SAVE CODE
  2724 00000D2E E8CD060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2725 00000D33 8A1D[25690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2726 00000D39 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2727 00000D3B 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
  2728 00000D3E 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
  2729 00000D40 E850060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2730                              <1> _K2T:
  2731 00000D45 6658                <1> 	pop	ax			; RESTORE CODE
  2732 00000D47 9D                  <1> 	popf				; RESTORE FLAGS
  2733 00000D48 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2734 00000D49 C3                  <1> 	retn				; RETURN
  2735                              <1> 
  2736                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
  2737                              <1> _KIO_E_XLAT:
  2738 00000D4A 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2739 00000D4C 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
  2740 00000D4E 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
  2741 00000D50 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
  2742 00000D52 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
  2743                              <1> _KIO_E_RET:				
  2744 00000D54 C3                  <1> 	retn				; GO BACK
  2745                              <1> 
  2746                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
  2747                              <1> _KIO_S_XLAT:
  2748 00000D55 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
  2749 00000D58 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
  2750 00000D5A 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
  2751 00000D5C 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
  2752 00000D5E 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
  2753 00000D60 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
  2754 00000D62 B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
  2755                              <1> _kio_ret: ; 03/12/2014
  2756 00000D64 F8                  <1> 	clc
  2757 00000D65 C3                  <1> 	retn
  2758                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2759                              <1> _KIO_S1:				
  2760 00000D66 B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
  2761                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2762 00000D68 C3                  <1> 	retn
  2763                              <1> _KIO_S2:		
  2764 00000D69 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
  2765 00000D6C 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
  2766 00000D6E 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2767 00000D70 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
  2768 00000D72 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2769 00000D74 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
  2770 00000D76 EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
  2771                              <1> _KIO_S3:
  2772 00000D78 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
  2773                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
  2774 00000D7A 75E8                <1> 	jne	short _kio_ret
  2775 00000D7C 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2776 00000D7E 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
  2777 00000D80 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
  2778                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
  2779                              <1> _KIO_USE:
  2780                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
  2781 00000D82 C3                  <1> 	retn				; RETURN	
  2782                              <1> _KIO_DIS:
  2783 00000D83 F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
  2784 00000D84 C3                  <1> 	retn				; RETURN
  2785                              <1> 
  2786                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
  2787                              <1> _K4:    
  2788 00000D85 43                  <1> 	inc     ebx
  2789 00000D86 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
  2790 00000D87 3B1D[2C690000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
  2791                              <1>         ;jne    short _K5               ; NO, CONTINUE
  2792 00000D8D 7206                <1> 	jb	short _K5
  2793 00000D8F 8B1D[28690000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
  2794                              <1> _K5:
  2795 00000D95 C3                  <1> 	retn
  2796                              <1> 
  2797                              <1> ; 20/02/2015
  2798                              <1> ; 05/12/2014
  2799                              <1> ; 26/08/2014
  2800                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
  2801                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
  2802                              <1> ;
  2803                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
  2804                              <1> ; rombios source code (06/10/1985)
  2805                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
  2806                              <1> 
  2807                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
  2808                              <1> ENA_KBD		equ	0AEh	; ENABLE KEYBOARD COMMAND
  2809                              <1> DIS_KBD		equ	0ADh	; DISABLE KEYBOARD COMMAND
  2810                              <1> SHUT_CMD	equ	0FEh	; CAUSE A SHUTDOWN COMMAND
  2811                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  2812                              <1> STATUS_PORT	equ	064h	; 8042 STATUS PORT
  2813                              <1> INPT_BUF_FULL	equ	00000010b ; 1 = +INPUT BUFFER FULL
  2814                              <1> PORT_A		equ	060h	; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  2815                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
  2816                              <1> KB_ACK		equ	0FAh	; ACKNOWLEDGE PROM TRANSMISSION
  2817                              <1> KB_RESEND	equ	0FEh	; RESEND REQUEST
  2818                              <1> KB_OVER_RUN	equ	0FFh	; OVER RUN SCAN CODE
  2819                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
  2820                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
  2821                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
  2822                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
  2823                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
  2824                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
  2825                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
  2826                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
  2827                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
  2828                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
  2829                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
  2830                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
  2831                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
  2832                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
  2833                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
  2834                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
  2835                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
  2836                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
  2837                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
  2838                              <1> F11_M		equ	87		; F11 KEY MAKE
  2839                              <1> F12_M		equ	88		; F12 KEY MAKE
  2840                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
  2841                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
  2842                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
  2843                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
  2844                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
  2845                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
  2846                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
  2847                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
  2848                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
  2849                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
  2850                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
  2851                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
  2852                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
  2853                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
  2854                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
  2855                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
  2856                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
  2857                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
  2858                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
  2859                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
  2860                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
  2861                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
  2862                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
  2863                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
  2864                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
  2865                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
  2866                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
  2867                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
  2868                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
  2869                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
  2870                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
  2871                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
  2872                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
  2873                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
  2874                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
  2875                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
  2876                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
  2877                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
  2878                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
  2879                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
  2880                              <1> ;
  2881                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
  2882                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
  2883                              <1> INTA00		equ	020h		; 8259 PORT
  2884                              <1> 
  2885                              <1> 
  2886                              <1> kb_int:
  2887                              <1> 
  2888                              <1> ; 17/10/2015 ('ctrlbrk') 
  2889                              <1> ; 05/12/2014
  2890                              <1> ; 04/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2891                              <1> 	;	      instead of pc-at bios - 1985-)
  2892                              <1> ; 26/08/2014
  2893                              <1> ;
  2894                              <1> ; 03/06/86  KEYBOARD BIOS
  2895                              <1> ;
  2896                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
  2897                              <1> ;										;
  2898                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
  2899                              <1> ;										;
  2900                              <1> ;--------------------------------------------------------------------------------
  2901                              <1> 
  2902                              <1> KB_INT_1:
  2903 00000D96 FB                  <1> 	sti				; ENABLE INTERRUPTS
  2904                              <1> 	;push	ebp
  2905 00000D97 50                  <1> 	push	eax
  2906 00000D98 53                  <1> 	push	ebx
  2907 00000D99 51                  <1> 	push	ecx
  2908 00000D9A 52                  <1> 	push	edx
  2909 00000D9B 56                  <1> 	push	esi
  2910 00000D9C 57                  <1> 	push	edi
  2911 00000D9D 1E                  <1> 	push	ds
  2912 00000D9E 06                  <1> 	push	es
  2913 00000D9F FC                  <1> 	cld				; FORWARD DIRECTION
  2914 00000DA0 66B81000            <1> 	mov	ax, KDATA
  2915 00000DA4 8ED8                <1> 	mov	ds, ax
  2916 00000DA6 8EC0                <1> 	mov	es, ax
  2917                              <1> 	;
  2918                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
  2919 00000DA8 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
  2920 00000DAA E885050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
  2921 00000DAF FA                  <1> 	cli				; DISABLE INTERRUPTS
  2922 00000DB0 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
  2923                              <1> KB_INT_01:
  2924 00000DB5 E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
  2925 00000DB7 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
  2926 00000DB9 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
  2927                              <1> 	;
  2928                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
  2929 00000DBB E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
  2930                              <1> 	;
  2931                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
  2932                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
  2933                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
  2934                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
  2935                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
  2936                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
  2937                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
  2938                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
  2939                              <1> 	;
  2940                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
  2941                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
  2942 00000DBD FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  2943 00000DBE 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
  2944 00000DC0 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
  2945                              <1> 	;
  2946                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
  2947 00000DC2 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
  2948 00000DC4 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
  2949                              <1> 	;
  2950                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
  2951 00000DC6 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2952 00000DC7 800D[25690000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
  2953 00000DCE E97A020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
  2954                              <1> 	;
  2955                              <1> 	;-----	RESEND THE LAST BYTE
  2956                              <1> KB_INT_4:
  2957 00000DD3 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2958 00000DD4 800D[25690000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
  2959 00000DDB E96D020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
  2960                              <1> 	;
  2961                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
  2962                              <1> KB_INT_2:
  2963 00000DE0 6650                <1> 	push 	ax			; SAVE DATA IN
  2964 00000DE2 E819060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2965 00000DE7 8A1D[25690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2966 00000DED 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2967 00000DEF 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
  2968 00000DF2 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
  2969 00000DF4 E89C050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2970                              <1> UP0:
  2971 00000DF9 6658                <1> 	pop	ax			; RESTORE DATA IN
  2972                              <1> ;------------------------------------------------------------------------
  2973                              <1> ;	START OF KEY PROCESSING						;
  2974                              <1> ;------------------------------------------------------------------------
  2975 00000DFB 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
  2976                              <1> 	;
  2977                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
  2978 00000DFD 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
  2979 00000DFF 0F841B050000        <1>         je      K62			; BUFFER_FULL_BEEP
  2980                              <1> 	;
  2981                              <1> K16:	
  2982 00000E05 8A3D[26690000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
  2983                              <1> 	;
  2984                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
  2985 00000E0B F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
  2986 00000E0E 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
  2987 00000E10 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
  2988 00000E12 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
  2989 00000E14 7507                <1> 	jne	short RST_RD_ID
  2990 00000E16 800D[26690000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
  2991                              <1> RST_RD_ID:
  2992 00000E1D 8025[26690000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
  2993                              <1>         ;jmp    short ID_EX		; AND EXIT
  2994 00000E24 E924020000          <1> 	jmp	K26
  2995                              <1> 	;
  2996                              <1> TST_ID_2:
  2997 00000E29 8025[26690000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
  2998 00000E30 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
  2999 00000E32 7419                <1>         je	short KX_BIT		; JUMP IF SO
  3000 00000E34 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
  3001                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
  3002 00000E36 0F8511020000        <1> 	jne	K26
  3003                              <1> 	;
  3004                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
  3005 00000E3C F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
  3006 00000E3F 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
  3007 00000E41 800D[23690000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
  3008 00000E48 E848050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
  3009                              <1> KX_BIT:
  3010 00000E4D 800D[26690000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
  3011 00000E54 E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
  3012                              <1> 	;
  3013                              <1> NOT_ID:
  3014 00000E59 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
  3015 00000E5B 750C                <1> 	jne	short TEST_E1
  3016 00000E5D 800D[26690000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
  3017                              <1> 	;jmp	short EXIT		; THROW AWAY THIS CODE
  3018 00000E64 E9EB010000          <1> 	jmp	K26A	
  3019                              <1> TEST_E1:	
  3020 00000E69 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
  3021 00000E6B 750C                <1> 	jne	short NOT_HC
  3022 00000E6D 800D[26690000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
  3023 00000E74 E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
  3024                              <1> 	;
  3025                              <1> NOT_HC:
  3026 00000E79 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
  3027 00000E7B F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
  3028 00000E7E 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
  3029                              <1> 	;
  3030 00000E80 BF[0E680000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
  3031 00000E85 AE                  <1> 	scasb
  3032 00000E86 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
  3033 00000E8C AE                  <1> 	scasb
  3034 00000E8D 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
  3035                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
  3036 00000E8F E9B9010000          <1> 	jmp	K26
  3037                              <1> 	;
  3038                              <1> NOT_LC_E0:
  3039 00000E94 F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
  3040 00000E97 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
  3041 00000E99 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
  3042 00000E9E BF[0C680000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
  3043 00000EA3 F2AE                <1> 	repne	scasb			; CHECK IT
  3044                              <1> 	;je	short EXIT		; THROW AWAY IF SO
  3045 00000EA5 0F84A9010000        <1> 	je	K26A			
  3046                              <1> 	;
  3047 00000EAB 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
  3048                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
  3049 00000EAD 0F859A010000        <1> 	jne	K26
  3050 00000EB3 F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
  3051                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
  3052 00000EB6 0F8591010000        <1> 	jnz	K26
  3053                              <1>         ; 20/02/2015 
  3054 00000EBC F605[24690000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
  3055                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
  3056 00000EC3 0F8584010000        <1> 	jnz	K26
  3057 00000EC9 E9E1020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
  3058                              <1> 	;
  3059                              <1> 	;-----	TEST FOR SYSTEM KEY
  3060                              <1> T_SYS_KEY:
  3061 00000ECE 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
  3062 00000ED0 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
  3063                              <1> 	;
  3064 00000ED2 F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
  3065 00000ED5 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
  3066                              <1> 	;
  3067 00000ED7 F605[24690000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
  3068                              <1>         ;jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
  3069 00000EDE 0F8569010000        <1> 	jnz     K26			
  3070                              <1> 	;
  3071 00000EE4 800D[24690000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
  3072 00000EEB B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3073 00000EED E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3074                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3075 00000EEF B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3076 00000EF1 E83E040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3077                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
  3078                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
  3079                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  3080                              <1> 	;INT	15H			; USER INTERRUPT	
  3081 00000EF6 E965010000          <1>         jmp     K27A                    ; END PROCESSING
  3082                              <1> 	;
  3083                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
  3084                              <1> 	;
  3085                              <1> K16C:
  3086 00000EFB 8025[24690000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
  3087 00000F02 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3088 00000F04 E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
  3089                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3090                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3091                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3092                              <1> 	;
  3093                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
  3094                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  3095                              <1> 	;INT	15H			; USER INTERRUPT
  3096                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
  3097                              <1> 	;
  3098 00000F06 E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
  3099                              <1> 	;
  3100                              <1> 	;-----	TEST FOR SHIFT KEYS
  3101                              <1> K16A:
  3102 00000F0B 8A1D[23690000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
  3103 00000F11 BF[08680000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
  3104 00000F16 B908000000          <1> 	mov	ecx, _K6L		; LENGTH
  3105 00000F1B F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
  3106 00000F1D 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
  3107 00000F1F 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
  3108                              <1> 	;
  3109                              <1> 	;------	SHIFT KEY FOUND
  3110                              <1> K17:
  3111 00000F25 81EF[09680000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
  3112 00000F2B 8AA7[10680000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
  3113 00000F31 B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
  3114 00000F33 A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
  3115 00000F35 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
  3116                              <1> 	;
  3117                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
  3118                              <1> K17C:
  3119 00000F3B 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
  3120 00000F3E 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
  3121                              <1> 	;
  3122                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
  3123 00000F40 0825[23690000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
  3124 00000F46 A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
  3125                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
  3126 00000F48 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
  3127                              <1> K17D:
  3128 00000F4E F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
  3129 00000F51 740B                <1> 	jz 	short K17E		; NO, JUMP
  3130 00000F53 0825[26690000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
  3131 00000F59 E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
  3132                              <1> K17E:
  3133 00000F5E D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
  3134 00000F60 0825[24690000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
  3135 00000F66 E9E2000000          <1> 	jmp	K26
  3136                              <1> 	;
  3137                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
  3138                              <1> K18:					; SHIFT-TOGGLE
  3139 00000F6B F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
  3140                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
  3141 00000F6E 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
  3142                              <1> K18A:
  3143 00000F74 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
  3144 00000F76 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
  3145 00000F78 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
  3146                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
  3147 00000F7B 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
  3148                              <1> K18B:
  3149 00000F81 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
  3150 00000F84 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
  3151                              <1> K19:	
  3152 00000F86 F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
  3153 00000F89 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
  3154 00000F8B F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
  3155 00000F8E 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
  3156                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
  3157 00000F90 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
  3158 00000F92 E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
  3159                              <1> K21:					; MIGHT BE NUMERIC
  3160 00000F97 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
  3161 00000F9A 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
  3162                              <1> 	;
  3163                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
  3164 00000F9C 8425[24690000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
  3165 00000FA2 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
  3166                              <1> K22A:
  3167 00000FA8 0825[24690000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
  3168 00000FAE 3025[23690000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
  3169                              <1> 	;
  3170                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
  3171 00000FB4 F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
  3172 00000FB7 7409                <1> 	jz	short K22B		; GO IF NOT
  3173                              <1> 	;
  3174 00000FB9 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
  3175 00000FBB E8D5030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
  3176 00000FC0 6658                <1> 	pop	ax			; RESTORE SCAN CODE
  3177                              <1> K22B:
  3178 00000FC2 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
  3179 00000FC4 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
  3180 00000FCA 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
  3181 00000FCC E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
  3182                              <1> 	;
  3183                              <1> 	;-----	BREAK SHIFT FOUND
  3184                              <1> K23:					; BREAK-SHIFT-FOUND
  3185 00000FD1 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
  3186 00000FD4 F6D4                <1> 	not	ah			; INVERT MASK
  3187 00000FD6 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
  3188 00000FD8 2025[23690000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
  3189 00000FDE 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
  3190 00000FE1 7730                <1> 	ja	short K23D		; NO, ALL DONE
  3191                              <1> 	;
  3192 00000FE3 F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
  3193 00000FE6 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
  3194 00000FE8 2025[26690000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
  3195 00000FEE EB08                <1> 	jmp	short K23B		; CONTINUE
  3196                              <1> K23A:
  3197 00000FF0 D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
  3198 00000FF2 2025[24690000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
  3199                              <1> K23B:
  3200 00000FF8 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
  3201 00000FFA A0[26690000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
  3202 00000FFF D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
  3203 00001001 0A05[24690000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
  3204 00001007 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
  3205 00001009 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
  3206 0000100B 0805[23690000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
  3207 00001011 88E0                <1> 	mov	al, ah
  3208                              <1> K23D:
  3209 00001013 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
  3210 00001015 7536                <1> 	jne	short K26		; INTERRUPT RETURN
  3211                              <1> 	;	
  3212                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
  3213 00001017 A0[27690000]        <1> 	mov	al, [ALT_INPUT]
  3214 0000101C B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
  3215 0000101E 8825[27690000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
  3216 00001024 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
  3217 00001026 7425                <1> 	je	short K26		; INTERRUPT_RETURN
  3218 00001028 E9D0020000          <1>         jmp     K61                     ; IT WASN'T, SO PUT IN BUFFER
  3219                              <1> 	;
  3220                              <1> K24:					; BREAK-TOGGLE
  3221 0000102D 2025[24690000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
  3222 00001033 EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
  3223                              <1> 	;
  3224                              <1> 	;-----	TEST FOR HOLD STATE
  3225                              <1> 					; AL, AH = SCAN CODE
  3226                              <1> K25:					; NO-SHIFT-FOUND
  3227 00001035 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
  3228 00001037 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
  3229 00001039 F605[24690000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
  3230 00001040 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
  3231 00001042 3C45                <1> 	cmp	al, NUM_KEY
  3232 00001044 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
  3233 00001046 8025[24690000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
  3234                              <1> 	;
  3235                              <1> K26:
  3236 0000104D 8025[26690000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3237                              <1> K26A:					; INTERRUPT-RETURN
  3238 00001054 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3239 00001055 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3240 00001057 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3241                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
  3242 00001059 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3243 0000105B E8D4020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3244                              <1> K27A:
  3245 00001060 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3246 00001061 07                  <1> 	pop	es			; RESTORE REGISTERS
  3247 00001062 1F                  <1> 	pop	ds
  3248 00001063 5F                  <1> 	pop	edi
  3249 00001064 5E                  <1> 	pop	esi
  3250 00001065 5A                  <1> 	pop	edx
  3251 00001066 59                  <1> 	pop	ecx
  3252 00001067 5B                  <1> 	pop	ebx
  3253 00001068 58                  <1> 	pop	eax
  3254                              <1> 	;pop	ebp
  3255 00001069 CF                  <1> 	iret				; RETURN
  3256                              <1> 
  3257                              <1> 	;-----	NOT IN	HOLD STATE
  3258                              <1> K28:					; NO-HOLD-STATE
  3259 0000106A 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
  3260 0000106C 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
  3261                              <1> 	;
  3262 0000106E F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
  3263                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
  3264 00001071 0F84F1000000        <1>         jz      K38
  3265                              <1> 	;
  3266 00001077 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
  3267 0000107A 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  3268                              <1> 	 ;28/02/2015
  3269 0000107C F605[24690000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
  3270                              <1> 	;jz	short K29		;  NO, ALT STATE IS REAL
  3271 00001083 0F85DF000000        <1> 	jnz	K38			; YES, THIS IS PHONY ALT STATE 
  3272                              <1>         ;				; DUE TO PRESSING SYSREQ	
  3273                              <1> ;K28A:	jmp	short K38
  3274                              <1> 	;
  3275                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
  3276                              <1> K29:					; TEST-RESET
  3277 00001089 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
  3278 0000108C 740B                <1> 	jz	short K31		; NO_RESET
  3279 0000108E 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
  3280 00001090 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
  3281                              <1> 	;
  3282                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
  3283                              <1>  	; 26/08/2014
  3284                              <1> cpu_reset:
  3285                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
  3286                              <1> 	; Send FEh (system reset command) to the keyboard controller.
  3287 00001092 B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
  3288 00001094 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
  3289                              <1> khere:
  3290 00001096 F4                  <1> 	hlt				; WAIT FOR 80286 RESET
  3291 00001097 EBFD                <1> 	jmp 	short khere		; INSURE HALT
  3292                              <1> 
  3293                              <1> 	;
  3294                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
  3295                              <1> K31:					; NO-RESET
  3296 00001099 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
  3297 0000109B 7507                <1> 	jne	short K311		; NOT THERE
  3298 0000109D B020                <1> 	mov	al, ' '			; SET SPACE CHAR
  3299 0000109F E948020000          <1>         jmp     K57                     ; BUFFER_FILL
  3300                              <1> K311:
  3301 000010A4 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
  3302 000010A6 7509                <1> 	jne	short K312		; NOT THERE
  3303 000010A8 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
  3304 000010AC E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
  3305                              <1> K312:
  3306 000010B1 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
  3307 000010B3 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
  3308 000010B9 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
  3309 000010BB 0F849A000000        <1>         je      K37B                    ; GO PROCESS
  3310                              <1> 	;
  3311                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
  3312                              <1> K32:					; ALT-KEY-PAD
  3313 000010C1 BF[E4670000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
  3314 000010C6 B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
  3315 000010CB F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
  3316 000010CD 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
  3317 000010CF F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
  3318 000010D2 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
  3319 000010D8 81EF[E5670000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
  3320 000010DE A0[27690000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
  3321 000010E3 B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
  3322 000010E5 F6E4                <1> 	mul	ah
  3323 000010E7 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
  3324 000010EA A2[27690000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
  3325                              <1> ;K32A:
  3326 000010EF E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
  3327                              <1> 	;
  3328                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
  3329                              <1> K33:					; NO-ALT-KEYPAD
  3330 000010F4 C605[27690000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
  3331 000010FB B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
  3332 00001100 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
  3333 00001102 7450                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
  3334                              <1> 	;
  3335                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
  3336                              <1> K34:					; ALT-TOP-ROW
  3337 00001104 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
  3338 00001106 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
  3339 00001108 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
  3340 0000110A 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
  3341 0000110C 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
  3342 0000110F EB43                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3343                              <1> 	;
  3344                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
  3345                              <1> K35:					; ALT-FUNCTION
  3346 00001111 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
  3347 00001113 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
  3348 00001115 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
  3349 00001117 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
  3350 00001119 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
  3351 0000111C EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3352                              <1> K35A:
  3353 0000111E F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
  3354 00001121 7422                <1> 	jz	short K37		; NO, JUMP
  3355 00001123 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
  3356 00001125 7509                <1>         jne     short K35B              ; NOT THERE
  3357 00001127 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
  3358 0000112B E9BC010000          <1> 	jmp	K57			; BUFFER FILL
  3359                              <1> K35B:
  3360 00001130 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
  3361 00001132 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
  3362 00001134 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
  3363                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
  3364 00001136 0F8511FFFFFF        <1>         jne     K26
  3365 0000113C 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
  3366 00001140 E9A7010000          <1> 	jmp	K57			; BUFFER FILL
  3367                              <1> K37:
  3368 00001145 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
  3369 00001147 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
  3370 00001149 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
  3371                              <1>         ;ja	short K32A		; IF SO, IGNORE
  3372 0000114B 0F87FCFEFFFF        <1>         ja      K26
  3373 00001151 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
  3374                              <1> K37A:
  3375 00001154 B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  3376 00001156 E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  3377                              <1> K37B:
  3378 0000115B B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  3379 0000115D E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  3380                              <1> K37C:
  3381 00001162 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  3382 00001164 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  3383 00001166 EBEC                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  3384                              <1> 	;
  3385                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  3386                              <1> K38:					; NOT-ALT-SHIFT
  3387                              <1> 					; BL STILL HAS SHIFT FLAGS
  3388 00001168 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  3389                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
  3390 0000116B 0F84B0000000        <1>         jz      K44                     ; NOT-CTL-SHIFT
  3391                              <1> 	;
  3392                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  3393                              <1> 	;-----	TEST FOR BREAK
  3394                              <1> K38A:
  3395 00001171 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  3396 00001173 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
  3397 00001175 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3398 00001178 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  3399 0000117A F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3400 0000117D 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  3401                              <1> K38B:
  3402 0000117F 8B1D[30690000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  3403 00001185 891D[34690000]      <1> 	mov	[BUFFER_TAIL], ebx
  3404 0000118B C605[22690000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  3405                              <1> 	;
  3406                              <1> 	;-----	ENABLE KEYBOARD
  3407 00001192 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3408 00001194 E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3409                              <1> 	;
  3410                              <1> 	; CTRL+BREAK code here !!!
  3411                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  3412                              <1> 	; 17/10/2015	
  3413 00001199 E8A5230000          <1> 	call	ctrlbrk ; control+break subroutine
  3414                              <1> 	;
  3415 0000119E 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
  3416 000011A1 E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  3417                              <1> 	;
  3418                              <1> 	;-----	TEST FOR PAUSE
  3419                              <1> K39:					; NO_BREAK
  3420 000011A6 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3421 000011A9 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  3422 000011AB 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  3423 000011AD 7533                <1> 	jne	short K41		; NO-PAUSE
  3424                              <1> K39P:
  3425 000011AF 800D[24690000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  3426                              <1> 	;
  3427                              <1> 	;-----	ENABLE KEYBOARD
  3428 000011B6 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3429 000011B8 E877010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3430                              <1> K39A:
  3431 000011BD B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  3432 000011BF E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  3433                              <1> 	;
  3434                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  3435 000011C1 803D[20690000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  3436 000011C8 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  3437 000011CA 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  3438 000011CE A0[21690000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  3439 000011D3 EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  3440                              <1> 	;
  3441                              <1> K40:					; PAUSE-LOOP
  3442 000011D4 F605[24690000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  3443 000011DB 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  3444                              <1> 	;
  3445 000011DD E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  3446                              <1>         ;
  3447                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  3448                              <1> K41:					; NO-PAUSE
  3449 000011E2 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  3450 000011E4 7513                <1> 	jne	short K42		; NOT-KEY-55
  3451 000011E6 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3452 000011E9 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  3453 000011EB F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3454 000011EE 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  3455                              <1> K41A:	
  3456 000011F0 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  3457 000011F4 E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  3458                              <1> 	;
  3459                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  3460                              <1> K42:					; NOT-KEY-55
  3461 000011F9 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  3462 000011FB 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  3463 000011FD 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  3464 000011FF 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  3465 00001201 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  3466 00001204 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  3467 00001206 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  3468 0000120A E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  3469                              <1> K42A: 
  3470                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3471 0000120F 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  3472                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  3473                              <1> 	;;jb	K56 ; 20/02/2015
  3474                              <1> 	;;jmp	K64 ; 20/02/2015
  3475                              <1> K42B:
  3476 00001211 BB[18680000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3477 00001216 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  3478 0000121C E9B9000000          <1> 	jmp	K64	
  3479                              <1>         ;
  3480                              <1> 	;-----	NOT IN CONTROL SHIFT
  3481                              <1> K44:					; NOT-CTL-SHIFT
  3482 00001221 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  3483 00001223 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  3484 00001225 F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  3485 00001228 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  3486 0000122A F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  3487 0000122D 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  3488 0000122F EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3489                              <1> K44A:
  3490 00001231 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  3491 00001234 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3492                              <1> 	;
  3493                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  3494                              <1> K44B:
  3495 00001236 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3496 00001238 E8F7000000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3497 0000123D B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  3498 0000123F E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  3499                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  3500                              <1> 	;PUSH 	BP			; SAVE POINTER
  3501                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  3502                              <1> 	;POP	BP			; RESTORE POINTER
  3503 00001241 8025[26690000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  3504 00001248 E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  3505                              <1> 	;
  3506                              <1> 	;-----	HANDLE IN-CORE KEYS
  3507                              <1> K45:					; NOT-PRINT-SCREEN
  3508 0000124D 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  3509 0000124F 7734                <1> 	ja	short K46		; JUMP IF NOT
  3510 00001251 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  3511 00001253 7505                <1> 	jne	short K45A		; NO, JUMP
  3512 00001255 F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  3513 00001258 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  3514                              <1> K45A:
  3515 0000125A B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  3516 0000125F BF[EE670000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  3517 00001264 F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  3518                              <1> 		; 20/02/2015
  3519 00001266 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  3520                              <1> 	;
  3521 00001268 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  3522 0000126B 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  3523                              <1> K45B:
  3524 0000126D F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3525 00001270 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  3526                              <1> 					; NO, LOWERCASE
  3527                              <1> K45C:
  3528 00001272 BB[70680000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  3529 00001277 EB51                <1> 	jmp	short K56	
  3530                              <1> K45D:					; ALMOST-CAPS-STATE
  3531 00001279 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  3532 0000127C 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  3533                              <1> K45E:
  3534 0000127E BB[C8680000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  3535 00001283 EB45                <1> K45F:	jmp	short K56
  3536                              <1> 	;
  3537                              <1> 	;-----	TEST FOR KEYS F1 - F10
  3538                              <1> K46:					; NOT IN-CORE AREA
  3539 00001285 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  3540                              <1> 	;ja	short K47		; JUMP IF NOT
  3541                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  3542 00001287 7635                <1> 	jna	short K53		
  3543                              <1> 	;
  3544                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  3545                              <1> K47:					; NOT F1 - F10
  3546 00001289 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  3547 0000128B 772D                <1> 	ja	short K52		; JUMP IF NOT
  3548                              <1> 	;
  3549                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  3550                              <1> K48:
  3551 0000128D 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  3552 0000128F 74ED                <1> 	je	short K45E		; GO TRANSLATE
  3553 00001291 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  3554 00001293 74E9                <1> 	je	short K45E		; GO TRANSLATE
  3555 00001295 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  3556 00001298 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  3557                              <1> 	;		
  3558 0000129A F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  3559 0000129D 7514                <1> 	jnz	short K50		; TEST FOR SURE
  3560 0000129F F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3561                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  3562 000012A2 75DA                <1> 	jnz	short K45E
  3563                              <1> 	;
  3564                              <1> 	;-----	BASE CASE FOR KEYPAD
  3565                              <1> K49:					
  3566 000012A4 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  3567 000012A6 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  3568 000012A8 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  3569 000012AA EB40                <1> 	jmp	short K57		; BUFFER FILL
  3570                              <1> K49A:
  3571 000012AC BB[70680000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  3572 000012B1 EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  3573                              <1> 	;
  3574                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  3575                              <1> K50:					; ALMOST-NUM-STATE
  3576 000012B3 F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  3577 000012B6 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  3578 000012B8 EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  3579                              <1> 	;
  3580                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  3581                              <1> K52:					; NOT A NUMPAD KEY
  3582 000012BA 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  3583                              <1> 	;jne	short K53		; JUMP IF NOT
  3584                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  3585 000012BC 74AF                <1> 	je	short K45B		
  3586                              <1> 	;
  3587                              <1> 	;-----	MUST BE F11 OR F12 
  3588                              <1> K53:					; F1 - F10 COME HERE, TOO
  3589 000012BE F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  3590 000012C1 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  3591                              <1> 		; 20/02/2015 
  3592 000012C3 BB[C8680000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  3593 000012C8 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  3594                              <1> 	;
  3595                              <1> 	;-----	TRANSLATE THE CHARACTER
  3596                              <1> K56:					; TRANSLATE-CHAR
  3597 000012CA FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3598 000012CC D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  3599 000012CD F605[26690000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3600 000012D4 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3601 000012D6 B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  3602 000012D8 EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  3603                              <1> 	;
  3604                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  3605                              <1> K64:					; TRANSLATE-SCAN-ORGD
  3606 000012DA FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3607 000012DC D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  3608 000012DD 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  3609 000012DF B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  3610 000012E1 F605[26690000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3611 000012E8 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3612 000012EA B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  3613                              <1> 	;
  3614                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  3615                              <1> K57:					; BUFFER_FILL
  3616 000012EC 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  3617                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  3618 000012EE 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  3619 000012F4 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  3620                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  3621 000012F7 0F8450FDFFFF        <1> 	je      K26			; INTERRUPT_RETURN
  3622                              <1> ;K59:					; NEAR_INTERRUPT_RETURN
  3623                              <1> ;	jmp	K26			; INTERRUPT_RETURN
  3624                              <1> K61:					; NOT-CAPS-STATE
  3625 000012FD 8B1D[34690000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  3626 00001303 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  3627 00001305 E87BFAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  3628 0000130A 3B1D[30690000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  3629 00001310 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  3630 00001312 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  3631 00001315 891D[34690000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  3632 0000131B E92DFDFFFF          <1> 	jmp	K26
  3633                              <1> 	;;cli				; TURN OFF INTERRUPTS
  3634                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  3635                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  3636                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3637                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3638                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  3639                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  3640                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3641                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  3642                              <1> 	;;jmp   K27                    
  3643                              <1> 	;
  3644                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  3645                              <1> K62:
  3646 00001320 B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  3647 00001322 E620                <1> 	out	INTA00, al
  3648 00001324 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  3649 00001328 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  3650 0000132A E8A1010000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  3651 0000132F E925FDFFFF          <1> 	jmp     K27			; EXIT   
  3652                              <1> 
  3653                              <1> SHIP_IT:
  3654                              <1> 	;---------------------------------------------------------------------------------
  3655                              <1> 	; SHIP_IT
  3656                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3657                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  3658                              <1> 	;---------------------------------------------------------------------------------
  3659                              <1> 	;
  3660 00001334 6650                <1> 	push	ax			; SAVE DATA TO SEND
  3661                              <1> 
  3662                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  3663 00001336 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  3664                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  3665 00001337 B900000100          <1> 	mov	ecx, 10000h			
  3666                              <1> S10:
  3667 0000133C E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  3668 0000133E A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  3669 00001340 E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  3670                              <1> 
  3671 00001342 6658                <1> 	pop	ax			; GET DATA TO SEND
  3672 00001344 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  3673 00001346 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3674 00001347 C3                  <1> 	retn				; RETURN TO CALLER
  3675                              <1> 
  3676                              <1> SND_DATA:
  3677                              <1> 	; ---------------------------------------------------------------------------------
  3678                              <1> 	; SND_DATA
  3679                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3680                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  3681                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  3682                              <1> 	; ---------------------------------------------------------------------------------
  3683                              <1> 	;
  3684 00001348 6650                <1> 	push	ax			; SAVE REGISTERS
  3685 0000134A 6653                <1> 	push	bx
  3686 0000134C 51                  <1> 	push	ecx
  3687 0000134D 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  3688 0000134F B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  3689                              <1> SD0:
  3690 00001351 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3691 00001352 8025[25690000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  3692                              <1> 	;
  3693                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  3694 00001359 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  3695                              <1> SD5:
  3696 0000135E E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  3697 00001360 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  3698 00001362 E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  3699                              <1> 	;
  3700 00001364 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  3701 00001366 E660                <1> 	out	PORT_A, al		; SEND BYTE
  3702 00001368 FB                  <1> 	sti				; ENABLE INTERRUPTS
  3703                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  3704 00001369 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  3705                              <1> SD1:
  3706 0000136E F605[25690000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  3707 00001375 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  3708 00001377 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  3709                              <1> SD2:
  3710 00001379 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  3711 0000137B 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  3712 0000137D 800D[25690000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  3713 00001384 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  3714                              <1> SD3:
  3715 00001386 F605[25690000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  3716 0000138D 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  3717                              <1> SD4:	
  3718 0000138F 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  3719 00001390 665B                <1> 	pop	bx
  3720 00001392 6658                <1> 	pop	ax
  3721 00001394 C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  3722                              <1> 
  3723                              <1> SND_LED:
  3724                              <1> 	; ---------------------------------------------------------------------------------
  3725                              <1> 	; SND_LED
  3726                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  3727                              <1> 	;
  3728                              <1> 	;----------------------------------------------------------------------------------
  3729                              <1> 	;
  3730 00001395 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3731 00001396 F605[25690000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3732 0000139D 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3733                              <1> 	;
  3734 0000139F 800D[25690000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3735 000013A6 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3736 000013A8 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3737 000013AA EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  3738                              <1> SND_LED1:
  3739 000013AC FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3740 000013AD F605[25690000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3741 000013B4 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3742                              <1> 	;
  3743 000013B6 800D[25690000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3744                              <1> SL0:
  3745 000013BD B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  3746 000013BF E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3747 000013C4 FA                  <1> 	cli
  3748 000013C5 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  3749 000013CA 8025[25690000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  3750 000013D1 0805[25690000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  3751 000013D7 F605[25690000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3752 000013DE 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  3753                              <1> 	;
  3754 000013E0 E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3755 000013E5 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3756 000013E6 F605[25690000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3757 000013ED 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  3758                              <1> SL2:
  3759 000013EF B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  3760 000013F1 E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3761 000013F6 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3762                              <1> SL3:
  3763 000013F7 8025[25690000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  3764                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  3765 000013FE FB                  <1> 	sti				; ENABLE INTERRUPTS
  3766 000013FF C3                  <1> 	retn				; RETURN TO CALLER
  3767                              <1> 
  3768                              <1> MAKE_LED:
  3769                              <1> 	;---------------------------------------------------------------------------------
  3770                              <1> 	; MAKE_LED
  3771                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  3772                              <1> 	;	THE MODE INDICATORS.
  3773                              <1> 	;---------------------------------------------------------------------------------
  3774                              <1> 	;
  3775                              <1> 	;push 	cx			; SAVE CX
  3776 00001400 A0[23690000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  3777 00001405 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  3778                              <1> 	;mov	cl, 4			; SHIFT COUNT
  3779                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  3780 00001407 C0C004              <1> 	rol	al, 4 ; 20/02/2015
  3781 0000140A 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  3782                              <1> 	;pop	cx
  3783 0000140C C3                  <1> 	retn				; RETURN TO CALLER
  3784                              <1> 
  3785                              <1> ; % include 'kybdata.inc'   ; KEYBOARD DATA ; 11/03/2015
  3786                              <1> 
  3787                              <1> 
  3788                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  3789                                  
  3790                                  %include 'video.s' ; 07/03/2015
  3791                              <1> ; Retro UNIX 386 v1 Kernel - VIDEO.INC
  3792                              <1> ; Last Modification: 16/01/2016
  3793                              <1> ;		  (Video Data is in 'VIDATA.INC')
  3794                              <1> ;
  3795                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
  3796                              <1> 
  3797                              <1> ; 30/06/2015
  3798                              <1> ; 27/06/2015
  3799                              <1> ; 11/03/2015
  3800                              <1> ; 02/09/2014
  3801                              <1> ; 30/08/2014
  3802                              <1> ; VIDEO FUNCTIONS
  3803                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  3804                              <1> 
  3805                              <1> write_tty:
  3806                              <1> 	; 13/08/2015
  3807                              <1> 	; 02/09/2014
  3808                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  3809                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  3810                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  3811                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  3812                              <1> 	;
  3813                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  3814                              <1> 	;	   AL = Character to be written
  3815                              <1> 	;	   EBX = Video Page (0 to 7)
  3816                              <1> 	;	   (BH = 0 --> Video Mode 3)
  3817                              <1> 
  3818                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  3819                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  3820                              <1> 
  3821                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  3822                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  3823                              <1> ;
  3824                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  3825                              <1> ;
  3826                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  3827                              <1> ;										:
  3828                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  3829                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  3830                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  3831                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  3832                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  3833                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  3834                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  3835                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  3836                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  3837                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  3838                              <1> ;   THE 0 COLOR IS USED.							:
  3839                              <1> ;   ENTRY --									:
  3840                              <1> ;     (AH) = CURRENT CRT MODE							:
  3841                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  3842                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  3843                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  3844                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  3845                              <1> ;   EXIT -- 									:
  3846                              <1> ;     ALL REGISTERS SAVED							:
  3847                              <1> ;--------------------------------------------------------------------------------
  3848                              <1> 
  3849 0000140D FA                  <1> 	cli
  3850                              <1> 	;
  3851                              <1> 	; READ CURSOR (04/12/2013)
  3852                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  3853 0000140E 08FF                <1> 	or	bh, bh
  3854 00001410 0F85AB000000        <1> 	jnz	beeper
  3855                              <1> 	; 01/09/2014
  3856 00001416 803D[20690000]03    <1> 	cmp	byte [CRT_MODE], 3
  3857 0000141D 7405                <1> 	je	short m3
  3858                              <1> 	;
  3859 0000141F E887020000          <1> 	call	set_mode
  3860                              <1> m3:
  3861 00001424 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  3862 00001426 66D1E6              <1> 	shl	si, 1
  3863 00001429 81C6[166F0000]      <1> 	add	esi, cursor_posn
  3864 0000142F 668B16              <1> 	mov	dx, [esi]
  3865                              <1> 	;
  3866                              <1> 	; dx now has the current cursor position
  3867                              <1> 	;
  3868 00001432 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  3869 00001434 764D                <1> 	jbe	short u8
  3870                              <1> 	;
  3871                              <1> 	; write the char to the screen
  3872                              <1> u0:	
  3873                              <1> 	; ah = attribute/color
  3874                              <1> 	; al = character
  3875                              <1> 	; bl = video page number (0 to 7)
  3876                              <1> 	; bh = 0
  3877                              <1> 	;
  3878 00001436 E83F020000          <1> 	call	write_c_current
  3879                              <1> 	;
  3880                              <1> 	; position the cursor for next char
  3881 0000143B FEC2                <1> 	inc	dl		; next column
  3882                              <1> 	;cmp	dl, [CRT_COLS]
  3883 0000143D 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  3884 00001440 0F85EB000000        <1>         jne     set_cpos
  3885 00001446 B200                <1> 	mov	dl, 0		; column = 0
  3886                              <1> u10:				; (line feed found)
  3887 00001448 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  3888 0000144B 722F                <1> 	jb 	short u6
  3889                              <1> 	;
  3890                              <1> 	; scroll required
  3891                              <1> u1:	
  3892                              <1> 	; SET CURSOR POSITION (04/12/2013)
  3893 0000144D E8DF000000          <1> 	call	set_cpos
  3894                              <1> 	;
  3895                              <1> 	; determine value to fill with during scroll
  3896                              <1> u2:
  3897                              <1> 	; READ_AC_CURRENT		:
  3898                              <1> 	;   THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER
  3899                              <1> 	;    AT THE CURRENT CURSOR POSITION
  3900                              <1> 	;
  3901                              <1> 	; INPUT				
  3902                              <1> 	;	(AH) = CURRENT CRT MODE
  3903                              <1> 	;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )
  3904                              <1> 	;	(DS) = DATA SEGMENT
  3905                              <1> 	;	(ES) = REGEN SEGMENT
  3906                              <1> 	; OUTPUT			
  3907                              <1> 	;	(AL) = CHARACTER READ
  3908                              <1> 	;	(AH) = ATTRIBUTE READ
  3909                              <1> 	;
  3910                              <1> 	; mov	ah, [CRT_MODE] ; move current mode into ah
  3911                              <1> 	;
  3912                              <1> 	; bl = video page number
  3913                              <1> 	;
  3914 00001452 E837010000          <1> 	call	find_position	; get regen location and port address
  3915                              <1> 	; dx = status port
  3916                              <1> 	; esi = cursor location/address
  3917                              <1> p11:
  3918 00001457 FB                  <1> 	sti			; enable interrupts
  3919 00001458 90                  <1> 	nop			; allow for small interupts window
  3920 00001459 FA                  <1> 	cli			; blocks interrupts for single loop
  3921 0000145A EC                  <1> 	in	al, dx		; get status from adapter
  3922 0000145B A801                <1> 	test	al, RHRZ	; is horizontal retrace low
  3923 0000145D 75F8                <1> 	jnz	short p11	; wait until it is
  3924                              <1> p12:				; now wait for either retrace high
  3925 0000145F EC                  <1> 	in	al, dx		; get status
  3926 00001460 A809                <1> 	test	al, RVRT+RHRZ	; is horizontal or vertical retrace high
  3927 00001462 74FB                <1> 	jz	short p12	; wait until either is active	
  3928                              <1> p13:
  3929 00001464 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
  3930 0000146A 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
  3931                              <1> 	;
  3932                              <1> 	; al = character, ah = attribute
  3933                              <1> 	;
  3934 0000146D FB                  <1> 	sti
  3935                              <1> 	; bl = video page number 	
  3936                              <1> u3:
  3937                              <1> 	;;mov	ax, 0601h 	; scroll one line
  3938                              <1> 	;;sub	cx, cx		; upper left corner
  3939                              <1> 	;;mov	dh, 25-1 	; lower right row
  3940                              <1> 	;;;mov	dl, [CRT_COLS]
  3941                              <1> 	;mov	dl, 80		; lower right column	
  3942                              <1> 	;;dec	dl
  3943                              <1> 	;;mov	dl, 79
  3944                              <1> 
  3945                              <1> 	;;call	scroll_up	; 04/12/2013
  3946                              <1> 	;;; 11/03/2015
  3947                              <1> 	; 02/09/2014
  3948                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  3949                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  3950                              <1> 	; 11/03/2015
  3951 0000146E 6629C9              <1> 	sub	cx, cx
  3952 00001471 66BA4F18            <1> 	mov	dx, 184Fh ; dl= 79 (column), dh = 24 (row)
  3953                              <1> 	;
  3954 00001475 B001                <1> 	mov	al, 1		; scroll 1 line up
  3955                              <1> 		; ah = attribute
  3956 00001477 E93E010000          <1> 	jmp	scroll_up
  3957                              <1> ;u4:
  3958                              <1> 	;;int	10h		; video-call return
  3959                              <1> 				; scroll up the screen
  3960                              <1> 				; tty return
  3961                              <1> ;u5:
  3962                              <1> 	;retn			; return to the caller
  3963                              <1> 
  3964                              <1> u6:				; set-cursor-inc
  3965 0000147C FEC6                <1> 	inc	dh		; next row
  3966                              <1> 				; set cursor
  3967                              <1> ;u7:					
  3968                              <1> 	;;mov	ah, 02h
  3969                              <1> 	;;jmp	short u4 	; establish the new cursor
  3970                              <1> 	;call	set_cpos
  3971                              <1> 	;jmp 	short u5
  3972 0000147E E9AE000000          <1> 	jmp     set_cpos
  3973                              <1> 
  3974                              <1> 	; check for control characters
  3975                              <1> u8:
  3976 00001483 7438                <1> 	je	short u9
  3977 00001485 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  3978 00001487 74BF                <1> 	je	short u10
  3979 00001489 3C07                <1> 	cmp	al, 07h 	; is it a bell
  3980 0000148B 7434                <1> 	je	short u11
  3981 0000148D 3C08                <1> 	cmp	al, 08h		; is it a backspace
  3982                              <1> 	;jne	short u0
  3983 0000148F 7424                <1> 	je	short bs	; 12/12/2013
  3984                              <1> 	; 12/12/2013 (tab stop)
  3985 00001491 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  3986 00001493 75A1                <1> 	jne	short u0
  3987 00001495 88D0                <1> 	mov	al, dl
  3988 00001497 6698                <1> 	cbw
  3989 00001499 B108                <1> 	mov	cl, 8
  3990 0000149B F6F1                <1> 	div	cl
  3991 0000149D 28E1                <1> 	sub	cl, ah
  3992                              <1> ts:
  3993                              <1> 	; 02/09/2014
  3994                              <1> 	; 01/09/2014
  3995 0000149F B020                <1> 	mov	al, 20h
  3996                              <1> tsloop:
  3997 000014A1 6651                <1> 	push	cx
  3998 000014A3 6650                <1> 	push	ax
  3999 000014A5 30FF                <1> 	xor 	bh, bh
  4000                              <1> 	;mov	bl, [active_page]
  4001 000014A7 E878FFFFFF          <1> 	call	m3
  4002 000014AC 6658                <1> 	pop	ax  ; ah = attribute/color
  4003 000014AE 6659                <1> 	pop	cx
  4004 000014B0 FEC9                <1> 	dec	cl
  4005 000014B2 75ED                <1> 	jnz	short tsloop
  4006 000014B4 C3                  <1> 	retn
  4007                              <1> bs:	
  4008                              <1> 	; back space found
  4009                              <1> 
  4010 000014B5 08D2                <1> 	or	dl, dl 		; is it already at start of line
  4011                              <1> 	;je	short u7 	; set_cursor
  4012 000014B7 7478                <1> 	jz	short set_cpos
  4013 000014B9 664A                <1> 	dec	dx     		; no -- just move it back
  4014                              <1> 	;jmp	short u7
  4015 000014BB EB74                <1> 	jmp	short set_cpos
  4016                              <1> 
  4017                              <1> 	; carriage return found
  4018                              <1> u9:
  4019 000014BD B200                <1> 	mov	dl, 0 		; move to first column
  4020                              <1> 	;jmp	short u7
  4021 000014BF EB70                <1> 	jmp	short set_cpos
  4022                              <1> 
  4023                              <1> 	; line feed found
  4024                              <1> ;u10:
  4025                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  4026                              <1> ;	jne	short u6 	; no, just set the cursor
  4027                              <1> ;       jmp     u1              ; yes, scroll the screen
  4028                              <1> 
  4029                              <1> beeper: 
  4030                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4031                              <1> 	; 18/01/2014
  4032                              <1> 	; 03/12/2013
  4033                              <1> 	; bell found
  4034                              <1> u11:
  4035 000014C1 FB                  <1> 	sti
  4036 000014C2 3A1D[266F0000]      <1> 	cmp	bl, [active_page]
  4037 000014C8 7551                <1> 	jne	short u12	; Do not sound the beep 
  4038                              <1> 				; if it is not written on the active page
  4039 000014CA 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  4040 000014CE B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  4041                              <1> 	;call	beep		; sound the pod bell
  4042                              <1> 	;jmp	short u5 	; tty_return
  4043                              <1> 	;retn
  4044                              <1> 	
  4045                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  4046                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  4047                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  4048                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  4049                              <1> 
  4050                              <1> beep:
  4051                              <1> 	; 07/02/2015
  4052                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4053                              <1> 	; 18/01/2014
  4054                              <1> 	; 03/12/2013
  4055                              <1> 	;
  4056                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  4057                              <1> 	;
  4058                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  4059                              <1> 	;
  4060                              <1> 	; ENTRY:
  4061                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  4062                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  4063                              <1> 	; EXIT:				:
  4064                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  4065                              <1> 
  4066 000014D0 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  4067 000014D1 FA                  <1> 	cli			; block interrupts during update
  4068 000014D2 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  4069 000014D4 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  4070 000014D6 EB00                <1> 	jmp	$+2		; I/O delay
  4071 000014D8 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  4072 000014DA E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  4073 000014DC EB00                <1> 	jmp	$+2		; I/O delay
  4074 000014DE 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  4075 000014E0 E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  4076 000014E2 E461                <1> 	in	al, PORT_B	; get current setting of port
  4077 000014E4 88C4                <1> 	mov	ah, al		; save that setting
  4078 000014E6 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  4079 000014E8 E661                <1> 	out	PORT_B, al	; and restore interrupt status
  4080                              <1> 	;popf	; 18/01/2014
  4081 000014EA FB                  <1> 	sti
  4082                              <1> g7:				; 1/64 second per count (bl)
  4083 000014EB B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  4084 000014F0 E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  4085 000014F5 FECB                <1> 	dec	bl		; (bl) length count expired?
  4086 000014F7 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  4087                              <1> 	;
  4088                              <1> 	;pushf			; save interrupt status
  4089 000014F9 FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  4090 000014FA E461                <1> 	in	al, PORT_B	; get current port value
  4091                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  4092 000014FC 0CFC                <1>         or      al, ~(GATE2+SPK2)
  4093 000014FE 20C4                <1>         and	ah, al		; someone turned them off during beep
  4094 00001500 88E0                <1> 	mov	al, ah		; recover value of port
  4095                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  4096 00001502 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  4097 00001504 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  4098                              <1> 	;popf			; restore interrupt flag state
  4099 00001506 FB                  <1> 	sti
  4100 00001507 B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  4101 0000150C E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  4102                              <1> 	;pushf			; save interrupt status
  4103 00001511 FA                  <1> 	cli			; block interrupts during update
  4104 00001512 E461                <1> 	in	al, PORT_B	; get current port value in case	
  4105 00001514 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  4106 00001516 08E0                <1> 	or	al, ah		; recover value of port_b
  4107 00001518 E661                <1> 	out	PORT_B, al	; restore speaker status
  4108 0000151A 9D                  <1> 	popf			; restore interrupt flag state
  4109                              <1> u12:	
  4110 0000151B C3                  <1> 	retn
  4111                              <1> 
  4112                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  4113                              <1> 
  4114                              <1> WAITF:
  4115                              <1> waitf:
  4116                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4117                              <1> 	; 03/12/2013
  4118                              <1> 	;
  4119                              <1> ;	push ax			; save work register (ah)	
  4120                              <1> ;waitf1:
  4121                              <1> 				; use timer 1 output bits
  4122                              <1> ;	in	al, PORT_B	; read current counter output status
  4123                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  4124                              <1> ;	cmp	al, ah		; did it just change
  4125                              <1> ;	je	short waitf1	; wait for a change in output line
  4126                              <1> ;	;
  4127                              <1> ;	mov	ah, al		; save new lflag state
  4128                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  4129                              <1> ;	;
  4130                              <1> ;	pop	ax		; restore (ah)
  4131                              <1> ;	retn			; return (cx)=0
  4132                              <1> 
  4133                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  4134                              <1> ; 17/12/2014 (dsectrm2.s)
  4135                              <1> ; WAITF
  4136                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  4137                              <1> ;
  4138                              <1> ;---WAITF-----------------------------------------------------------------------
  4139                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  4140                              <1> ; ENTRY:
  4141                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  4142                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  4143                              <1> ; EXIT:
  4144                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  4145                              <1> ;	(CX) = 0	
  4146                              <1> ;-------------------------------------------------------------------------------
  4147                              <1> 
  4148                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  4149                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  4150                              <1> 
  4151                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  4152 0000151C 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  4153                              <1> 	; 16/12/2014
  4154                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  4155 0000151E D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  4156                              <1> ;17/12/2014	
  4157                              <1> ;WAITF1:
  4158                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  4159                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  4160                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  4161                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  4162                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  4163                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  4164                              <1> 	;
  4165                              <1> 	; 17/12/2014
  4166                              <1> 	;
  4167                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  4168                              <1> 	;
  4169                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  4170                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  4171                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  4172                              <1> WR_STATE_0:
  4173 00001520 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4174 00001522 A810                <1> 	TEST	AL,010H
  4175 00001524 74FA                <1> 	JZ	SHORT WR_STATE_0
  4176                              <1> WR_STATE_1:
  4177 00001526 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4178 00001528 A810                <1> 	TEST	AL,010H
  4179 0000152A 75FA                <1> 	JNZ	SHORT WR_STATE_1
  4180 0000152C E2F2                <1>         LOOP    WR_STATE_0
  4181                              <1> 	;
  4182 0000152E 6658                <1> 	POP	AX			; RESTORE (AH)
  4183 00001530 C3                  <1> 	RETn				; (CX) = 0
  4184                              <1> 
  4185                              <1> set_cpos:
  4186                              <1> 	; 27/06/2015
  4187                              <1> 	; 01/09/2014
  4188                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  4189                              <1> 	;
  4190                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  4191                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  4192                              <1> 	;
  4193                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4194                              <1> 	;
  4195                              <1> 	; SET_CPOS
  4196                              <1> 	;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  4197                              <1> 	;	NEW X-Y VALUES PASSED
  4198                              <1> 	; INPUT
  4199                              <1> 	;	DX - ROW,COLUMN OF NEW CURSOR
  4200                              <1> 	;	BH - DISPLAY PAGE OF CURSOR
  4201                              <1> 	; OUTPUT
  4202                              <1> 	;	CURSOR IS SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  4203                              <1> 	;
  4204 00001531 0FB6C3              <1>         movzx   eax, bl  ; BL = video page number ; 27/06/2015 (movzx)
  4205 00001534 D0E0                <1>         shl     al, 1   ; word offset
  4206 00001536 BE[166F0000]        <1> 	mov	esi, cursor_posn
  4207 0000153B 01C6                <1>         add     esi, eax
  4208 0000153D 668916              <1> 	mov	[esi], dx ; save the pointer
  4209 00001540 381D[266F0000]      <1> 	cmp	[active_page], bl
  4210 00001546 7532                <1> 	jne	short m17
  4211                              <1> 	;call	m18	; CURSOR SET
  4212                              <1> ;m17:			; SET_CPOS_RETURN
  4213                              <1> 	; 01/09/2014
  4214                              <1> ;	retn
  4215                              <1> 		; DX  = row/column
  4216                              <1> m18:
  4217 00001548 E832000000          <1> 	call	position ; determine location in regen buffer	
  4218 0000154D 668B0D[146F0000]    <1> 	mov	cx, [CRT_START]
  4219 00001554 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  4220                              <1> 			; to the start address (offset) for this page
  4221 00001557 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  4222 0000155A B40E                <1> 	mov	ah, 14	; register number for cursor
  4223                              <1> 	;call	m16	; output value to the 6845	
  4224                              <1> 	;retn
  4225                              <1> 
  4226                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  4227                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  4228                              <1> m16:
  4229 0000155C FA                  <1> 	cli
  4230                              <1> 	;mov	dx, [addr_6845] ; address register
  4231 0000155D 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  4232 00001561 88E0                <1> 	mov	al, ah	; get value
  4233 00001563 EE                  <1> 	out	dx, al	; register set
  4234 00001564 6642                <1> 	inc	dx	; data register
  4235 00001566 EB00                <1> 	jmp	$+2	; i/o delay
  4236 00001568 88E8                <1> 	mov	al, ch	; data
  4237 0000156A EE                  <1> 	out	dx, al	
  4238 0000156B 664A                <1> 	dec	dx	
  4239 0000156D 88E0                <1> 	mov	al, ah
  4240 0000156F FEC0                <1> 	inc	al	; point to other data register
  4241 00001571 EE                  <1> 	out	dx, al	; set for second register
  4242 00001572 6642                <1> 	inc	dx
  4243 00001574 EB00                <1> 	jmp	$+2	; i/o delay
  4244 00001576 88C8                <1> 	mov	al, cl	; second data value
  4245 00001578 EE                  <1> 	out	dx, al
  4246 00001579 FB                  <1> 	sti
  4247                              <1> m17:
  4248 0000157A C3                  <1> 	retn
  4249                              <1> 
  4250                              <1> 
  4251                              <1> set_ctype:
  4252                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4253                              <1> 	;
  4254                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4255                              <1> 
  4256                              <1> ;	CH) = BITS 4-0 = START LINE FOR CURSOR
  4257                              <1> ;       ** HARDWARE WILL ALWAYS CAUSE BLINK
  4258                              <1> ;       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
  4259                              <1> ;          OR NO CURSOR AT ALL
  4260                              <1> ;	(CL) = BITS 4-0 = END LINE FOR CURSOR
  4261                              <1> 
  4262                              <1> ;------------------------------------------------
  4263                              <1> ; SET_CTYPE
  4264                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
  4265                              <1> ; INPUT
  4266                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
  4267                              <1> ; OUTPUT	
  4268                              <1> ;	NONE
  4269                              <1> ;------------------------------------------------
  4270                              <1> 
  4271 0000157B B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  4272                              <1> 	;mov	[CURSOR_MODE], cx ; save in data area
  4273                              <1> 	;call	m16	; output cx register
  4274                              <1> 	;retn
  4275 0000157D EBDD                <1> 	jmp	m16
  4276                              <1> 
  4277                              <1> 
  4278                              <1> position:
  4279                              <1> 	; 27/06/2015
  4280                              <1> 	; 02/09/2014
  4281                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4282                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
  4283                              <1> 	;
  4284                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4285                              <1> 	;
  4286                              <1> 	; POSITION
  4287                              <1> 	;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
  4288                              <1> 	;	OF A CHARACTER IN THE ALPHA MODE
  4289                              <1> 	; INPUT
  4290                              <1> 	;	AX = ROW, COLUMN POSITION
  4291                              <1> 	; OUTPUT
  4292                              <1> 	;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
  4293                              <1> 
  4294                              <1> 		; DX = ROW, COLUMN POSITION
  4295                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
  4296 0000157F 31C0                <1> 	xor	eax, eax ; 02/09/2014
  4297 00001581 B050                <1> 	mov	al, 80   ; determine bytes to row	
  4298 00001583 F6E6                <1> 	mul	dh ;	 row value
  4299 00001585 30F6                <1> 	xor	dh, dh   ; 0	
  4300 00001587 6601D0              <1> 	add	ax, dx	 ; add column value to the result
  4301 0000158A 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
  4302                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
  4303 0000158D C3                  <1> 	retn
  4304                              <1> 
  4305                              <1> find_position:
  4306                              <1> 	; 27/06/2015
  4307                              <1> 	; 07/09/2014
  4308                              <1> 	; 02/09/2014
  4309                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4310                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4311 0000158E 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
  4312 00001591 89CE                <1> 	mov	esi, ecx
  4313 00001593 66D1E6              <1> 	shl	si, 1
  4314 00001596 668B96[166F0000]    <1> 	mov	dx, [esi + cursor_posn]
  4315 0000159D 740A                <1> 	jz	short p21
  4316 0000159F 6631F6              <1> 	xor	si, si
  4317                              <1> p20:
  4318                              <1> 	;add	si, [CRT_LEN]
  4319 000015A2 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
  4320 000015A7 E2F9                <1> 	loop	p20
  4321                              <1> p21:
  4322 000015A9 6621D2              <1> 	and	dx, dx
  4323 000015AC 7407                <1> 	jz	short p22
  4324 000015AE E8CCFFFFFF          <1> 	call 	position ; determine location in regen in page
  4325 000015B3 01C6                <1> 	add	esi, eax ; add location to start of regen page
  4326                              <1> p22:	
  4327                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
  4328                              <1> 	;mov	dx, 03D4h ; I/O address of color card
  4329                              <1> 	;add	dx, 6	; point at status port
  4330 000015B5 66BADA03            <1> 	mov	dx, 03DAh ; status port
  4331                              <1> 	; cx = 0
  4332 000015B9 C3                  <1> 	retn
  4333                              <1> 
  4334                              <1> scroll_up:
  4335                              <1> 	; 16/01/2016
  4336                              <1> 	; 07/09/2014
  4337                              <1> 	; 02/09/2014
  4338                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
  4339                              <1> 	; 04/04/2014
  4340                              <1> 	; 04/12/2013
  4341                              <1> 	;
  4342                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4343                              <1> 	;
  4344                              <1> 	; SCROLL UP
  4345                              <1> 	;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
  4346                              <1> 	;	ON THE SCREEN
  4347                              <1> 	; INPUT
  4348                              <1> 	;	(AH) = CURRENT CRT MODE
  4349                              <1> 	;	(AL) = NUMBER OF ROWS TO SCROLL
  4350                              <1> 	;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
  4351                              <1> 	;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
  4352                              <1> 	;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
  4353                              <1> 	;	(DS) = DATA SEGMENT
  4354                              <1> 	;	(ES) = REGEN BUFFER SEGMENT
  4355                              <1> 	; OUTPUT
  4356                              <1> 	;	NONE -- THE REGEN BUFFER IS MODIFIED
  4357                              <1> 	;
  4358                              <1> 	;	bh = 0  (02/09/2014)
  4359                              <1> 	;
  4360                              <1> 	; ((ah = 3))
  4361                              <1> 	; cl = left upper column
  4362                              <1> 	; ch = left upper row
  4363                              <1> 	; dl = right lower column
  4364                              <1> 	; dh = right lower row
  4365                              <1> 	;
  4366                              <1> 	; al = line count 
  4367                              <1> 	; ah = attribute to be used on blanked line	
  4368                              <1> 	; bl = video page number (0 to 7)
  4369                              <1> 	; 
  4370                              <1> 
  4371                              <1> 	; Test	Line Count
  4372 000015BA 08C0                <1> 	or	al, al
  4373 000015BC 740C                <1> 	jz	short al_set
  4374 000015BE 88F7                <1> 	mov	bh, dh	; subtract lower row from upper row
  4375 000015C0 28EF                <1> 	sub	bh, ch
  4376 000015C2 FEC7                <1> 	inc	bh	; adjust difference by 1
  4377 000015C4 38C7                <1> 	cmp	bh, al 	; line count = amount of rows in window?
  4378 000015C6 7502                <1> 	jne	short al_set ; if not the we're all set
  4379 000015C8 30C0                <1> 	xor	al, al	; otherwise set al to zero
  4380                              <1> al_set:
  4381 000015CA 30FF                <1> 	xor	bh, bh	; 0
  4382 000015CC 6650                <1> 	push	ax
  4383                              <1> 	;mov 	esi, [crt_base]
  4384 000015CE BE00800B00          <1>         mov     esi, 0B8000h  
  4385 000015D3 3A1D[266F0000]      <1>         cmp     bl, [active_page]
  4386 000015D9 750B                <1> 	jne	short n0
  4387                              <1> 	;
  4388 000015DB 66A1[146F0000]      <1>         mov     ax, [CRT_START]
  4389 000015E1 6601C6              <1>         add     si, ax
  4390 000015E4 EB0F                <1>         jmp     short n1
  4391                              <1> n0:
  4392 000015E6 20DB                <1>         and     bl, bl
  4393 000015E8 740B                <1> 	jz	short n1
  4394 000015EA 88D8                <1> 	mov	al, bl
  4395                              <1> n0x:
  4396                              <1>         ;add    si, [CRT_LEN]
  4397                              <1>         ;add    esi, 80*25*2 
  4398 000015EC 6681C6A00F          <1>         add     si, 80*25*2
  4399 000015F1 FEC8                <1>         dec	al
  4400 000015F3 75F7                <1> 	jnz	short n0x
  4401                              <1> n1:	
  4402                              <1>         ;Scroll position
  4403 000015F5 6652                <1> 	push	dx
  4404 000015F7 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
  4405 000015FA E880FFFFFF          <1> 	call	position
  4406 000015FF 01C6                <1> 	add	esi, eax
  4407 00001601 89F7                <1> 	mov	edi, esi
  4408 00001603 665A                <1> 	pop	dx	; lower right position in DX
  4409 00001605 6629CA              <1> 	sub	dx, cx
  4410 00001608 FEC6                <1> 	inc	dh	; dh = #rows 
  4411 0000160A FEC2                <1> 	inc	dl	; dl = #cols in block
  4412 0000160C 6658                <1> 	pop	ax	; al = line count, ah = attribute
  4413 0000160E 31C9                <1> 	xor	ecx, ecx
  4414 00001610 6689C1              <1> 	mov	cx, ax
  4415                              <1> 	;mov	ah, [CRT_COLS]
  4416 00001613 B450                <1> 	mov	ah, 80
  4417 00001615 F6E4                <1> 	mul	ah	; determine offset to from address
  4418 00001617 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
  4419                              <1> 	;
  4420 0000161A 6650                <1> 	push	ax	; offset 
  4421 0000161C 6652                <1> 	push	dx
  4422                              <1> 	;
  4423                              <1> 	; 04/04/2014
  4424 0000161E 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
  4425                              <1> n8:                      ; wait_display_enable
  4426 00001622 EC                  <1>         in      al, dx   ; get port
  4427 00001623 A808                <1> 	test	al, RVRT ; wait for vertical retrace	
  4428 00001625 74FB                <1> 	jz	short n8 ; wait_display_enable
  4429 00001627 B025                <1> 	mov	al, 25h
  4430 00001629 B2D8                <1> 	mov	dl, 0D8h ; address control port
  4431 0000162B EE                  <1> 	out	dx, al	; turn off video during vertical retrace
  4432 0000162C 665A                <1> 	pop	dx	; #rows, #cols
  4433 0000162E 6658                <1>        	pop	ax	; offset
  4434 00001630 6691                <1> 	xchg	ax, cx	; 
  4435                              <1> 	; ecx = offset, al = line count, ah = attribute
  4436                              <1> ;n9:
  4437 00001632 08C0                <1> 	or	al, al
  4438 00001634 7420                <1>         jz      short n3 
  4439 00001636 01CE                <1>         add     esi, ecx ; from address for scroll
  4440 00001638 88F7                <1> 	mov	bh, dh  ; #rows in block
  4441 0000163A 28C7                <1> 	sub	bh, al	; #rows to be moved
  4442                              <1> n2:
  4443                              <1> 	; Move rows
  4444 0000163C 88D1                <1> 	mov	cl, dl	; get # of cols to move
  4445 0000163E 56                  <1> 	push	esi
  4446 0000163F 57                  <1> 	push	edi	; save start address
  4447                              <1> n10:
  4448 00001640 66A5                <1> 	movsw		; move that line on screen
  4449 00001642 FEC9                <1> 	dec	cl
  4450 00001644 75FA                <1>         jnz     short n10
  4451 00001646 5F                  <1> 	pop	edi
  4452 00001647 5E                  <1> 	pop	esi	; recover addresses
  4453                              <1>         ;mov    cl, [CRT_COLS] 
  4454                              <1> 	;add	cl, cl
  4455                              <1>         ;mov    ecx, 80*2
  4456 00001648 66B9A000            <1>         mov     cx, 80*2
  4457 0000164C 01CE                <1>         add     esi, ecx  ; next line
  4458 0000164E 01CF                <1>         add     edi, ecx
  4459 00001650 FECF                <1> 	dec	bh	 ; count of lines to move
  4460 00001652 75E8                <1> 	jnz	short n2 ; row loop
  4461                              <1> 	; bh = 0
  4462 00001654 88C6                <1> 	mov	dh, al	 ; #rows	
  4463                              <1> n3:
  4464                              <1> 	; attribute in ah
  4465 00001656 B020                <1> 	mov	al, ' '	 ; fill with blanks
  4466                              <1> n3x:
  4467                              <1> 	; Clear rows
  4468                              <1>                 ; dh =  #rows
  4469 00001658 88D1                <1>         mov	cl, dl	; get # of cols to clear
  4470 0000165A 57                  <1>         push    edi     ; save address
  4471                              <1> n11:
  4472 0000165B 66AB                <1>         stosw           ; store fill character
  4473 0000165D FEC9                <1> 	dec	cl
  4474 0000165F 75FA                <1>         jnz     short n11
  4475 00001661 5F                  <1>         pop     edi     ; recover address
  4476                              <1> 	;mov	cl, [CRT_COLS]
  4477                              <1> 	;add	cl, cl
  4478                              <1>         ;mov    ecx, 80*2
  4479 00001662 B1A0                <1>         mov	cl, 80*2
  4480 00001664 01CF                <1>         add     edi, ecx
  4481 00001666 FECE                <1> 	dec	dh
  4482 00001668 75EE                <1> 	jnz	short n3x ; 16/01/2016
  4483                              <1> 	;
  4484 0000166A 3A1D[266F0000]      <1> 	cmp	bl, [active_page]
  4485 00001670 7507                <1> 	jne	short n6
  4486                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
  4487 00001672 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
  4488 00001674 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
  4489 00001678 EE                  <1> 	out	dx, al
  4490                              <1> n6:
  4491 00001679 C3                  <1> 	retn
  4492                              <1> 
  4493                              <1> 
  4494                              <1> write_c_current:
  4495                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4496                              <1> 	; 18/01/2014
  4497                              <1> 	; 04/12/2013
  4498                              <1> 	;
  4499                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4500                              <1> 	;
  4501                              <1> 	; WRITE_C_CURRENT
  4502                              <1> 	;	THIS ROUTINE WRITES THE CHARACTER AT
  4503                              <1> 	;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED
  4504                              <1> 	; INPUT	
  4505                              <1> 	;	(AH) = CURRENT CRT MODE
  4506                              <1> 	;	(BH) = DISPLAY PAGE
  4507                              <1> 	;	(CX) = COUNT OF CHARACTERS TO WRITE
  4508                              <1> 	;	(AL) = CHAR TO WRITE
  4509                              <1> 	;	(DS) = DATA SEGMENT
  4510                              <1> 	;	(ES) = REGEN SEGMENT
  4511                              <1> 	; OUTPUT
  4512                              <1> 	;	DISPLAY REGEN BUFFER UPDATED
  4513                              <1> 
  4514 0000167A FA                  <1> 	cli		
  4515                              <1> 	; bl = video page
  4516                              <1> 	; al = character
  4517                              <1> 	; ah = color/attribute
  4518 0000167B 6652                <1> 	push	dx
  4519 0000167D 6650                <1> 	push	ax	; save character & attribute/color
  4520 0000167F E80AFFFFFF          <1> 	call 	find_position  ; get regen location and port address
  4521                              <1> 	; esi = regen location
  4522                              <1> 	; dx = status port
  4523                              <1> 	;
  4524                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  4525                              <1> 	;
  4526                              <1> p41:			; wait for horizontal retrace is low or vertical
  4527 00001684 FB                  <1> 	sti		; enable interrupts first
  4528 00001685 3A1D[266F0000]      <1>         cmp     bl, [active_page]
  4529 0000168B 7510                <1> 	jne	short p44 
  4530 0000168D FA                  <1> 	cli 		; block interrupts for single loop
  4531 0000168E EC                  <1> 	in	al, dx	; get status from the adapter
  4532 0000168F A808                <1> 	test	al, RVRT ; check for vertical retrace first
  4533 00001691 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  4534 00001693 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  4535 00001695 75ED                <1> 	jnz	short p41 ; wait until it is
  4536                              <1> p42:			;  wait for either retrace high
  4537 00001697 EC                  <1> 	in	al, dx ; get status again
  4538 00001698 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  4539 0000169A 74FB                <1> 	jz	short p42 ; wait until either retrace active
  4540                              <1> p43:	
  4541 0000169C FB                  <1> 	sti
  4542                              <1> p44:
  4543 0000169D 6658                <1> 	pop	ax	; restore the character (al) & attribute (ah)
  4544 0000169F 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  4545                              <1> 				; Retro UNIX 386 v1 feature only!
  4546 000016A5 668906              <1> 	mov	[esi], ax
  4547 000016A8 665A                <1> 	pop	dx
  4548 000016AA C3                  <1> 	retn
  4549                              <1> 
  4550                              <1> set_mode:
  4551                              <1> 	; 16/01/2016
  4552                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4553                              <1> 	;
  4554                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4555                              <1> 
  4556                              <1> ;------------------------------------------------------
  4557                              <1> ; SET MODE					      :
  4558                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
  4559                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
  4560                              <1> ; INPUT						      :
  4561                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
  4562                              <1> ; OUTPUT					      :
  4563                              <1> ;	NONE					      :
  4564                              <1> ;------------------------------------------------------
  4565                              <1> 
  4566 000016AB 57                  <1> 	push	edi ; 16/01/2016
  4567 000016AC 53                  <1> 	push	ebx
  4568 000016AD 52                  <1> 	push	edx
  4569 000016AE 51                  <1> 	push	ecx ; 16/01/2016
  4570 000016AF 50                  <1>         push    eax
  4571                              <1> 
  4572                              <1> 	;mov	dx, 03D4h 	; address or color card
  4573 000016B0 B003                <1> 	mov	al, 3
  4574                              <1> ;M8:
  4575 000016B2 A2[20690000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
  4576 000016B7 B029                <1> 	mov	al, 29h
  4577                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
  4578 000016B9 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
  4579                              <1> 	;push	dx  		; save port value
  4580                              <1> 	;add	dx, 4		; point to control register
  4581 000016BB 66BAD803            <1> 	mov	dx, 3D8h
  4582 000016BF EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
  4583                              <1> 	;pop	dx
  4584                              <1> ;M9:
  4585 000016C0 BB[58690000]        <1> 	mov	ebx, video_params ; initialization table
  4586                              <1> 	;mov	ax, [ebx+10]      ; get the cursor mode from the table	
  4587                              <1> 	;xchg 	ah, al
  4588                              <1> 	;mov	[CURSOR_MODE], ax ; save cursor mode
  4589 000016C5 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
  4590                              <1> 	
  4591                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
  4592 000016C7 B910000000          <1> 	mov	ecx, 16 ; 16/01/2016
  4593                              <1> M10:			;  initialization loop
  4594 000016CC 88E0                <1> 	mov	al, ah 	; get 6845 register number
  4595 000016CE EE                  <1> 	out	dx, al
  4596 000016CF 6642                <1> 	inc	dx      ; point to data port
  4597 000016D1 FEC4                <1> 	inc	ah	; next register value
  4598 000016D3 8A03                <1> 	mov	al, [ebx] ; get table value
  4599 000016D5 EE                  <1> 	out	dx, al	; out to chip
  4600 000016D6 43                  <1> 	inc	ebx	; next in table
  4601 000016D7 664A                <1> 	dec	dx	; back to pointer register
  4602 000016D9 E2F1                <1> 	loop	M10	; do the whole table
  4603                              <1> 	
  4604                              <1> ;-----	FILL REGEN AREA WITH BLANK
  4605                              <1> 	;xor	ax, ax  
  4606                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
  4607                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
  4608                              <1> 	;mov	ecx, 8192 ; number of words in color card
  4609                              <1> 	; black background, light gray characeter color, space character
  4610                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
  4611                              <1> ;M13:			  ; clear buffer
  4612                              <1> 	;add	edi, 0B8000h ; [crt_base]
  4613                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
  4614                              <1> 
  4615                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
  4616                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
  4617                              <1> 			 ; prepare to output to video enable port
  4618                              <1> 	;add	dx,4	 ; point to the mode control gerister
  4619 000016DB 66BAD803            <1> 	mov	dx, 3D8h
  4620                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
  4621 000016DF B029                <1> 	mov	al, 29h
  4622 000016E1 EE                  <1> 	out	dx, al	 ; set video enable port
  4623                              <1> 
  4624                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
  4625                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
  4626                              <1> 	;
  4627                              <1> 	;mov byte [CRT_COLS], 80h ; initialize number of columns count
  4628                              <1> 	;
  4629                              <1> ;-----	SET CURSOR POSITIONS
  4630                              <1> 	;push	edi
  4631                              <1> 	;mov	word [CRT_LEN], 80*25*2
  4632 000016E2 BF[166F0000]        <1> 	mov	edi, cursor_posn
  4633 000016E7 B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
  4634 000016EC 31C0                <1> 	xor	eax, eax
  4635 000016EE F3AB                <1> 	rep 	stosd	; fill with zeroes
  4636                              <1> 	;pop	edi
  4637                              <1> 
  4638                              <1> ;-----	SET UP OVERSCAN REGISTER
  4639 000016F0 6642                <1> 	inc	dx	; set overscan port to a default
  4640 000016F2 B030                <1> 	mov	al, 30h	; 30H valuye for all modes except 640X200 bw
  4641                              <1> ;M14:
  4642 000016F4 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
  4643                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
  4644                              <1> 
  4645                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  4646                              <1> 	;
  4647 000016F5 58                  <1> 	pop	eax
  4648 000016F6 59                  <1> 	pop	ecx ; 16/01/2016
  4649 000016F7 5A                  <1> 	pop	edx
  4650 000016F8 5B                  <1> 	pop	ebx
  4651 000016F9 5F                  <1> 	pop	edi ; 16/01/2016
  4652 000016FA C3                  <1> 	retn
  4653                              <1> 	
  4654                              <1> tty_sw:
  4655                              <1> 	; 30/06/2015
  4656                              <1> 	; 27/06/2015 
  4657                              <1> 	; 07/09/2014
  4658                              <1> 	; 02/09/2014 (Retro UNIX 386 v1 - beginning)
  4659                              <1> 	;
  4660                              <1> 	; (Modified registers : EAX)
  4661                              <1> 	;
  4662                              <1>         ;mov     byte [u.quant], 0  ; 04/03/2014
  4663                              <1> 	;
  4664                              <1> ;act_disp_page:
  4665                              <1> 	; 30/06/2015
  4666                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
  4667                              <1> 	; 10/12/2013
  4668                              <1> 	; 04/12/2013
  4669                              <1> 	;
  4670                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4671                              <1> 	;
  4672                              <1> 	; ACT_DISP_PAGE
  4673                              <1> 	;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
  4674                              <1> 	;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
  4675                              <1> 	; INPUT
  4676                              <1> 	;	AL HAS THE NEW ACTIVE DISPLAY PAGE
  4677                              <1> 	; OUTPUT
  4678                              <1> 	;	THE 6845 IS RESET TO DISPLAY THAT PAGE
  4679                              <1> 
  4680                              <1> 	;cli
  4681                              <1> 
  4682 000016FB 53                  <1> 	push	ebx
  4683 000016FC 6651                <1> 	push	cx
  4684 000016FE 6652                <1> 	push	dx
  4685                              <1> 	;
  4686 00001700 A2[266F0000]        <1> 	mov	[active_page], al ; save active page value ; [ptty]
  4687                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
  4688 00001705 66B9A00F            <1> 	mov	cx, 25*80*2
  4689                              <1> 	; 27/06/2015
  4690 00001709 0FB6D8              <1> 	movzx	ebx, al
  4691                              <1> 	;
  4692 0000170C 6698                <1> 	cbw	; 07/09/2014 (ah=0)
  4693 0000170E 66F7E1              <1> 	mul 	cx	; display page times regen length
  4694                              <1> 	; 10/12/2013
  4695 00001711 66A3[146F0000]      <1> 	mov	[CRT_START], ax ; save start address for later
  4696 00001717 6689C1              <1> 	mov	cx, ax ; start address to cx
  4697                              <1> 	;sar	cx, 1
  4698 0000171A 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
  4699 0000171D B40C                <1> 	mov	ah, 12	; 6845 register for start address
  4700 0000171F E838FEFFFF          <1> 	call	m16
  4701                              <1> 	;sal	bx, 1
  4702                              <1> 	; 01/09/2014
  4703 00001724 D0E3                <1> 	shl	bl, 1	; *2 for word offset
  4704 00001726 81C3[166F0000]      <1> 	add	ebx, cursor_posn
  4705 0000172C 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
  4706 0000172F E814FEFFFF          <1> 	call	m18
  4707                              <1> 	;
  4708 00001734 665A                <1> 	pop	dx
  4709 00001736 6659                <1> 	pop	cx
  4710 00001738 5B                  <1> 	pop	ebx
  4711                              <1> 	;
  4712                              <1> 	;sti
  4713                              <1> 	;
  4714 00001739 C3                  <1> 	retn
  4715                              <1> 
  4716                              <1> ; % include 'vidata.inc' ; VIDEO DATA ; 11/03/2015
  4717                              <1> 
  4718                              <1> 
  4719                              <1> ; /// End Of VIDEO FUNCTIONS ///
  4720                                  
  4721                                  setup_rtc_int:
  4722                                  ; source: http://wiki.osdev.org/RTC
  4723 0000173A FA                      	cli		; disable interrupts
  4724                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  4725                                  	; in order to change this ...
  4726                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  4727                                  	; (rate must be above 2 and not over 15)
  4728                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  4729 0000173B B08A                    	mov	al, 8Ah 
  4730 0000173D E670                    	out	70h, al ; set index to register A, disable NMI
  4731 0000173F 90                      	nop
  4732 00001740 E471                    	in	al, 71h ; get initial value of register A
  4733 00001742 88C4                    	mov 	ah, al
  4734 00001744 80E4F0                  	and	ah, 0F0h
  4735 00001747 B08A                    	mov	al, 8Ah 
  4736 00001749 E670                    	out	70h, al ; reset index to register A
  4737 0000174B 88E0                    	mov	al, ah
  4738 0000174D 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  4739 0000174F E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  4740                                  	; enable RTC interrupt
  4741 00001751 B08B                    	mov	al, 8Bh ;
  4742 00001753 E670                    	out	70h, al ; select register B and disable NMI
  4743 00001755 90                      	nop
  4744 00001756 E471                    	in	al, 71h ; read the current value of register B
  4745 00001758 88C4                    	mov	ah, al  ;
  4746 0000175A B08B                    	mov 	al, 8Bh ;
  4747 0000175C E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  4748 0000175E 88E0                    	mov	al, ah  ;
  4749 00001760 0C40                    	or	al, 40h ;
  4750 00001762 E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  4751 00001764 FB                      	sti
  4752 00001765 C3                      	retn
  4753                                  
  4754                                  ; Write memory information
  4755                                  ; Temporary Code
  4756                                  ; 06/11/2014
  4757                                  ; 14/08/2015 
  4758                                  memory_info:	
  4759 00001766 A1[FC6E0000]            	mov	eax, [memory_size] ; in pages
  4760 0000176B 50                      	push	eax
  4761 0000176C C1E00C                  	shl	eax, 12		   ; in bytes
  4762 0000176F BB0A000000              	mov	ebx, 10
  4763 00001774 89D9                    	mov	ecx, ebx	   ; 10
  4764 00001776 BE[616B0000]            	mov	esi, mem_total_b_str	
  4765 0000177B E8B2000000              	call	bintdstr
  4766 00001780 58                      	pop	eax
  4767 00001781 B107                    	mov	cl, 7
  4768 00001783 BE[856B0000]            	mov	esi, mem_total_p_str
  4769 00001788 E8A5000000              	call	bintdstr	
  4770                                  	; 14/08/2015
  4771 0000178D E8BD000000              	call	calc_free_mem
  4772                                  	; edx = calculated free pages
  4773                                  	; ecx = 0
  4774 00001792 A1[006F0000]            	mov 	eax, [free_pages]
  4775 00001797 39D0                    	cmp	eax, edx ; calculated free mem value 
  4776                                  		; and initial free mem value are same or not?
  4777 00001799 751D                    	jne 	short pmim ; print mem info with '?' if not
  4778 0000179B 52                      	push 	edx ; free memory in pages	
  4779                                  	;mov 	eax, edx
  4780 0000179C C1E00C                  	shl	eax, 12 ; convert page count
  4781                                  			; to byte count
  4782 0000179F B10A                    	mov	cl, 10
  4783 000017A1 BE[A56B0000]            	mov	esi, free_mem_b_str
  4784 000017A6 E887000000              	call	bintdstr
  4785 000017AB 58                      	pop	eax
  4786 000017AC B107                    	mov	cl, 7
  4787 000017AE BE[C96B0000]            	mov	esi, free_mem_p_str
  4788 000017B3 E87A000000              	call	bintdstr
  4789                                  pmim:
  4790 000017B8 BE[4F6B0000]            	mov	esi, msg_memory_info
  4791                                  pmim_nb:	
  4792 000017BD AC                      	lodsb
  4793 000017BE 08C0                    	or	al, al
  4794 000017C0 740D                    	jz	short pmim_ok
  4795 000017C2 56                      	push	esi
  4796 000017C3 31DB                    	xor	ebx, ebx ; 0
  4797                                  			; Video page 0 (bl=0)
  4798 000017C5 B407                    	mov	ah, 07h ; Black background, 
  4799                                  			; light gray forecolor
  4800 000017C7 E841FCFFFF              	call	write_tty
  4801 000017CC 5E                      	pop	esi
  4802 000017CD EBEE                    	jmp	short pmim_nb
  4803                                  pmim_ok:
  4804 000017CF C3                      	retn
  4805                                  
  4806                                  ; Convert binary number to hexadecimal string
  4807                                  ; 10/05/2015  
  4808                                  ; dsectpm.s (28/02/2015)
  4809                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  4810                                  ; 01/12/2014
  4811                                  ; 25/11/2014
  4812                                  ;
  4813                                  bytetohex:
  4814                                  	; INPUT ->
  4815                                  	; 	AL = byte (binary number)
  4816                                  	; OUTPUT ->
  4817                                  	;	AX = hexadecimal string
  4818                                  	;
  4819 000017D0 53                      	push	ebx
  4820 000017D1 31DB                    	xor	ebx, ebx
  4821 000017D3 88C3                    	mov	bl, al
  4822 000017D5 C0EB04                  	shr	bl, 4
  4823 000017D8 8A9B[22180000]          	mov	bl, [ebx+hexchrs] 	 	
  4824 000017DE 86D8                    	xchg	bl, al
  4825 000017E0 80E30F                  	and	bl, 0Fh
  4826 000017E3 8AA3[22180000]          	mov	ah, [ebx+hexchrs] 
  4827 000017E9 5B                      	pop	ebx	
  4828 000017EA C3                      	retn
  4829                                  
  4830                                  wordtohex:
  4831                                  	; INPUT ->
  4832                                  	; 	AX = word (binary number)
  4833                                  	; OUTPUT ->
  4834                                  	;	EAX = hexadecimal string
  4835                                  	;
  4836 000017EB 53                      	push	ebx
  4837 000017EC 31DB                    	xor	ebx, ebx
  4838 000017EE 86E0                    	xchg	ah, al
  4839 000017F0 6650                    	push	ax
  4840 000017F2 88E3                    	mov	bl, ah
  4841 000017F4 C0EB04                  	shr	bl, 4
  4842 000017F7 8A83[22180000]          	mov	al, [ebx+hexchrs] 	 	
  4843 000017FD 88E3                    	mov	bl, ah
  4844 000017FF 80E30F                  	and	bl, 0Fh
  4845 00001802 8AA3[22180000]          	mov	ah, [ebx+hexchrs]
  4846 00001808 C1E010                  	shl	eax, 16
  4847 0000180B 6658                    	pop	ax
  4848 0000180D 5B                      	pop	ebx
  4849 0000180E EBC0                    	jmp	short bytetohex
  4850                                  	;mov	bl, al
  4851                                  	;shr	bl, 4
  4852                                  	;mov	bl, [ebx+hexchrs] 	 	
  4853                                  	;xchg	bl, al	 	
  4854                                  	;and	bl, 0Fh
  4855                                  	;mov	ah, [ebx+hexchrs] 
  4856                                  	;pop	ebx	
  4857                                  	;retn
  4858                                  
  4859                                  dwordtohex:
  4860                                  	; INPUT ->
  4861                                  	; 	EAX = dword (binary number)
  4862                                  	; OUTPUT ->
  4863                                  	;	EDX:EAX = hexadecimal string
  4864                                  	;
  4865 00001810 50                      	push	eax
  4866 00001811 C1E810                  	shr	eax, 16
  4867 00001814 E8D2FFFFFF              	call	wordtohex
  4868 00001819 89C2                    	mov	edx, eax
  4869 0000181B 58                      	pop	eax
  4870 0000181C E8CAFFFFFF              	call	wordtohex
  4871 00001821 C3                      	retn
  4872                                  
  4873                                  ; 10/05/2015
  4874                                  hex_digits:
  4875                                  hexchrs:
  4876 00001822 303132333435363738-     	db '0123456789ABCDEF'
  4877 0000182B 39414243444546     
  4878                                  
  4879                                  ; Convert binary number to decimal/numeric string
  4880                                  ; 06/11/2014
  4881                                  ; Temporary Code
  4882                                  ;
  4883                                  
  4884                                  bintdstr:
  4885                                  	; EAX = binary number
  4886                                  	; ESI = decimal/numeric string address
  4887                                  	; EBX = divisor (10)
  4888                                  	; ECX = string length (<=10)
  4889 00001832 01CE                    	add	esi, ecx
  4890                                  btdstr0:
  4891 00001834 4E                      	dec	esi
  4892 00001835 31D2                    	xor	edx, edx
  4893 00001837 F7F3                    	div	ebx
  4894 00001839 80C230                  	add	dl, 30h
  4895 0000183C 8816                    	mov	[esi], dl
  4896 0000183E FEC9                    	dec	cl
  4897 00001840 740C                    	jz	btdstr2
  4898 00001842 09C0                    	or	eax, eax
  4899 00001844 75EE                    	jnz	short btdstr0
  4900                                  btdstr1:
  4901 00001846 4E                      	dec	esi
  4902 00001847 C60620                          mov     byte [esi], 20h ; blank space
  4903 0000184A FEC9                    	dec	cl
  4904 0000184C 75F8                    	jnz	short btdstr1
  4905                                  btdstr2:
  4906 0000184E C3                      	retn
  4907                                  
  4908                                  ; Calculate free memory pages on M.A.T.
  4909                                  ; 06/11/2014
  4910                                  ; Temporary Code
  4911                                  ;
  4912                                  
  4913                                  calc_free_mem:
  4914 0000184F 31D2                    	xor	edx, edx
  4915                                  	;xor	ecx, ecx
  4916 00001851 668B0D[106F0000]        	mov	cx, [mat_size] ; in pages
  4917 00001858 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  4918 0000185B BE00001000              	mov	esi, MEM_ALLOC_TBL
  4919                                  cfm0:
  4920 00001860 AD                      	lodsd
  4921 00001861 51                      	push	ecx
  4922 00001862 B920000000              	mov	ecx, 32
  4923                                  cfm1:
  4924 00001867 D1E8                    	shr	eax, 1
  4925 00001869 7301                    	jnc	short cfm2
  4926 0000186B 42                      	inc	edx
  4927                                  cfm2:
  4928 0000186C E2F9                    	loop	cfm1
  4929 0000186E 59                      	pop	ecx
  4930 0000186F E2EF                    	loop	cfm0
  4931 00001871 C3                      	retn
  4932                                  
  4933                                  %include 'diskio.s'  ; 07/03/2015
  4934                              <1> ; Retro UNIX 386 v1 Kernel - DISKIO.INC
  4935                              <1> ; Last Modification: 04/02/2016
  4936                              <1> ; 	(Initialized Disk Parameters Data is in 'DISKDATA.INC') 
  4937                              <1> ; 	(Uninitialized Disk Parameters Data is in 'DISKBSS.INC') 
  4938                              <1> 
  4939                              <1> ; DISK I/O SYSTEM - Erdogan Tan (Retro UNIX 386 v1 project)
  4940                              <1> 
  4941                              <1> ; ///////// DISK I/O SYSTEM ///////////////
  4942                              <1> 
  4943                              <1> ; 06/02/2015
  4944                              <1> diskette_io:
  4945 00001872 9C                  <1> 	pushfd
  4946 00001873 0E                  <1> 	push 	cs
  4947 00001874 E809000000          <1> 	call 	DISKETTE_IO_1
  4948 00001879 C3                  <1> 	retn
  4949                              <1> 	
  4950                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
  4951                              <1> ;//////////////////////////////////////////////////////
  4952                              <1> 
  4953                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  4954                              <1> ; 20/02/2015
  4955                              <1> ; 06/02/2015 (unix386.s)
  4956                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
  4957                              <1> ;
  4958                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
  4959                              <1> ;
  4960                              <1> ; ADISK.EQU
  4961                              <1> 
  4962                              <1> ;----- Wait control constants 
  4963                              <1> 
  4964                              <1> ;amount of time to wait while RESET is active.
  4965                              <1> 
  4966                              <1> WAITCPU_RESET_ON	EQU	21		;Reset on must last at least 14us
  4967                              <1> 						;at 250 KBS xfer rate.
  4968                              <1> 						;see INTEL MCS, 1985, pg. 5-456
  4969                              <1> 
  4970                              <1> WAITCPU_FOR_STATUS	EQU	100		;allow 30 microseconds for
  4971                              <1> 						;status register to become valid
  4972                              <1> 						;before re-reading.
  4973                              <1> 
  4974                              <1> ;After sending a byte to NEC, status register may remain
  4975                              <1> ;incorrectly set for 24 us.
  4976                              <1> 
  4977                              <1> WAITCPU_RQM_LOW		EQU	24		;number of loops to check for
  4978                              <1> 						;RQM low.
  4979                              <1> 
  4980                              <1> ; COMMON.MAC
  4981                              <1> ;
  4982                              <1> ;	Timing macros
  4983                              <1> ;
  4984                              <1> 
  4985                              <1> %macro 		SIODELAY 0 			; SHORT IODELAY
  4986                              <1> 		jmp short $+2
  4987                              <1> %endmacro		
  4988                              <1> 
  4989                              <1> %macro		IODELAY  0			; NORMAL IODELAY
  4990                              <1> 		jmp short $+2
  4991                              <1> 		jmp short $+2
  4992                              <1> %endmacro
  4993                              <1> 
  4994                              <1> %macro		NEWIODELAY 0
  4995                              <1> 		out	0ebh,al
  4996                              <1> %endmacro 
  4997                              <1> 
  4998                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
  4999                              <1> ;;; WAIT_FOR_MEM
  5000                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
  5001                              <1> ;WAIT_FDU_INT_HI	equ	1
  5002                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
  5003                              <1> ;;; WAIT_FOR_PORT
  5004                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
  5005                              <1> ;WAIT_FDU_SEND_HI	equ	0
  5006                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
  5007                              <1> ;Time to wait while waiting for each byte of NEC results = .5
  5008                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  5009                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
  5010                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
  5011                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
  5012                              <1> ;;; WAIT_REFRESH
  5013                              <1> ;amount of time to wait for head settle, per unit in parameter
  5014                              <1> ;table = 1 ms.
  5015                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
  5016                              <1> 
  5017                              <1> 
  5018                              <1> ; //////////////// DISKETTE I/O ////////////////
  5019                              <1> 
  5020                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
  5021                              <1> 
  5022                              <1> ;----------------------------------------
  5023                              <1> ;	EQUATES USED BY POST AND BIOS	:
  5024                              <1> ;----------------------------------------
  5025                              <1> 
  5026                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  5027                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  5028                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  5029                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
  5030                              <1> 
  5031                              <1> ;----------------------------------------
  5032                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
  5033                              <1> ;-------------------------------------------------------------------------------
  5034                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
  5035                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
  5036                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
  5037                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
  5038                              <1> 
  5039                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
  5040                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
  5041                              <1> ;		EQU	011H		; - RESERVED			      ;C
  5042                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
  5043                              <1> ;		EQU	013H		; - RESERVED			      ;E
  5044                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
  5045                              <1> 
  5046                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
  5047                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
  5048                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
  5049                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
  5050                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
  5051                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
  5052                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
  5053                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
  5054                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
  5055                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
  5056                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
  5057                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
  5058                              <1> 
  5059                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
  5060                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
  5061                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
  5062                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
  5063                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
  5064                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
  5065                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
  5066                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
  5067                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
  5068                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
  5069                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
  5070                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
  5071                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
  5072                              <1> 
  5073                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
  5074                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
  5075                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
  5076                              <1> 
  5077                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
  5078                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
  5079                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
  5080                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
  5081                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
  5082                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
  5083                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
  5084                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
  5085                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
  5086                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
  5087                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
  5088                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
  5089                              <1> 
  5090                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
  5091                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
  5092                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
  5093                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
  5094                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
  5095                              <1> 
  5096                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
  5097                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
  5098                              <1> ;INTA00		EQU	020H		; 8259 PORT
  5099                              <1> INTA01		EQU	021H		; 8259 PORT
  5100                              <1> INTB00		EQU	0A0H		; 2ND 8259
  5101                              <1> INTB01		EQU	0A1H		;
  5102                              <1> 
  5103                              <1> ;-------------------------------------------------------------------------------
  5104                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
  5105                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
  5106                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
  5107                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
  5108                              <1> ;-------------------------------------------------------------------------------
  5109                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
  5110                              <1> 
  5111                              <1> ;-------------------------------------------------------------------------------
  5112                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
  5113                              <1> 
  5114                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
  5115                              <1> ; (unix386.s <-- dsectrm2.s)
  5116                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
  5117                              <1> 
  5118                              <1> ; 10/12/2014
  5119                              <1> ;
  5120                              <1> ;int40h:
  5121                              <1> ;	pushf
  5122                              <1> ;	push 	cs
  5123                              <1> ;	;cli
  5124                              <1> ;	call 	DISKETTE_IO_1
  5125                              <1> ;	retn
  5126                              <1> 
  5127                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
  5128                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  5129                              <1> ;
  5130                              <1> 
  5131                              <1> ;-- INT13H ---------------------------------------------------------------------
  5132                              <1> ; DISKETTE I/O
  5133                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
  5134                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
  5135                              <1> ; INPUT
  5136                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
  5137                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
  5138                              <1> ;		ON ALL DRIVES
  5139                              <1> ;------------------------------------------------------------------------------- 
  5140                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
  5141                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
  5142                              <1> ;-------------------------------------------------------------------------------
  5143                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
  5144                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5145                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
  5146                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
  5147                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
  5148                              <1> ;		320/360	320/360	    0-39
  5149                              <1> ;		320/360	1.2M	    0-39
  5150                              <1> ;		1.2M	1.2M	    0-79
  5151                              <1> ;		720K	720K	    0-79
  5152                              <1> ;		1.44M	1.44M	    0-79	
  5153                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
  5154                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
  5155                              <1> ;		320/360	320/360	     1-8/9
  5156                              <1> ;		320/360	1.2M	     1-8/9
  5157                              <1> ;		1.2M	1.2M	     1-15
  5158                              <1> ;		720K	720K	     1-9
  5159                              <1> ;		1.44M	1.44M	     1-18		
  5160                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
  5161                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
  5162                              <1> ;		320/360	320/360	        8/9
  5163                              <1> ;		320/360	1.2M	        8/9
  5164                              <1> ;		1.2M	1.2M		15
  5165                              <1> ;		720K	720K		9
  5166                              <1> ;		1.44M	1.44M		18
  5167                              <1> ;
  5168                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
  5169                              <1> ;
  5170                              <1> ;-------------------------------------------------------------------------------
  5171                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
  5172                              <1> ;-------------------------------------------------------------------------------
  5173                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
  5174                              <1> ;-------------------------------------------------------------------------------
  5175                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
  5176                              <1> ;-------------------------------------------------------------------------------
  5177                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
  5178                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
  5179                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
  5180                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
  5181                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
  5182                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
  5183                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
  5184                              <1> ;		READ/WRITE ACCESS.
  5185                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
  5186                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
  5187                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
  5188                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
  5189                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
  5190                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
  5191                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
  5192                              <1> ;
  5193                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
  5194                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
  5195                              <1> ;		---------------------------------------------
  5196                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
  5197                              <1> ;		---------------------------------------------
  5198                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
  5199                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
  5200                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
  5201                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
  5202                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
  5203                              <1> ;		---------------------------------------------
  5204                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
  5205                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
  5206                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
  5207                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
  5208                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
  5209                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
  5210                              <1> ;-------------------------------------------------------------------------------
  5211                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
  5212                              <1> ;	REGISTERS
  5213                              <1> ;	  INPUT
  5214                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5215                              <1> ;	  OUTPUT
  5216                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
  5217                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
  5218                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5219                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5220                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
  5221                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
  5222                              <1> ;	    (BH) - 0
  5223                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
  5224                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
  5225                              <1> ;	    (AX) - 0
  5226                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
  5227                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
  5228                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
  5229                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
  5230                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
  5231                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
  5232                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
  5233                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
  5234                              <1> ;-------------------------------------------------------------------------------
  5235                              <1> ;	(AH)= 15H  READ DASD TYPE
  5236                              <1> ;	OUTPUT REGISTERS
  5237                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
  5238                              <1> ;		00 - DRIVE NOT PRESENT	
  5239                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
  5240                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
  5241                              <1> ;		03 - RESERVED (FIXED DISK)
  5242                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5243                              <1> ;-------------------------------------------------------------------------------
  5244                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
  5245                              <1> ;	OUTPUT REGISTERS
  5246                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
  5247                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
  5248                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5249                              <1> ;-------------------------------------------------------------------------------
  5250                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
  5251                              <1> ;	INPUT REGISTERS
  5252                              <1> ;	(AL) -	00 - NOT USED	
  5253                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
  5254                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
  5255                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
  5256                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
  5257                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
  5258                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
  5259                              <1> ;-------------------------------------------------------------------------------
  5260                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
  5261                              <1> ;	INPUT REGISTERS
  5262                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
  5263                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5264                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5265                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
  5266                              <1> ;	OUTPUT REGISTERS:
  5267                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
  5268                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
  5269                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
  5270                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
  5271                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
  5272                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
  5273                              <1> ;-------------------------------------------------------------------------------
  5274                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
  5275                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
  5276                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
  5277                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
  5278                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
  5279                              <1> ;		CHANGE ERROR CODE
  5280                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
  5281                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
  5282                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
  5283                              <1> ;
  5284                              <1> ; DATA VARIABLE -- @DISK_POINTER
  5285                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
  5286                              <1> ;-------------------------------------------------------------------------------
  5287                              <1> ; OUTPUT FOR ALL FUNCTIONS
  5288                              <1> ;	AH = STATUS OF OPERATION
  5289                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
  5290                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
  5291                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
  5292                              <1> ;		TYPE AH=(15)).
  5293                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
  5294                              <1> ;	FOR READ/WRITE/VERIFY
  5295                              <1> ;		DS,BX,DX,CX PRESERVED
  5296                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
  5297                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
  5298                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
  5299                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
  5300                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
  5301                              <1> ;-------------------------------------------------------------------------------
  5302                              <1> ;
  5303                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
  5304                              <1> ;
  5305                              <1> ;   -----------------------------------------------------------------
  5306                              <1> ;   |       |       |       |       |       |       |       |       |
  5307                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
  5308                              <1> ;   |       |       |       |       |       |       |       |       |
  5309                              <1> ;   -----------------------------------------------------------------
  5310                              <1> ;	|	|	|	|	|	|	|	|
  5311                              <1> ;	|	|	|	|	|	-----------------
  5312                              <1> ;	|	|	|	|	|		|
  5313                              <1> ;	|	|	|	|    RESERVED		|
  5314                              <1> ;	|	|	|	|		  PRESENT STATE
  5315                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
  5316                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
  5317                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
  5318                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
  5319                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
  5320                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
  5321                              <1> ;	|	|	|	|	110: RESERVED
  5322                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
  5323                              <1> ;	|	|	|	|
  5324                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
  5325                              <1> ;	|	|	|
  5326                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
  5327                              <1> ;	|	|			DRIVE)
  5328                              <1> ;	|	|
  5329                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
  5330                              <1> ;
  5331                              <1> ;						00: 500 KBS
  5332                              <1> ;						01: 300 KBS
  5333                              <1> ;						10: 250 KBS
  5334                              <1> ;						11: RESERVED
  5335                              <1> ;
  5336                              <1> ;
  5337                              <1> ;-------------------------------------------------------------------------------
  5338                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
  5339                              <1> ;-------------------------------------------------------------------------------
  5340                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
  5341                              <1> ;-------------------------------------------------------------------------------
  5342                              <1> 
  5343                              <1> struc MD
  5344 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  5345 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  5346 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  5347 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
  5348 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
  5349 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
  5350 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
  5351 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
  5352 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
  5353 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
  5354 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
  5355 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
  5356 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
  5357                              <1> endstruc
  5358                              <1> 
  5359                              <1> BIT7OFF	EQU	7FH
  5360                              <1> BIT7ON	EQU	80H
  5361                              <1> 
  5362                              <1> ;;int13h: ; 16/02/2015
  5363                              <1> ;; 16/02/2015 - 21/02/2015
  5364                              <1> int40h:
  5365 0000187A 9C                  <1> 	pushfd
  5366 0000187B 0E                  <1> 	push 	cs
  5367 0000187C E801000000          <1> 	call 	DISKETTE_IO_1
  5368 00001881 C3                  <1> 	retn	
  5369                              <1> 
  5370                              <1> DISKETTE_IO_1:
  5371                              <1> 
  5372 00001882 FB                  <1> 	STI				; INTERRUPTS BACK ON
  5373 00001883 55                  <1> 	PUSH	eBP			; USER REGISTER
  5374 00001884 57                  <1> 	PUSH	eDI			; USER REGISTER
  5375 00001885 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
  5376 00001886 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
  5377 00001887 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
  5378 00001888 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
  5379                              <1> 					; [BP]   = SECTOR #
  5380                              <1> 					; [BP+1] = TRACK #
  5381                              <1> 					; [BP+2] = BUFFER OFFSET
  5382                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
  5383                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
  5384                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
  5385                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
  5386                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
  5387                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
  5388                              <1> 					; BH/[BP+3] = 0
  5389                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
  5390                              <1> 					; DH/[BP+5] = MAX HEAD #
  5391                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
  5392 0000188A 06                  <1> 	push	es ; 06/02/2015	
  5393 0000188B 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
  5394 0000188C 56                  <1> 	PUSH	eSI			; USER REGISTERS
  5395                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
  5396                              <1> 	;mov	cx, cs
  5397                              <1> 	;mov	ds, cx
  5398 0000188D 66B91000            <1> 	mov	cx, KDATA
  5399 00001891 8ED9                <1>         mov     ds, cx
  5400 00001893 8EC1                <1>         mov     es, cx
  5401                              <1> 
  5402                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
  5403 00001895 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4 ; 18/02/2015
  5404 00001898 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
  5405 0000189A B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5406                              <1> OK_FUNC:
  5407 0000189C 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
  5408 0000189F 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
  5409 000018A1 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
  5410 000018A4 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
  5411 000018A6 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
  5412 000018A9 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
  5413 000018AB B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5414                              <1> OK_DRV:
  5415 000018AD 31C9                <1> 	xor	ecx, ecx
  5416                              <1> 	;mov	esi, ecx ; 08/02/2015
  5417 000018AF 89CF                <1> 	mov	edi, ecx ; 08/02/2015
  5418 000018B1 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
  5419                              <1> 	;XOR	CH,CH			; CX = FUNCTION
  5420                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
  5421 000018B3 C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
  5422 000018B6 BB[EE180000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
  5423 000018BB 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
  5424 000018BD 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
  5425 000018BF 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
  5426 000018C1 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
  5427 000018C4 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
  5428                              <1> 	;
  5429                              <1> 	; 11/12/2014
  5430 000018C7 8815[E1690000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
  5431                              <1> 	;
  5432 000018CD 8A25[7C6F0000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
  5433 000018D3 C605[7C6F0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
  5434                              <1> 
  5435                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
  5436                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
  5437                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
  5438                              <1> ;
  5439                              <1> ;		DI	: DRIVE #
  5440                              <1> ;		SI-HI	: HEAD #
  5441                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
  5442                              <1> ;		ES	: BUFFER SEGMENT
  5443                              <1> ;		[BP]	: SECTOR #
  5444                              <1> ;		[BP+1]	: TRACK #
  5445                              <1> ;		[BP+2]	: BUFFER OFFSET
  5446                              <1> ;
  5447                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
  5448                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
  5449                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
  5450                              <1> ;	SPECIFIC ERROR CODE.
  5451                              <1> ;
  5452                              <1> 					; (AH) = @DSKETTE_STATUS
  5453 000018DA FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
  5454 000018DC 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
  5455 000018DD 1F                  <1> 	POP	DS
  5456 000018DE 07                  <1> 	pop	es	; 06/02/2015
  5457 000018DF 59                  <1> 	POP	eCX
  5458 000018E0 5B                  <1> 	POP	eBX
  5459 000018E1 5A                  <1> 	POP	eDX
  5460 000018E2 5F                  <1> 	POP	eDI
  5461 000018E3 89E5                <1> 	MOV	eBP, eSP
  5462 000018E5 50                  <1> 	PUSH	eAX
  5463 000018E6 9C                  <1> 	PUSHFd
  5464 000018E7 58                  <1> 	POP	eAX
  5465                              <1> 	;MOV	[BP+6], AX
  5466 000018E8 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
  5467 000018EB 58                  <1> 	POP	eAX
  5468 000018EC 5D                  <1> 	POP	eBP
  5469 000018ED CF                  <1> 	IRETd
  5470                              <1> 
  5471                              <1> ;-------------------------------------------------------------------------------
  5472                              <1> ; DW --> dd (06/02/2015)
  5473 000018EE [52190000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
  5474 000018F2 [CB190000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
  5475 000018F6 [DC190000]          <1> 	dd	DSK_READ		; AH = 02H; READ
  5476 000018FA [ED190000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
  5477 000018FE [FE190000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
  5478 00001902 [0F1A0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
  5479 00001906 [941A0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
  5480 0000190A [941A0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
  5481 0000190E [A11A0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
  5482 00001912 [941A0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
  5483 00001916 [941A0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
  5484 0000191A [941A0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
  5485 0000191E [941A0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
  5486 00001922 [941A0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
  5487 00001926 [941A0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
  5488 0000192A [941A0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
  5489 0000192E [941A0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
  5490 00001932 [941A0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
  5491 00001936 [941A0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
  5492 0000193A [941A0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
  5493 0000193E [941A0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
  5494 00001942 [621B0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
  5495 00001946 [8D1B0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
  5496 0000194A [C71B0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
  5497 0000194E [4A1C0000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
  5498                              <1> FNC_TAE EQU     $                       ; END
  5499                              <1> 
  5500                              <1> ;-------------------------------------------------------------------------------
  5501                              <1> ; DISK_RESET	(AH = 00H)	
  5502                              <1> ;		RESET THE DISKETTE SYSTEM.
  5503                              <1> ;
  5504                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5505                              <1> ;-------------------------------------------------------------------------------
  5506                              <1> DSK_RESET:
  5507 00001952 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
  5508 00001956 FA                  <1> 	CLI				; NO INTERRUPTS
  5509 00001957 A0[7A6F0000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  5510 0000195C 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
  5511 0000195E C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
  5512                              <1> 					; DRIVE SELECT TO LOW NIBBLE
  5513 00001961 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
  5514 00001963 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5515 00001964 C605[796F0000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  5516                              <1> 	;JMP	$+2			; WAIT FOR I/O
  5517                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
  5518                              <1> 					;      PULSE WIDTH)
  5519                              <1> 	; 19/12/2014
  5520                              <1> 	NEWIODELAY
  5521 0000196B E6EB                <2>  out 0ebh,al
  5522                              <1> 
  5523                              <1> 	; 17/12/2014 
  5524                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
  5525 0000196D B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
  5526                              <1> wdw1:
  5527                              <1> 	NEWIODELAY   ; 27/02/2015
  5528 00001972 E6EB                <2>  out 0ebh,al
  5529 00001974 E2FC                <1> 	loop	wdw1
  5530                              <1> 	;
  5531 00001976 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
  5532 00001978 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5533                              <1> 	; 16/12/2014
  5534                              <1> 	IODELAY
  5535 00001979 EB00                <2>  jmp short $+2
  5536 0000197B EB00                <2>  jmp short $+2
  5537                              <1> 	;
  5538                              <1> 	;STI				; ENABLE THE INTERRUPTS
  5539 0000197D E8250C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  5540 00001982 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
  5541 00001984 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
  5542                              <1> NXT_DRV:
  5543 00001988 6651                <1> 	PUSH	CX			; SAVE FOR CALL
  5544 0000198A B8[C0190000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
  5545 0000198F 50                  <1> 	PUSH	eAX			; "
  5546 00001990 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  5547 00001992 E8030B0000          <1> 	CALL	NEC_OUTPUT
  5548 00001997 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  5549 00001998 E83A0C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  5550 0000199D 6659                <1> 	POP	CX			; RESTORE AFTER CALL
  5551 0000199F 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
  5552 000019A1 3A0D[7D6F0000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
  5553 000019A7 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
  5554 000019A9 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
  5555 000019AB 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
  5556 000019AE 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
  5557                              <1> 	;
  5558 000019B0 E852030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5559                              <1> RESBAC:
  5560 000019B5 E806090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5561 000019BA 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5562 000019BD 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5563 000019BF C3                  <1> 	RETn		
  5564                              <1> DR_POP_ERR:
  5565 000019C0 6659                <1> 	POP	CX			; CLEAR STACK
  5566                              <1> DR_ERR:
  5567 000019C2 800D[7C6F0000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
  5568 000019C9 EBEA                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
  5569                              <1> 
  5570                              <1> ;-------------------------------------------------------------------------------
  5571                              <1> ; DISK_STATUS	(AH = 01H)
  5572                              <1> ;	DISKETTE STATUS.
  5573                              <1> ;
  5574                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
  5575                              <1> ;
  5576                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
  5577                              <1> ;-------------------------------------------------------------------------------
  5578                              <1> DSK_STATUS:
  5579 000019CB 8825[7C6F0000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
  5580 000019D1 E8EA080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5581 000019D6 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5582 000019D9 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5583 000019DB C3                  <1> 	RETn		
  5584                              <1> 
  5585                              <1> ;-------------------------------------------------------------------------------
  5586                              <1> ; DISK_READ	(AH = 02H)	
  5587                              <1> ;	DISKETTE READ.
  5588                              <1> ;
  5589                              <1> ; ON ENTRY:	DI	: DRIVE #
  5590                              <1> ;		SI-HI	: HEAD #
  5591                              <1> ;		SI-LOW	: # OF SECTORS
  5592                              <1> ;		ES	: BUFFER SEGMENT
  5593                              <1> ;		[BP]	: SECTOR #
  5594                              <1> ;		[BP+1]	: TRACK #
  5595                              <1> ;		[BP+2]	: BUFFER OFFSET
  5596                              <1> ;
  5597                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5598                              <1> ;-------------------------------------------------------------------------------
  5599                              <1> 
  5600                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5601                              <1> 
  5602                              <1> DSK_READ:
  5603 000019DC 8025[7A6F0000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5604 000019E3 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
  5605 000019E7 E825040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5606 000019EC C3                  <1> 	RETn
  5607                              <1> 
  5608                              <1> ;-------------------------------------------------------------------------------
  5609                              <1> ; DISK_WRITE	(AH = 03H)
  5610                              <1> ;	DISKETTE WRITE.
  5611                              <1> ;
  5612                              <1> ; ON ENTRY:	DI	: DRIVE #
  5613                              <1> ;		SI-HI	: HEAD #
  5614                              <1> ;		SI-LOW	: # OF SECTORS
  5615                              <1> ;		ES	: BUFFER SEGMENT
  5616                              <1> ;		[BP]	: SECTOR #
  5617                              <1> ;		[BP+1]	: TRACK #
  5618                              <1> ;		[BP+2]	: BUFFER OFFSET
  5619                              <1> ;
  5620                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5621                              <1> ;-------------------------------------------------------------------------------
  5622                              <1> 
  5623                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5624                              <1> 
  5625                              <1> DSK_WRITE:
  5626 000019ED 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
  5627 000019F1 800D[7A6F0000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
  5628 000019F8 E814040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5629 000019FD C3                  <1> 	RETn
  5630                              <1> 
  5631                              <1> ;-------------------------------------------------------------------------------
  5632                              <1> ; DISK_VERF	(AH = 04H)
  5633                              <1> ;	DISKETTE VERIFY.
  5634                              <1> ;
  5635                              <1> ; ON ENTRY:	DI	: DRIVE #
  5636                              <1> ;		SI-HI	: HEAD #
  5637                              <1> ;		SI-LOW	: # OF SECTORS
  5638                              <1> ;		ES	: BUFFER SEGMENT
  5639                              <1> ;		[BP]	: SECTOR #
  5640                              <1> ;		[BP+1]	: TRACK #
  5641                              <1> ;		[BP+2]	: BUFFER OFFSET
  5642                              <1> ;
  5643                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5644                              <1> ;-------------------------------------------------------------------------------
  5645                              <1> DSK_VERF:
  5646 000019FE 8025[7A6F0000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5647 00001A05 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
  5648 00001A09 E803040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5649 00001A0E C3                  <1> 	RETn
  5650                              <1> 
  5651                              <1> ;-------------------------------------------------------------------------------
  5652                              <1> ; DISK_FORMAT	(AH = 05H)
  5653                              <1> ;	DISKETTE FORMAT.
  5654                              <1> ;
  5655                              <1> ; ON ENTRY:	DI	: DRIVE #
  5656                              <1> ;		SI-HI	: HEAD #
  5657                              <1> ;		SI-LOW	: # OF SECTORS
  5658                              <1> ;		ES	: BUFFER SEGMENT
  5659                              <1> ;		[BP]	: SECTOR #
  5660                              <1> ;		[BP+1]	: TRACK #
  5661                              <1> ;		[BP+2]	: BUFFER OFFSET
  5662                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
  5663                              <1> ;
  5664                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5665                              <1> ;-------------------------------------------------------------------------------
  5666                              <1> DSK_FORMAT:
  5667 00001A0F E83C030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5668 00001A14 E838050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
  5669 00001A19 800D[7A6F0000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
  5670 00001A20 E880050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
  5671 00001A25 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
  5672 00001A27 E8DB020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5673 00001A2C E8E6050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
  5674 00001A31 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
  5675 00001A33 E8BD050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
  5676                              <1> FM_WR:
  5677 00001A38 E873060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
  5678 00001A3D 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
  5679 00001A3F B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
  5680 00001A41 E8D0060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
  5681 00001A46 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
  5682 00001A48 B8[841A0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
  5683 00001A4D 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  5684 00001A4E B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
  5685 00001A50 E83F090000          <1> 	CALL	GET_PARM
  5686 00001A55 E8400A0000          <1> 	CALL	NEC_OUTPUT
  5687 00001A5A B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
  5688 00001A5C E833090000          <1> 	CALL	GET_PARM
  5689 00001A61 E8340A0000          <1> 	CALL	NEC_OUTPUT
  5690 00001A66 B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
  5691 00001A68 E827090000          <1> 	CALL	GET_PARM
  5692 00001A6D E8280A0000          <1> 	CALL	NEC_OUTPUT
  5693 00001A72 B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
  5694 00001A74 E81B090000          <1> 	CALL	GET_PARM
  5695 00001A79 E81C0A0000          <1> 	CALL	NEC_OUTPUT
  5696 00001A7E 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  5697 00001A7F E810070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
  5698                              <1> FM_DON:
  5699 00001A84 E8F8020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5700 00001A89 E832080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5701 00001A8E 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5702 00001A91 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5703 00001A93 C3                  <1> 	RETn
  5704                              <1> 
  5705                              <1> ;-------------------------------------------------------------------------------
  5706                              <1> ; FNC_ERR
  5707                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
  5708                              <1> ;	SET BAD COMMAND IN STATUS.
  5709                              <1> ;
  5710                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5711                              <1> ;-------------------------------------------------------------------------------
  5712                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
  5713 00001A94 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
  5714 00001A97 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  5715 00001A99 8825[7C6F0000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
  5716 00001A9F F9                  <1> 	STC				; SET CARRY INDICATING ERROR
  5717 00001AA0 C3                  <1> 	RETn
  5718                              <1> 
  5719                              <1> ;-------------------------------------------------------------------------------
  5720                              <1> ; DISK_PARMS	(AH = 08H)	
  5721                              <1> ;	READ DRIVE PARAMETERS.
  5722                              <1> ;
  5723                              <1> ; ON ENTRY:	DI : DRIVE #
  5724                              <1> ;
  5725                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
  5726                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
  5727                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
  5728                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
  5729                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
  5730                              <1> ;		BH/[BP+3] = 0
  5731                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
  5732                              <1> ;		DH/[BP+5] = MAX HEAD #
  5733                              <1> ;		DI/[BP+6] = OFFSET TO DISK_BASE
  5734                              <1> ;		ES        = SEGMENT OF DISK_BASE
  5735                              <1> ;		AX        = 0
  5736                              <1> ;
  5737                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
  5738                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
  5739                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
  5740                              <1> ;		       CALLER.
  5741                              <1> ;-------------------------------------------------------------------------------
  5742                              <1> DSK_PARMS:
  5743 00001AA1 E8AA020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  5744                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
  5745 00001AA6 29D2                <1> 	sub     edx, edx ; 20/02/2015
  5746 00001AA8 895504              <1>         mov	[ebp+4], edx ; 20/02/2015
  5747                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
  5748                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
  5749                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
  5750                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
  5751                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
  5752                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
  5753                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
  5754                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
  5755                              <1> 	;sub	edx, edx
  5756 00001AAB 66A1[EE690000]      <1> 	mov     ax, [fd0_type]
  5757 00001AB1 6621C0              <1> 	and     ax, ax
  5758 00001AB4 7474                <1> 	jz      short NON_DRV
  5759 00001AB6 FEC2                <1> 	inc     dl
  5760 00001AB8 20E4                <1> 	and     ah, ah
  5761 00001ABA 7402                <1> 	jz      short STO_DL
  5762 00001ABC FEC2                <1> 	inc     dl
  5763                              <1> STO_DL:
  5764                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
  5765 00001ABE 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
  5766 00001AC1 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
  5767 00001AC5 7766                <1> 	JA	short NON_DRV1		; DRIVE INVALID
  5768                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
  5769 00001AC7 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
  5770 00001ACB E8BB080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  5771                              <1> 	;;20/02/2015
  5772                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
  5773                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
  5774 00001AD0 7412                <1> 	JZ	short CHK_EST		; JUMP IF SO
  5775 00001AD2 E805020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5776 00001AD7 720B                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
  5777                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
  5778 00001AD9 884504              <1>         mov	[ebp+4], al ; 06/02/2015
  5779 00001ADC 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
  5780 00001ADF 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
  5781 00001AE2 EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
  5782                              <1> CHK_EST:
  5783 00001AE4 8AA7[896F0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
  5784 00001AEA F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
  5785 00001AED 743E                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
  5786                              <1> USE_EST:
  5787 00001AEF 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
  5788 00001AF2 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  5789 00001AF5 7557                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
  5790                              <1> 
  5791                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
  5792                              <1> 
  5793 00001AF7 B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
  5794 00001AF9 E8DE010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5795 00001AFE 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5796 00001B01 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5797 00001B04 F687[896F0000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
  5798 00001B0B 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
  5799                              <1> 
  5800                              <1> ;-----	IT IS 1.44 MB DRIVE
  5801                              <1> 
  5802                              <1> PARM144:
  5803 00001B0D B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
  5804 00001B0F E8C8010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5805 00001B14 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5806 00001B17 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5807                              <1> STO_CX:
  5808 00001B1A 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
  5809                              <1> ES_DI:
  5810                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
  5811 00001B1D 895D0C              <1> 	mov	[ebp+12], ebx ; 06/02/2015
  5812                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
  5813                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  5814                              <1> DP_OUT:
  5815 00001B20 E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5816 00001B25 6631C0              <1> 	XOR	AX,AX			; CLEAR
  5817 00001B28 F8                  <1> 	CLC
  5818 00001B29 C3                  <1> 	RETn
  5819                              <1> 
  5820                              <1> ;-----	NO DRIYE PRESENT HANDLER
  5821                              <1> 
  5822                              <1> NON_DRV:
  5823                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
  5824 00001B2A 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
  5825                              <1> NON_DRV1:
  5826 00001B2D 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
  5827 00001B32 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
  5828                              <1> 
  5829                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
  5830                              <1> 	
  5831 00001B34 E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
  5832 00001B39 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
  5833 00001B3C B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  5834 00001B3E F9                  <1> 	STC
  5835 00001B3F C3                  <1> 	RETn
  5836                              <1> 
  5837                              <1> NON_DRV2:
  5838                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
  5839 00001B40 31C0                <1> 	xor	eax, eax	
  5840 00001B42 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
  5841                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
  5842 00001B46 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
  5843                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
  5844 00001B49 89450C              <1> 	mov	[ebp+12], eax
  5845                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  5846 00001B4C EBD2                <1> 	JMP	SHORT DP_OUT
  5847                              <1> 
  5848                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
  5849                              <1> 
  5850                              <1> USE_EST2:
  5851 00001B4E B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
  5852 00001B50 E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5853 00001B55 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5854 00001B58 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5855 00001B5B 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  5856 00001B5E 74BA                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
  5857 00001B60 EBAB                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
  5858                              <1> 
  5859                              <1> ;-------------------------------------------------------------------------------
  5860                              <1> ; DISK_TYPE (AH = 15H)	
  5861                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
  5862                              <1> ;
  5863                              <1> ;  ON ENTRY:	DI = DRIVE #
  5864                              <1> ;
  5865                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
  5866                              <1> ;-------------------------------------------------------------------------------
  5867                              <1> DSK_TYPE:
  5868 00001B62 E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5869 00001B67 8A87[896F0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
  5870 00001B6D 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
  5871 00001B6F 7418                <1> 	JZ	short NO_DRV
  5872 00001B71 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
  5873 00001B73 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
  5874 00001B75 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
  5875 00001B77 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
  5876                              <1> DT_BACK:
  5877 00001B79 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
  5878 00001B7B E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5879 00001B80 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
  5880 00001B82 F8                  <1> 	CLC				; NO ERROR
  5881 00001B83 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5882 00001B86 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5883 00001B88 C3                  <1> 	RETn
  5884                              <1> NO_DRV:	
  5885 00001B89 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
  5886 00001B8B EBEC                <1> 	JMP	SHORT DT_BACK
  5887                              <1> 
  5888                              <1> ;-------------------------------------------------------------------------------
  5889                              <1> ; DISK_CHANGE	(AH = 16H)
  5890                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
  5891                              <1> ;
  5892                              <1> ; ON ENTRY:	DI = DRIVE #
  5893                              <1> ;
  5894                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
  5895                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
  5896                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
  5897                              <1> ;-------------------------------------------------------------------------------
  5898                              <1> DSK_CHANGE:
  5899 00001B8D E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5900 00001B92 8A87[896F0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  5901 00001B98 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  5902 00001B9A 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  5903 00001B9C A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  5904 00001B9E 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  5905                              <1> DC0:
  5906 00001BA0 E88D0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  5907 00001BA5 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  5908                              <1> 
  5909 00001BA7 C605[7C6F0000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  5910                              <1> 
  5911 00001BAE E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5912 00001BB3 E808070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5913 00001BB8 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5914 00001BBB 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5915 00001BBD C3                  <1> 	RETn
  5916                              <1> DC_NON:
  5917 00001BBE 800D[7C6F0000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  5918 00001BC5 EBE7                <1> 	JMP	SHORT FINIS
  5919                              <1> 
  5920                              <1> ;-------------------------------------------------------------------------------
  5921                              <1> ; FORMAT_SET	(AH = 17H)
  5922                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  5923                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  5924                              <1> ;
  5925                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  5926                              <1> ;		DI     = DRIVE #
  5927                              <1> ;
  5928                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  5929                              <1> ;		AH = @DSKETTE_STATUS
  5930                              <1> ;		CY = 1 IF ERROR
  5931                              <1> ;-------------------------------------------------------------------------------
  5932                              <1> FORMAT_SET:
  5933 00001BC7 E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5934 00001BCC 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  5935 00001BCE 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  5936 00001BD1 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  5937 00001BD3 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  5938 00001BD6 80A7[896F0000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  5939 00001BDD 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  5940 00001BDF 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  5941 00001BE1 808F[896F0000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  5942 00001BE8 EB48                <1> 	JMP	SHORT S0
  5943                              <1> 
  5944                              <1> NOT_320:
  5945 00001BEA E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  5946 00001BEF 803D[7C6F0000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  5947 00001BF6 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  5948                              <1> S3:
  5949 00001BF8 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  5950 00001BFA 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  5951 00001BFC 808F[896F0000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  5952 00001C03 EB2D                <1> 	JMP	SHORT S0
  5953                              <1> 
  5954                              <1> NOT_320_12:
  5955 00001C05 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  5956 00001C07 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  5957 00001C09 808F[896F0000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  5958 00001C10 EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  5959                              <1> 
  5960                              <1> NOT_12:	
  5961 00001C12 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  5962 00001C14 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  5963                              <1> 
  5964 00001C16 F687[896F0000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  5965 00001C1D 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  5966 00001C1F B050                <1> 	MOV	AL,MED_DET+RATE_300
  5967 00001C21 F687[896F0000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  5968 00001C28 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  5969                              <1> 
  5970                              <1> ASSUME:
  5971 00001C2A B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  5972                              <1> 
  5973                              <1> OR_IT_IN:
  5974 00001C2C 0887[896F0000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  5975                              <1> S0:
  5976 00001C32 E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5977 00001C37 E884060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5978 00001C3C 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  5979 00001C3E 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5980 00001C40 C3                  <1> 	RETn
  5981                              <1> 
  5982                              <1> FS_ERR:
  5983 00001C41 C605[7C6F0000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  5984 00001C48 EBE8                <1> 	JMP	SHORT S0
  5985                              <1> 
  5986                              <1> ;-------------------------------------------------------------------------------
  5987                              <1> ; SET_MEDIA	(AH = 18H)
  5988                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  5989                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  5990                              <1> ;
  5991                              <1> ; ON ENTRY:
  5992                              <1> ;	[BP]	= SECTOR PER TRACK
  5993                              <1> ;	[BP+1]	= TRACK #
  5994                              <1> ;	DI	= DRIVE #
  5995                              <1> ;
  5996                              <1> ; ON EXIT:
  5997                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  5998                              <1> ;	IF NO ERROR:
  5999                              <1> ;		AH = 0
  6000                              <1> ;		CY = 0
  6001                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  6002                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  6003                              <1> ;	IF ERROR:	
  6004                              <1> ;		AH = @DSKETTE_STATUS
  6005                              <1> ;		CY = 1
  6006                              <1> ;-------------------------------------------------------------------------------
  6007                              <1> SET_MEDIA:
  6008 00001C4A E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6009 00001C4F F687[896F0000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  6010 00001C56 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  6011 00001C58 E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  6012 00001C5D 803D[7C6F0000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  6013 00001C64 746B                <1> 	JE	short SM_RTN
  6014 00001C66 C605[7C6F0000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  6015                              <1> SM_CMOS:
  6016 00001C6D E819070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6017                              <1> 	;;20/02/2015
  6018                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  6019                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  6020 00001C72 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  6021 00001C74 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  6022 00001C79 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  6023 00001C7B 57                  <1> 	PUSH	eDI			; SAVE REG.
  6024 00001C7C 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  6025 00001C7E B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6026                              <1> DR_SEARCH:
  6027 00001C83 8AA3[6C690000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  6028 00001C89 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  6029 00001C8C 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  6030 00001C8E 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  6031                              <1> DR_FND:
  6032 00001C90 8BBB[6D690000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  6033                              <1> MD_SEARCH:
  6034 00001C96 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  6035 00001C99 386500              <1> 	CMP	[eBP],AH		; MATCH?
  6036 00001C9C 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  6037 00001C9E 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  6038 00001CA1 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  6039 00001CA4 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  6040                              <1> NXT_MD:
  6041                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6042 00001CA6 83C305              <1>         add	ebx, 5 ; 18/02/2015
  6043 00001CA9 E2D8                <1> 	LOOP    DR_SEARCH
  6044 00001CAB 5F                  <1> 	POP	eDI			; RESTORE REG.
  6045                              <1> MD_NOT_FND:
  6046 00001CAC C605[7C6F0000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  6047 00001CB3 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  6048                              <1> MD_FND:
  6049 00001CB5 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  6050 00001CB8 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  6051 00001CBA 7502                <1> 	JNE	short MD_SET
  6052 00001CBC 0C20                <1> 	OR	AL,DBL_STEP
  6053                              <1> MD_SET:
  6054                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  6055 00001CBE 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  6056 00001CC1 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  6057 00001CC3 5F                  <1> 	POP	eDI
  6058 00001CC4 80A7[896F0000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  6059 00001CCB 0887[896F0000]      <1> 	OR	[DSK_STATE+eDI], AL
  6060                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  6061                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  6062                              <1> SM_RTN:
  6063 00001CD1 E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6064 00001CD6 E8E5050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6065 00001CDB C3                  <1> 	RETn
  6066                              <1> 
  6067                              <1> ;----------------------------------------------------------------
  6068                              <1> ; DR_TYPE_CHECK							:
  6069                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  6070                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  6071                              <1> ; ON ENTRY:							:
  6072                              <1> ;	AL = DRIVE TYPE						:
  6073                              <1> ; ON EXIT:							:
  6074                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  6075                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  6076                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  6077                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  6078                              <1> ; REGISTERS ALTERED: eBX						:
  6079                              <1> ;----------------------------------------------------------------		
  6080                              <1> DR_TYPE_CHECK:
  6081 00001CDC 6650                <1> 	PUSH	AX			
  6082 00001CDE 51                  <1> 	PUSH	eCX
  6083 00001CDF 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6084 00001CE1 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6085                              <1> TYPE_CHK:	
  6086 00001CE6 8AA3[6C690000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  6087 00001CEC 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6088 00001CEE 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  6089                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6090 00001CF0 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  6091 00001CF3 E2F1                <1> 	LOOP    TYPE_CHK
  6092                              <1> 	;
  6093 00001CF5 BB[CB690000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  6094                              <1> 					; Default for GET_PARM (11/12/2014)
  6095                              <1> 	;
  6096 00001CFA F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  6097 00001CFB EB06                <1> 	JMP	SHORT TYPE_RTN
  6098                              <1> DR_TYPE_VALID:
  6099 00001CFD 8B9B[6D690000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  6100                              <1> TYPE_RTN:
  6101 00001D03 59                  <1> 	POP	eCX
  6102 00001D04 6658                <1> 	POP	AX
  6103 00001D06 C3                  <1> 	RETn	
  6104                              <1> 		
  6105                              <1> ;----------------------------------------------------------------
  6106                              <1> ; SEND_SPEC							:
  6107                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6108                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  6109                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  6110                              <1> ; ON EXIT:	NONE						:	
  6111                              <1> ; REGISTERS ALTERED: CX, DX					:
  6112                              <1> ;----------------------------------------------------------------		
  6113                              <1> SEND_SPEC:
  6114 00001D07 50                  <1> 	PUSH	eAX			; SAVE AX
  6115 00001D08 B8[2E1D0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  6116 00001D0D 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6117 00001D0E B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6118 00001D10 E885070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6119 00001D15 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  6120 00001D17 E878060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6121 00001D1C E879070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6122 00001D21 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  6123 00001D23 E86C060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6124 00001D28 E86D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6125 00001D2D 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6126                              <1> SPECBAC:
  6127 00001D2E 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6128 00001D2F C3                  <1> 	RETn
  6129                              <1> 
  6130                              <1> ;----------------------------------------------------------------
  6131                              <1> ; SEND_SPEC_MD							:
  6132                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6133                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  6134                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  6135                              <1> ; ON EXIT:	NONE						:	
  6136                              <1> ; REGISTERS ALTERED: AX						:
  6137                              <1> ;----------------------------------------------------------------		
  6138                              <1> SEND_SPEC_MD:
  6139 00001D30 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  6140 00001D31 B8[4E1D0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  6141 00001D36 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6142 00001D37 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6143 00001D39 E85C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6144 00001D3E 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  6145 00001D40 E855070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6146 00001D45 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  6147 00001D48 E84D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6148 00001D4D 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6149                              <1> SPEC_ESBAC:
  6150 00001D4E 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6151 00001D4F C3                  <1> 	RETn
  6152                              <1> 
  6153                              <1> ;-------------------------------------------------------------------------------
  6154                              <1> ; XLAT_NEW  
  6155                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  6156                              <1> ;	MODE TO NEW ARCHITECTURE.
  6157                              <1> ;
  6158                              <1> ; ON ENTRY:	DI = DRIVE #
  6159                              <1> ;-------------------------------------------------------------------------------
  6160                              <1> XLAT_NEW:
  6161 00001D50 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  6162 00001D53 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  6163 00001D55 80BF[896F0000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  6164 00001D5C 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  6165 00001D5E 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  6166 00001D61 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  6167 00001D64 A0[886F0000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  6168 00001D69 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  6169 00001D6B 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  6170 00001D6D 80A7[896F0000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  6171 00001D74 0887[896F0000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  6172                              <1> XN_OUT:
  6173 00001D7A C3                  <1> 	RETn
  6174                              <1> DO_DET:
  6175 00001D7B E8BF080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  6176 00001D80 C3                  <1> 	RETn
  6177                              <1> 
  6178                              <1> ;-------------------------------------------------------------------------------
  6179                              <1> ; XLAT_OLD 
  6180                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  6181                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  6182                              <1> ;
  6183                              <1> ; ON ENTRY:	DI = DRIVE
  6184                              <1> ;-------------------------------------------------------------------------------
  6185                              <1> XLAT_OLD:
  6186 00001D81 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  6187                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  6188 00001D84 0F8786000000        <1>         ja      XO_OUT
  6189 00001D8A 80BF[896F0000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  6190 00001D91 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  6191                              <1> 
  6192                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  6193                              <1> 
  6194 00001D93 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  6195 00001D96 C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  6196 00001D99 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  6197 00001D9B D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  6198 00001D9D 8425[886F0000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  6199 00001DA3 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  6200                              <1> 
  6201                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  6202                              <1> 
  6203 00001DA5 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  6204 00001DA7 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  6205 00001DA9 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  6206 00001DAB 2025[886F0000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  6207                              <1> 
  6208                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  6209                              <1> 
  6210 00001DB1 8A87[896F0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  6211 00001DB7 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  6212 00001DB9 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  6213 00001DBB 0805[886F0000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  6214                              <1> 
  6215                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  6216                              <1> 
  6217                              <1> SAVE_SET:
  6218 00001DC1 8AA7[896F0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  6219 00001DC7 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  6220 00001DC9 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  6221 00001DCC 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  6222 00001DCF 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  6223 00001DD1 B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  6224 00001DD3 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  6225 00001DD6 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  6226 00001DD8 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  6227 00001DDB 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  6228                              <1> UNKNO:
  6229 00001DDD B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  6230 00001DDF EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  6231                              <1> CHK_144:
  6232 00001DE1 E8A5050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6233                              <1> 	;;20/02/2015
  6234                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  6235 00001DE6 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  6236 00001DE8 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  6237 00001DEA 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  6238 00001DEC B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  6239 00001DEE EB0C                <1> 	JMP	SHORT TST_DET
  6240                              <1> CHK_250:
  6241 00001DF0 B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  6242 00001DF2 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  6243 00001DF5 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  6244 00001DF7 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  6245 00001DFA 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  6246                              <1> TST_DET:
  6247 00001DFC F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  6248 00001DFF 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  6249 00001E01 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  6250                              <1> AL_SET:
  6251 00001E03 80A7[896F0000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  6252 00001E0A 0887[896F0000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  6253                              <1> XO_OUT:
  6254 00001E10 C3                  <1> 	RETn
  6255                              <1> 
  6256                              <1> ;-------------------------------------------------------------------------------
  6257                              <1> ; RD_WR_VF
  6258                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  6259                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  6260                              <1> ;
  6261                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  6262                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  6263                              <1> ;
  6264                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6265                              <1> ;-------------------------------------------------------------------------------
  6266                              <1> RD_WR_VF:
  6267 00001E11 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  6268 00001E13 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6269 00001E18 E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  6270 00001E1D 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  6271                              <1> DO_AGAIN:
  6272 00001E1F 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6273 00001E21 E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  6274 00001E26 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  6275 00001E28 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  6276                              <1> RWV:
  6277 00001E2E 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6278 00001E30 8AB7[896F0000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6279 00001E36 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  6280 00001E39 E84D050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  6281                              <1> 	;;20/02/2015
  6282                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  6283 00001E3E 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  6284 00001E40 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  6285 00001E42 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  6286 00001E44 F687[896F0000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  6287 00001E4B 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  6288 00001E4D B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  6289 00001E4F EB0F                <1> 	JMP	SHORT RWV_2
  6290                              <1> RWV_1:
  6291 00001E51 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  6292 00001E53 F687[896F0000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  6293 00001E5A 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  6294 00001E5C B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  6295 00001E5E EB04                <1> 	jmp	short rwv_3
  6296                              <1> RWV_2:
  6297 00001E60 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  6298 00001E62 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  6299                              <1> rwv_3:
  6300 00001E64 E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  6301 00001E69 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  6302                              <1> 
  6303                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  6304                              <1> 
  6305 00001E6B 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  6306 00001E6C 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6307 00001E6E B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6308                              <1> RWV_DR_SEARCH:
  6309 00001E73 8AA3[6C690000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  6310 00001E79 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  6311 00001E7C 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6312 00001E7E 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  6313                              <1> RWV_DR_FND:
  6314 00001E80 8BBB[6D690000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  6315                              <1> RWV_MD_SEARH:
  6316 00001E86 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  6317 00001E89 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  6318                              <1> RWV_NXT_MD:
  6319                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6320 00001E8B 83C305              <1> 	add	eBX, 5
  6321 00001E8E E2E3                <1> 	LOOP	RWV_DR_SEARCH
  6322 00001E90 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6323                              <1> 
  6324                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  6325                              <1> 
  6326                              <1> RWV_ASSUME:
  6327 00001E91 BB[8A690000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  6328 00001E96 F687[896F0000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  6329 00001E9D 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  6330 00001E9F BB[A4690000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  6331 00001EA4 EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  6332                              <1> 
  6333                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  6334                              <1> 	 			
  6335                              <1> RWV_MD_FND:
  6336 00001EA6 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  6337 00001EA8 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6338                              <1> 	
  6339                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  6340                              <1> 
  6341                              <1> RWV_MD_FND1:
  6342 00001EA9 E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  6343 00001EAE E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  6344 00001EB3 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  6345 00001EB5 E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  6346                              <1> RWV_DBL:
  6347 00001EBA 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6348 00001EBB E822040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  6349 00001EC0 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6350 00001EC1 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  6351 00001EC3 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  6352 00001EC5 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6353 00001EC7 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6354 00001EC8 E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  6355 00001ECD 5B                  <1> 	POP	eBX 
  6356 00001ECE 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  6357 00001ED0 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  6358 00001ED2 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6359 00001ED4 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6360 00001ED5 E83C020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  6361 00001EDA 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6362 00001EDB 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6363 00001EDD E866020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  6364 00001EE2 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6365 00001EE4 E8AB020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  6366                              <1> CHK_RET:
  6367 00001EE9 E84A030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  6368 00001EEE 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  6369 00001EF0 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  6370 00001EF2 E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  6371                              <1> RWV_END:
  6372 00001EF7 E8F4020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  6373 00001EFC E887030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  6374                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  6375 00001F01 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  6376 00001F03 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6377 00001F08 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  6378 00001F0A E8B1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6379 00001F0F C3                  <1> 	RETn
  6380                              <1> 
  6381                              <1> ;-------------------------------------------------------------------------------
  6382                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  6383                              <1> ;-------------------------------------------------------------------------------
  6384                              <1> SETUP_STATE:
  6385 00001F10 F687[896F0000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  6386 00001F17 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  6387 00001F19 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  6388 00001F1D F687[896F0000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  6389 00001F24 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  6390 00001F26 F687[896F0000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  6391 00001F2D 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  6392 00001F2F 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  6393                              <1> AX_SET:	
  6394 00001F33 80A7[896F0000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  6395 00001F3A 08A7[896F0000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  6396 00001F40 8025[846F0000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  6397 00001F47 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  6398 00001F4A 0805[846F0000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  6399                              <1> J1C:	
  6400 00001F50 C3                  <1> 	RETn
  6401                              <1> 
  6402                              <1> ;-------------------------------------------------------------------------------
  6403                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  6404                              <1> ;-------------------------------------------------------------------------------
  6405                              <1> FMT_INIT:
  6406 00001F51 F687[896F0000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  6407 00001F58 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  6408 00001F5A E82C040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  6409                              <1> 	;; 20/02/2015
  6410                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  6411 00001F5F 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  6412 00001F61 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  6413                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  6414 00001F63 8AA7[896F0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  6415 00001F69 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  6416 00001F6C 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  6417 00001F6E 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  6418 00001F70 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  6419 00001F73 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6420                              <1> N_360:	
  6421 00001F75 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  6422 00001F77 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  6423                              <1> F1_RATE:
  6424 00001F79 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  6425 00001F7C EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6426                              <1> N_12:	
  6427 00001F7E FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  6428 00001F80 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  6429 00001F82 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  6430 00001F85 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  6431 00001F87 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  6432 00001F8A 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  6433 00001F8C 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  6434 00001F8F EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  6435                              <1> N_720:
  6436 00001F91 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  6437 00001F93 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  6438 00001F95 EBE2                <1> 	JMP	SHORT F1_RATE
  6439                              <1> ISNT_12: 
  6440 00001F97 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  6441                              <1> 
  6442                              <1> SKP_STATE:
  6443 00001F9A 88A7[896F0000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  6444                              <1> F1_OUT:
  6445 00001FA0 C3                  <1> 	RETn
  6446                              <1> CL_DRV:	
  6447 00001FA1 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  6448 00001FA3 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  6449                              <1> 
  6450                              <1> ;-------------------------------------------------------------------------------
  6451                              <1> ; MED_CHANGE	
  6452                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  6453                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  6454                              <1> ;
  6455                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  6456                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  6457                              <1> ;-------------------------------------------------------------------------------
  6458                              <1> MED_CHANGE:
  6459 00001FA5 E888060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  6460 00001FAA 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  6461 00001FAC 80A7[896F0000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  6462                              <1> 
  6463                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  6464                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  6465                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  6466                              <1> 
  6467 00001FB3 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  6468 00001FB6 B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  6469 00001FB8 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  6470 00001FBA F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  6471 00001FBC FA                  <1> 	CLI				; NO INTERRUPTS
  6472 00001FBD 2005[7A6F0000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  6473 00001FC3 FB                  <1> 	STI				; INTERRUPTS ENABLED
  6474 00001FC4 E810040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  6475                              <1> 
  6476                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  6477                              <1> 
  6478 00001FC9 E884F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  6479 00001FCE B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  6480 00001FD0 E8FF040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6481 00001FD5 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  6482 00001FD7 E8F8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6483 00001FDC C605[7C6F0000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  6484                              <1> OK1:
  6485 00001FE3 E84A060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  6486 00001FE8 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  6487                              <1> OK4:
  6488 00001FEA C605[7C6F0000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  6489                              <1> OK2:		
  6490 00001FF1 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  6491 00001FF2 C3                  <1> 	RETn
  6492                              <1> MC_OUT:
  6493 00001FF3 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  6494 00001FF4 C3                  <1> 	RETn
  6495                              <1> 
  6496                              <1> ;-------------------------------------------------------------------------------
  6497                              <1> ; SEND_RATE
  6498                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  6499                              <1> ; ON ENTRY:	DI = DRIVE #
  6500                              <1> ; ON EXIT:	NONE
  6501                              <1> ; REGISTERS ALTERED: DX
  6502                              <1> ;-------------------------------------------------------------------------------
  6503                              <1> SEND_RATE:
  6504 00001FF5 6650                <1> 	PUSH	AX			; SAVE REG.
  6505 00001FF7 8025[846F0000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  6506 00001FFE 8A87[896F0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6507 00002004 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  6508 00002006 0805[846F0000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  6509 0000200C C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  6510 0000200F 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  6511 00002013 EE                  <1> 	OUT	DX,AL
  6512 00002014 6658                <1> 	POP	AX			; RESTORE REG.
  6513 00002016 C3                  <1> 	RETn
  6514                              <1> 
  6515                              <1> ;-------------------------------------------------------------------------------
  6516                              <1> ; CHK_LASTRATE
  6517                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  6518                              <1> ; ON ENTRY:
  6519                              <1> ;	DI = DRIVE #
  6520                              <1> ; ON EXIT:
  6521                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  6522                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  6523                              <1> ; REGISTERS ALTERED: DX
  6524                              <1> ;-------------------------------------------------------------------------------
  6525                              <1> CHK_LASTRATE:
  6526 00002017 6650                <1> 	PUSH	AX			; SAVE REG
  6527 00002019 2225[846F0000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  6528 0000201F 8A87[896F0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6529 00002025 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  6530 00002029 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  6531                              <1> 					; ZF = 1 RATE IS THE SAME
  6532 0000202B 6658                <1> 	POP	AX			; RESTORE REG.
  6533 0000202D C3                  <1> 	RETn
  6534                              <1> 
  6535                              <1> ;-------------------------------------------------------------------------------
  6536                              <1> ; DMA_SETUP
  6537                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  6538                              <1> ;
  6539                              <1> ; ON ENTRY:	AL = DMA COMMAND
  6540                              <1> ;
  6541                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6542                              <1> ;-------------------------------------------------------------------------------
  6543                              <1> 
  6544                              <1> ; SI = Head #, # of Sectors or DASD Type
  6545                              <1> 
  6546                              <1> ; 22/08/2015
  6547                              <1> ; 08/02/2015 - Protected Mode Modification
  6548                              <1> ; 06/02/2015 - 07/02/2015
  6549                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  6550                              <1> ; (DMA Addres = Physical Address)
  6551                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  6552                              <1> ;
  6553                              <1> ; 04/02/2016 (clc)
  6554                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  6555                              <1> ; 16/12/2014 (IODELAY)
  6556                              <1> 
  6557                              <1> DMA_SETUP:
  6558                              <1> 
  6559                              <1> ;; 20/02/2015
  6560 0000202E 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6561 00002031 F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  6562 00002037 756E                <1> 	jnz	short dma_bnd_err_stc
  6563                              <1> 	;
  6564 00002039 6650                <1> 	push	ax			; DMA command
  6565 0000203B 52                  <1> 	push	edx			; *
  6566 0000203C B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  6567 0000203E E851030000          <1> 	call	GET_PARM		; 
  6568 00002043 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6569 00002045 6689F0              <1> 	mov	ax, si			; Sector count
  6570 00002048 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  6571 0000204A 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  6572 0000204C 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  6573 0000204F 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  6574 00002052 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  6575 00002054 6689C1              <1> 	mov	cx, ax
  6576 00002057 5A                  <1> 	pop	edx			; *
  6577 00002058 6658                <1> 	pop	ax
  6578 0000205A 3C42                <1> 	cmp	al, 42h
  6579 0000205C 7507                <1>         jne     short NOT_VERF
  6580 0000205E BA0000FF00          <1> 	mov	edx, 0FF0000h
  6581 00002063 EB08                <1> 	jmp	short J33
  6582                              <1> NOT_VERF:
  6583 00002065 6601CA              <1> 	add	dx, cx			; check for overflow
  6584 00002068 723E                <1> 	jc	short dma_bnd_err
  6585                              <1> 	;
  6586 0000206A 6629CA              <1> 	sub	dx, cx			; Restore start address
  6587                              <1> J33:
  6588 0000206D FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6589 0000206E E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6590                              <1> 	IODELAY				; WAIT FOR I/O
  6591 00002070 EB00                <2>  jmp short $+2
  6592 00002072 EB00                <2>  jmp short $+2
  6593 00002074 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6594 00002076 89D0                <1> 	mov	eax, edx		; Buffer address
  6595 00002078 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6596                              <1> 	IODELAY				; WAIT FOR I/O
  6597 0000207A EB00                <2>  jmp short $+2
  6598 0000207C EB00                <2>  jmp short $+2
  6599 0000207E 88E0                <1> 	MOV	AL,AH
  6600 00002080 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6601 00002082 C1E810              <1> 	shr	eax, 16
  6602                              <1> 	IODELAY				; I/O WAIT STATE
  6603 00002085 EB00                <2>  jmp short $+2
  6604 00002087 EB00                <2>  jmp short $+2
  6605 00002089 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6606                              <1> 	IODELAY
  6607 0000208B EB00                <2>  jmp short $+2
  6608 0000208D EB00                <2>  jmp short $+2
  6609 0000208F 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  6610 00002092 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6611                              <1> 	IODELAY				; WAIT FOR I/O
  6612 00002094 EB00                <2>  jmp short $+2
  6613 00002096 EB00                <2>  jmp short $+2
  6614 00002098 88E0                <1> 	MOV	AL, AH
  6615 0000209A E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6616                              <1> 	IODELAY
  6617 0000209C EB00                <2>  jmp short $+2
  6618 0000209E EB00                <2>  jmp short $+2
  6619 000020A0 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6620 000020A1 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  6621 000020A3 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6622                              <1> 
  6623 000020A5 F8                  <1> 	clc	; 04/02/2016
  6624 000020A6 C3                  <1> 	retn
  6625                              <1> 
  6626                              <1> dma_bnd_err_stc:
  6627 000020A7 F9                  <1> 	stc
  6628                              <1> dma_bnd_err:
  6629 000020A8 C605[7C6F0000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6630 000020AF C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  6631                              <1> 
  6632                              <1> ;; 16/12/2014
  6633                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6634                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6635                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6636                              <1> ;;	IODELAY
  6637                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6638                              <1> ;;	;SIODELAY
  6639                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  6640                              <1> ;;      ;JNE	short NOT_VERF		; NO
  6641                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  6642                              <1> ;;      ;JMP	SHORT J33
  6643                              <1> ;;;NOT_VERF:	
  6644                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  6645                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  6646                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  6647                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  6648                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  6649                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  6650                              <1> ;;	;JNC	short J33
  6651                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  6652                              <1> ;;;J33:
  6653                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  6654                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6655                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6656                              <1> ;;	IODELAY
  6657                              <1> ;;	MOV	AL,AH
  6658                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6659                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  6660                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  6661                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  6662                              <1> ;;	IODELAY
  6663                              <1> ;;	;AND	AL,00001111B
  6664                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  6665                              <1> ;;	;SIODELAY
  6666                              <1> ;;
  6667                              <1> ;;;----- DETERMINE COUNT
  6668                              <1> ;;	sub	eax, eax ; 08/02/2015
  6669                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  6670                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  6671                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  6672                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  6673                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  6674                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  6675                              <1> ;;	CALL	GET_PARM		; "
  6676                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6677                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  6678                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  6679                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  6680                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  6681                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6682                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6683                              <1> ;;	IODELAY
  6684                              <1> ;;	MOV	AL, AH
  6685                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6686                              <1> ;;	;IODELAY
  6687                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  6688                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  6689                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  6690                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  6691                              <1> ;;	add	ecx, eax ; 08/02/2015
  6692                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  6693                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6694                              <1> ;;	SIODELAY
  6695                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6696                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  6697                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  6698                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  6699                              <1> ;;	jz	short NO_BAD
  6700                              <1> ;;dma_bnd_err:
  6701                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6702                              <1> ;;NO_BAD:
  6703                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  6704                              <1> 
  6705                              <1> ;-------------------------------------------------------------------------------
  6706                              <1> ; FMTDMA_SET
  6707                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  6708                              <1> ;
  6709                              <1> ; ON ENTRY:	NOTHING REQUIRED
  6710                              <1> ;
  6711                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6712                              <1> ;-------------------------------------------------------------------------------
  6713                              <1> 
  6714                              <1> FMTDMA_SET:
  6715                              <1> ;; 20/02/2015 modification	
  6716 000020B0 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6717 000020B3 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  6718 000020B9 75EC                <1> 	jnz	short dma_bnd_err_stc
  6719                              <1> 	;
  6720 000020BB 6652                <1> 	push	dx			; *
  6721 000020BD B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  6722 000020BF E8D0020000          <1> 	call	GET_PARM		; "
  6723 000020C4 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  6724 000020C6 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  6725 000020C8 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  6726 000020CC 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  6727 000020CE 6689C1              <1> 	mov	cx, ax
  6728 000020D1 665A                <1> 	pop	dx			; *
  6729 000020D3 6601CA              <1> 	add	dx, cx			; check for overflow
  6730 000020D6 72D0                <1> 	jc	short dma_bnd_err
  6731                              <1> 	;
  6732 000020D8 6629CA              <1> 	sub	dx, cx			; Restore start address
  6733                              <1> 	;
  6734 000020DB B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  6735 000020DD FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6736 000020DE E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6737                              <1> 	IODELAY				; WAIT FOR I/O
  6738 000020E0 EB00                <2>  jmp short $+2
  6739 000020E2 EB00                <2>  jmp short $+2
  6740 000020E4 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6741 000020E6 89D0                <1> 	mov	eax, edx		; Buffer address
  6742 000020E8 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6743                              <1> 	IODELAY				; WAIT FOR I/O
  6744 000020EA EB00                <2>  jmp short $+2
  6745 000020EC EB00                <2>  jmp short $+2
  6746 000020EE 88E0                <1> 	MOV	AL,AH
  6747 000020F0 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6748 000020F2 C1E810              <1> 	shr	eax, 16
  6749                              <1> 	IODELAY				; I/O WAIT STATE
  6750 000020F5 EB00                <2>  jmp short $+2
  6751 000020F7 EB00                <2>  jmp short $+2
  6752 000020F9 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6753                              <1> 	IODELAY
  6754 000020FB EB00                <2>  jmp short $+2
  6755 000020FD EB00                <2>  jmp short $+2
  6756 000020FF 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  6757 00002102 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6758                              <1> 	IODELAY				; WAIT FOR I/O
  6759 00002104 EB00                <2>  jmp short $+2
  6760 00002106 EB00                <2>  jmp short $+2
  6761 00002108 88E0                <1> 	MOV	AL, AH
  6762 0000210A E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6763                              <1> 	IODELAY
  6764 0000210C EB00                <2>  jmp short $+2
  6765 0000210E EB00                <2>  jmp short $+2
  6766 00002110 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6767 00002111 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  6768 00002113 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6769 00002115 C3                  <1> 	retn
  6770                              <1> 
  6771                              <1> ;; 08/02/2015 - Protected Mode Modification
  6772                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  6773                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6774                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6775                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6776                              <1> ;;	IODELAY
  6777                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6778                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  6779                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  6780                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  6781                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  6782                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  6783                              <1> ;;	;JNC	short J33A
  6784                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  6785                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  6786                              <1> ;;;J33A:
  6787                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  6788                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6789                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6790                              <1> ;;	IODELAY
  6791                              <1> ;;	MOV	AL,AH
  6792                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6793                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  6794                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  6795                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  6796                              <1> ;;	IODELAY
  6797                              <1> ;;	;AND	AL,00001111B
  6798                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  6799                              <1> ;;
  6800                              <1> ;;;----- DETERMINE COUNT
  6801                              <1> ;;	sub	eax, eax ; 08/02/2015
  6802                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  6803                              <1> ;;	CALL	GET_PARM		; "
  6804                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  6805                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  6806                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  6807                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  6808                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  6809                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6810                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6811                              <1> ;;	IODELAY
  6812                              <1> ;;	MOV	AL, AH
  6813                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6814                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  6815                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  6816                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  6817                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  6818                              <1> ;;	add	ecx, eax ; 08/02/2015
  6819                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  6820                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6821                              <1> ;;	SIODELAY
  6822                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6823                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  6824                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  6825                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  6826                              <1> ;;	jz	short FMTDMA_OK
  6827                              <1> ;;	stc	; 20/02/2015
  6828                              <1> ;;fmtdma_bnd_err:
  6829                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6830                              <1> ;;FMTDMA_OK:
  6831                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  6832                              <1> 
  6833                              <1> ;-------------------------------------------------------------------------------
  6834                              <1> ; NEC_INIT	
  6835                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  6836                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  6837                              <1> ;
  6838                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  6839                              <1> ;
  6840                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6841                              <1> ;-------------------------------------------------------------------------------
  6842                              <1> NEC_INIT:
  6843 00002116 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6844 00002118 E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  6845                              <1> 
  6846                              <1> ;-----	DO THE SEEK OPERATION
  6847                              <1> 
  6848 0000211D 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  6849 00002120 E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  6850 00002125 6658                <1> 	POP	AX			; RECOVER COMMAND
  6851 00002127 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  6852 00002129 BB[47210000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  6853 0000212E 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  6854                              <1> 
  6855                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  6856                              <1> 
  6857 0000212F E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  6858 00002134 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  6859 00002137 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  6860 00002139 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  6861 0000213C 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  6862 0000213F 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  6863 00002141 E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  6864 00002146 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  6865                              <1> ER_1:
  6866 00002147 C3                  <1> 	RETn
  6867                              <1> 
  6868                              <1> ;-------------------------------------------------------------------------------
  6869                              <1> ; RWV_COM
  6870                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  6871                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  6872                              <1> ;
  6873                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  6874                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6875                              <1> ;-------------------------------------------------------------------------------
  6876                              <1> RWV_COM:
  6877 00002148 B8[93210000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  6878 0000214D 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6879 0000214E 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  6880 00002151 E844030000          <1> 	CALL	NEC_OUTPUT
  6881 00002156 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  6882 00002159 E83C030000          <1> 	CALL	NEC_OUTPUT
  6883 0000215E 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  6884 00002161 E834030000          <1> 	CALL	NEC_OUTPUT
  6885 00002166 B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  6886 00002168 E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  6887 0000216D E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6888 00002172 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  6889 00002174 E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  6890 00002179 E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6891 0000217E 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  6892                              <1> _R15:
  6893 00002181 E814030000          <1> 	CALL	NEC_OUTPUT
  6894 00002186 B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  6895 00002188 E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  6896 0000218D E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6897 00002192 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  6898                              <1> ER_2:
  6899 00002193 C3                  <1> 	RETn
  6900                              <1> 
  6901                              <1> ;-------------------------------------------------------------------------------
  6902                              <1> ; NEC_TERM
  6903                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  6904                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  6905                              <1> ;
  6906                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6907                              <1> ;-------------------------------------------------------------------------------
  6908                              <1> NEC_TERM:
  6909                              <1> 
  6910                              <1> ;-----	LET THE OPERATION HAPPEN
  6911                              <1> 
  6912 00002194 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  6913 00002195 E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  6914 0000219A 9C                  <1> 	PUSHF
  6915 0000219B E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  6916 000021A0 724B                <1> 	JC	short SET_END_POP
  6917 000021A2 9D                  <1> 	POPF
  6918 000021A3 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  6919                              <1> 
  6920                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  6921                              <1> 
  6922 000021A5 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  6923 000021A6 BE[7D6F0000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  6924 000021AB AC                  <1> 	lodsb				; GET ST0
  6925 000021AC 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  6926 000021AE 7433                <1> 	JZ	short SET_END
  6927 000021B0 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  6928 000021B2 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  6929                              <1> 
  6930                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  6931                              <1> 
  6932 000021B4 AC                  <1> 	lodsb				; GET ST1
  6933 000021B5 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  6934 000021B7 B404                <1> 	MOV	AH,RECORD_NOT_FND
  6935 000021B9 7222                <1> 	JC	short J19
  6936 000021BB C0E002              <1> 	SAL	AL,2
  6937 000021BE B410                <1> 	MOV	AH,BAD_CRC
  6938 000021C0 721B                <1> 	JC	short J19
  6939 000021C2 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  6940 000021C4 B408                <1> 	MOV	AH,BAD_DMA
  6941 000021C6 7215                <1> 	JC	short J19
  6942 000021C8 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  6943 000021CB B404                <1> 	MOV	AH,RECORD_NOT_FND
  6944 000021CD 720E                <1> 	JC	short J19
  6945 000021CF D0E0                <1> 	SAL	AL,1
  6946 000021D1 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  6947 000021D3 7208                <1> 	JC	short J19
  6948 000021D5 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  6949 000021D7 B402                <1> 	MOV	AH,BAD_ADDR_MARK
  6950 000021D9 7202                <1> 	JC	short J19
  6951                              <1> 
  6952                              <1> ;----- 	NEC MUST HAVE FAILED
  6953                              <1> J18:
  6954 000021DB B420                <1> 	MOV	AH,BAD_NEC
  6955                              <1> J19:
  6956 000021DD 0825[7C6F0000]      <1> 	OR	[DSKETTE_STATUS], AH
  6957                              <1> SET_END:
  6958 000021E3 803D[7C6F0000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  6959 000021EA F5                  <1> 	CMC
  6960 000021EB 5E                  <1> 	POP	eSI
  6961 000021EC C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  6962                              <1> 
  6963                              <1> SET_END_POP:
  6964 000021ED 9D                  <1> 	POPF
  6965 000021EE EBF3                <1> 	JMP	SHORT SET_END
  6966                              <1> 
  6967                              <1> ;-------------------------------------------------------------------------------
  6968                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  6969                              <1> ;-------------------------------------------------------------------------------
  6970                              <1> DSTATE:
  6971 000021F0 803D[7C6F0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  6972 000021F7 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  6973 000021F9 808F[896F0000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  6974 00002200 F687[896F0000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  6975 00002207 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  6976 00002209 8A87[896F0000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  6977 0000220F 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  6978 00002211 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  6979 00002213 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  6980                              <1> 
  6981                              <1> ;----- 	CHECK IF IT IS 1.44M
  6982                              <1> 
  6983 00002215 E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6984                              <1> 	;;20/02/2015
  6985                              <1> 	;;JC	short M_12		; CMOS BAD
  6986 0000221A 7414                <1> 	jz	short M_12 ;; 20/02/2015
  6987 0000221C 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  6988 0000221E 7410                <1> 	JE	short M_12		; YES
  6989                              <1> M_720:
  6990 00002220 80A7[896F0000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  6991 00002227 808F[896F0000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  6992 0000222E EB07                <1> 	JMP	SHORT SETBAC		; BACK
  6993                              <1> M_12:	
  6994 00002230 808F[896F0000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  6995                              <1> 					; TURN ON DETERMINED & FMT CAPA
  6996                              <1> SETBAC:
  6997 00002237 C3                  <1> 	RETn
  6998                              <1> 
  6999                              <1> ;-------------------------------------------------------------------------------
  7000                              <1> ; RETRY	
  7001                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  7002                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  7003                              <1> ;
  7004                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  7005                              <1> ;-------------------------------------------------------------------------------
  7006                              <1> RETRY:
  7007 00002238 803D[7C6F0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  7008 0000223F 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  7009 00002241 803D[7C6F0000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  7010 00002248 743C                <1> 	JZ	short NO_RETRY
  7011 0000224A 8AA7[896F0000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  7012 00002250 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  7013 00002253 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  7014 00002255 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  7015 00002258 8A2D[846F0000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  7016 0000225E C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  7017 00002261 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  7018 00002264 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  7019 00002266 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  7020                              <1> 
  7021                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  7022                              <1> ;	 00000000B (500) -> 10000000B	(250)
  7023                              <1> ;	 10000000B (250) -> 01000000B	(300)
  7024                              <1> ;	 01000000B (300) -> 00000000B	(500)
  7025                              <1> 
  7026 00002268 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  7027 0000226B D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  7028 0000226D 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  7029 00002270 80A7[896F0000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  7030                              <1> 					; RATE, DBL STEP OFF
  7031 00002277 08A7[896F0000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  7032 0000227D C605[7C6F0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  7033 00002284 F9                  <1> 	STC				; SET CARRY FOR RETRY
  7034 00002285 C3                  <1> 	RETn				; RETRY RETURN
  7035                              <1> 
  7036                              <1> NO_RETRY:
  7037 00002286 F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  7038 00002287 C3                  <1> 	RETn				; NO RETRY RETURN
  7039                              <1> 
  7040                              <1> ;-------------------------------------------------------------------------------
  7041                              <1> ; NUM_TRANS
  7042                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  7043                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  7044                              <1> ;
  7045                              <1> ; ON ENTRY:	[BP+1] = TRACK
  7046                              <1> ;		SI-HI  = HEAD
  7047                              <1> ;		[BP]   = START SECTOR
  7048                              <1> ;
  7049                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  7050                              <1> ;-------------------------------------------------------------------------------
  7051                              <1> NUM_TRANS:
  7052 00002288 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  7053 0000228A 803D[7C6F0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  7054 00002291 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  7055 00002293 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  7056 00002295 E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  7057 0000229A 8A1D[826F0000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  7058 000022A0 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  7059 000022A3 3A2D[816F0000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  7060 000022A9 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  7061 000022AB 8A2D[806F0000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  7062 000022B1 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  7063 000022B4 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  7064 000022B6 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7065                              <1> DIF_HD:
  7066 000022B8 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7067                              <1> SAME_TRK:
  7068 000022BA 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  7069 000022BD 88D8                <1> 	MOV	AL,BL			; TO AL
  7070                              <1> NT_OUT:
  7071 000022BF C3                  <1> 	RETn
  7072                              <1> 
  7073                              <1> ;-------------------------------------------------------------------------------
  7074                              <1> ; SETUP_END
  7075                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  7076                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  7077                              <1> ;
  7078                              <1> ; ON EXIT:
  7079                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7080                              <1> ;-------------------------------------------------------------------------------
  7081                              <1> SETUP_END:
  7082 000022C0 B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  7083 000022C2 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  7084 000022C4 E8CB000000          <1> 	CALL	GET_PARM
  7085 000022C9 8825[7B6F0000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  7086 000022CF 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  7087 000022D1 8A25[7C6F0000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  7088 000022D7 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  7089 000022D9 7402                <1> 	JZ	short NUN_ERR			; NO ERROR
  7090 000022DB 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  7091                              <1> NUN_ERR: 
  7092 000022DD 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  7093 000022E0 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  7094 000022E1 C3                  <1> 	RETn
  7095                              <1> 
  7096                              <1> ;-------------------------------------------------------------------------------
  7097                              <1> ; SETUP_DBL
  7098                              <1> ;	CHECK DOUBLE STEP.
  7099                              <1> ;
  7100                              <1> ; ON ENTRY :	DI = DRIVE
  7101                              <1> ;
  7102                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  7103                              <1> ;-------------------------------------------------------------------------------
  7104                              <1> SETUP_DBL:
  7105 000022E2 8AA7[896F0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  7106 000022E8 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  7107 000022EB 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  7108                              <1> 
  7109                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  7110                              <1> 
  7111 000022ED C605[796F0000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  7112 000022F4 E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  7113 000022F9 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  7114 000022FB E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  7115 00002300 E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  7116 00002305 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  7117                              <1> 
  7118                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  7119                              <1> 
  7120 00002307 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  7121 0000230B F687[896F0000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  7122 00002312 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  7123 00002314 B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  7124                              <1> 
  7125                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  7126                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  7127                              <1> ;	THEN SET DOUBLE STEP ON.
  7128                              <1> 
  7129                              <1> CNT_OK:
  7130 00002316 C605[7B6F0000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  7131 0000231D 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  7132 0000231F C605[7C6F0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  7133 00002326 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  7134 00002329 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  7135 0000232B C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  7136 0000232E 6650                <1> 	PUSH	AX			; SAVE HEAD
  7137 00002330 E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  7138 00002335 6658                <1> 	POP	AX			; RESTORE HEAD
  7139 00002337 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  7140 0000233A E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  7141 0000233F 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  7142 00002340 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  7143 00002345 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  7144 00002346 6659                <1> 	POP	CX			; RESTORE COUNT
  7145 00002348 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  7146 0000234A FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  7147 0000234C 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  7148 0000234E 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  7149                              <1> 
  7150                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  7151                              <1> 
  7152                              <1> SD_ERR:	
  7153 00002350 F9                  <1> 	STC				; SET CARRY FOR ERROR
  7154 00002351 C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  7155                              <1> 
  7156                              <1> DO_CHK:
  7157 00002352 8A0D[806F0000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  7158 00002358 888F[8D6F0000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  7159 0000235E D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  7160 00002360 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  7161 00002362 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  7162 00002364 808F[896F0000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  7163                              <1> NO_DBL:
  7164 0000236B F8                  <1> 	CLC				; CLEAR ERROR FLAG
  7165 0000236C C3                  <1> 	RETn
  7166                              <1> 
  7167                              <1> ;-------------------------------------------------------------------------------
  7168                              <1> ; READ_ID
  7169                              <1> ;	READ ID FUNCTION.
  7170                              <1> ;
  7171                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  7172                              <1> ;
  7173                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  7174                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7175                              <1> ;-------------------------------------------------------------------------------
  7176                              <1> READ_ID:
  7177 0000236D B8[8A230000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  7178 00002372 50                  <1> 	PUSH	eAX
  7179 00002373 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  7180 00002375 E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7181 0000237A 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  7182 0000237D 88C4                <1> 	MOV	AH,AL
  7183 0000237F E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7184 00002384 E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  7185 00002389 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  7186                              <1> ER_3:
  7187 0000238A C3                  <1> 	RETn
  7188                              <1> 
  7189                              <1> ;-------------------------------------------------------------------------------
  7190                              <1> ; CMOS_TYPE
  7191                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  7192                              <1> ;
  7193                              <1> ; ON ENTRY:	DI = DRIVE #
  7194                              <1> ;
  7195                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  7196                              <1> ;-------------------------------------------------------------------------------
  7197                              <1> 
  7198                              <1> CMOS_TYPE: ; 11/12/2014
  7199 0000238B 8A87[EE690000]      <1> mov	al, [eDI+fd0_type]
  7200 00002391 20C0                <1> and 	al, al ; 18/12/2014
  7201 00002393 C3                  <1> retn
  7202                              <1> 
  7203                              <1> ;CMOS_TYPE:
  7204                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  7205                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  7206                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  7207                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  7208                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  7209                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  7210                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  7211                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  7212                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  7213                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  7214                              <1> ;TB:
  7215                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  7216                              <1> ;BAD_CM:
  7217                              <1> ;	RETn				; CY, STATUS OF READ
  7218                              <1> 
  7219                              <1> ;-------------------------------------------------------------------------------
  7220                              <1> ; GET_PARM
  7221                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  7222                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  7223                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  7224                              <1> ;	THE PARAMETER IN DL.
  7225                              <1> ;
  7226                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  7227                              <1> ;
  7228                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  7229                              <1> ;		AL,DH DESTROYED
  7230                              <1> ;-------------------------------------------------------------------------------
  7231                              <1> GET_PARM:
  7232                              <1> 	;PUSH	DS
  7233 00002394 56                  <1> 	PUSH	eSI
  7234                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  7235                              <1>     	;MOV	DS,AX
  7236                              <1> 	;;mov	ax, cs
  7237                              <1> 	;;mov	ds, ax
  7238                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  7239 00002395 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  7240                              <1> 	;SUB	BH,BH			; BX = INDEX
  7241 00002397 81E3FF000000        <1> 	and	ebx, 0FFh
  7242                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  7243                              <1> 	;
  7244                              <1> 	; 17/12/2014
  7245 0000239D 66A1[E1690000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  7246 000023A3 38E0                <1> 	cmp	al, ah
  7247 000023A5 7425                <1> 	je	short gpndc
  7248 000023A7 A2[E2690000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  7249 000023AC 53                  <1> 	push	ebx ; 08/02/2015
  7250 000023AD 88C3                <1> 	mov	bl, al 
  7251                              <1> 	; 11/12/2014
  7252 000023AF 8A83[EE690000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  7253                              <1> 	; 18/12/2014
  7254 000023B5 20C0                <1> 	and	al, al
  7255 000023B7 7507                <1> 	jnz	short gpdtc
  7256 000023B9 BB[CB690000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  7257 000023BE EB05                <1>         jmp     short gpdpu
  7258                              <1> gpdtc:	
  7259 000023C0 E817F9FFFF          <1> 	call	DR_TYPE_CHECK
  7260                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  7261                              <1> gpdpu:
  7262 000023C5 891D[68690000]      <1> 	mov	[DISK_POINTER], ebx
  7263 000023CB 5B                  <1> 	pop	ebx
  7264                              <1> gpndc:
  7265 000023CC 8B35[68690000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  7266 000023D2 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  7267 000023D5 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  7268 000023D7 5E                  <1> 	POP	eSI
  7269                              <1> 	;POP	DS
  7270 000023D8 C3                  <1> 	RETn
  7271                              <1> 
  7272                              <1> ;-------------------------------------------------------------------------------
  7273                              <1> ; MOTOR_ON
  7274                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  7275                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  7276                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  7277                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  7278                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  7279                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  7280                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  7281                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  7282                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  7283                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  7284                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  7285                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  7286                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  7287                              <1> ;
  7288                              <1> ; ON ENTRY:	DI = DRIVE #
  7289                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  7290                              <1> ;-------------------------------------------------------------------------------
  7291                              <1> MOTOR_ON:
  7292 000023D9 53                  <1> 	PUSH	eBX			; SAVE REG.
  7293 000023DA E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  7294 000023DF 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  7295 000023E1 E89BF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7296 000023E6 E865F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  7297                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  7298                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  7299                              <1> M_WAIT:
  7300 000023EB B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  7301 000023ED E8A2FFFFFF          <1> 	CALL	GET_PARM
  7302                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  7303                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  7304                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  7305 000023F2 80FC08              <1> 	cmp	ah, 8
  7306                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  7307 000023F5 7702                <1> 	ja	short J13
  7308                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  7309 000023F7 B408                <1> 	mov	ah, 8
  7310                              <1> 
  7311                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  7312                              <1> GP2:	
  7313                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  7314                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  7315 000023F9 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  7316 000023FE E819F1FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  7317                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  7318 00002403 FECC                <1> 	dec	ah
  7319 00002405 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  7320                              <1> MOT_IS_ON:
  7321 00002407 5B                  <1> 	POP	eBX			; RESTORE REG.
  7322 00002408 C3                  <1> 	RETn
  7323                              <1> 
  7324                              <1> ;-------------------------------------------------------------------------------
  7325                              <1> ; TURN_ON
  7326                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  7327                              <1> ;
  7328                              <1> ; ON ENTRY:	DI = DRIVE #
  7329                              <1> ;
  7330                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  7331                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  7332                              <1> ;		AX,BX,CX,DX DESTROYED
  7333                              <1> ;-------------------------------------------------------------------------------
  7334                              <1> TURN_ON:
  7335 00002409 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7336 0000240B 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  7337 0000240D C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  7338 00002410 FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  7339 00002411 C605[7B6F0000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  7340 00002418 A0[7A6F0000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7341 0000241D 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  7342 0000241F B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  7343 00002421 D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  7344                              <1> 
  7345                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  7346                              <1> ;  BL = DRIVE SELECT DESIRED
  7347                              <1> ;  AH = MOTOR ON MASK DESIRED
  7348                              <1> 
  7349 00002423 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  7350 00002425 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  7351 00002427 8425[7A6F0000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  7352 0000242D 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  7353                              <1> 
  7354                              <1> TURN_IT_ON:
  7355 0000242F 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  7356 00002431 8A3D[7A6F0000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  7357 00002437 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  7358 0000243A 8025[7A6F0000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  7359 00002441 0825[7A6F0000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  7360 00002447 A0[7A6F0000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7361 0000244C 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  7362 0000244E 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  7363 00002451 FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  7364 00002452 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  7365 00002454 C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  7366 00002457 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  7367 00002459 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  7368 0000245D EE                  <1> 	OUT	DX,AL
  7369 0000245E 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  7370                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  7371 00002460 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  7372 00002462 F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  7373 00002463 C3                  <1> 	RETn
  7374                              <1> 
  7375                              <1> NO_MOT_WAIT:
  7376 00002464 FB                  <1> 	sti
  7377                              <1> no_mot_w1: ; 27/02/2015
  7378 00002465 F9                  <1> 	STC				; SET NO WAIT REQUIRED
  7379                              <1> 	;STI				; INTERRUPTS BACK ON
  7380 00002466 C3                  <1> 	RETn
  7381                              <1> 
  7382                              <1> ;-------------------------------------------------------------------------------
  7383                              <1> ; HD_WAIT
  7384                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  7385                              <1> ;
  7386                              <1> ; ON ENTRY:	DI = DRIVE #
  7387                              <1> ;
  7388                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  7389                              <1> ;-------------------------------------------------------------------------------
  7390                              <1> HD_WAIT:
  7391 00002467 B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  7392 00002469 E826FFFFFF          <1> 	CALL	GET_PARM
  7393 0000246E 08E4                <1> 	or	ah, ah	; 17/12/2014
  7394 00002470 7519                <1> 	jnz	short DO_WAT
  7395 00002472 F605[7A6F0000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  7396                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  7397                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  7398                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  7399 00002479 741E                <1> 	jz	short HW_DONE
  7400 0000247B B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  7401 0000247D 8A87[896F0000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  7402 00002483 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  7403 00002485 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  7404 00002487 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  7405                              <1> ;GP3:
  7406 00002489 B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  7407                              <1> ;	JMP	SHORT DO_WAT
  7408                              <1> 
  7409                              <1> ;ISNT_WRITE:
  7410                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  7411                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  7412                              <1> 
  7413                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  7414                              <1> DO_WAT:
  7415                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  7416                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  7417                              <1> J29:					; 	1 MILLISECOND LOOP
  7418                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  7419 0000248B B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  7420 00002490 E887F0FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  7421                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  7422 00002495 FECC                <1> 	dec	ah
  7423 00002497 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  7424                              <1> HW_DONE:
  7425 00002499 C3                  <1> 	RETn
  7426                              <1> 
  7427                              <1> ;-------------------------------------------------------------------------------
  7428                              <1> ; NEC_OUTPUT
  7429                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  7430                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  7431                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  7432                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  7433                              <1> ; 
  7434                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  7435                              <1> ;
  7436                              <1> ; ON EXIT:	CY = 0  SUCCESS
  7437                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  7438                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  7439                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  7440                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  7441                              <1> ;		AX,CX,DX DESTROYED
  7442                              <1> ;-------------------------------------------------------------------------------
  7443                              <1> 
  7444                              <1> ; 09/12/2014 [Erdogan Tan] 
  7445                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  7446                              <1> ; Diskette Drive Controller Status Register (3F4h)
  7447                              <1> ;	This read only register facilitates the transfer of data between
  7448                              <1> ;	the system microprocessor and the controller.
  7449                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  7450                              <1> ;	  with the system micrprocessor.
  7451                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  7452                              <1> ;	  the transfer is to the controller.
  7453                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  7454                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  7455                              <1> ; Bit 3 - Reserved.
  7456                              <1> ; Bit 2 - Reserved.
  7457                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7458                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7459                              <1> 
  7460                              <1> ; Data Register (3F5h)
  7461                              <1> ; This read/write register passes data, commands and parameters, and provides
  7462                              <1> ; diskette status information.
  7463                              <1>   		
  7464                              <1> NEC_OUTPUT:
  7465                              <1> 	;PUSH	BX			; SAVE REG.
  7466 0000249A 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  7467                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  7468                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  7469                              <1> 	; 16/12/2014
  7470                              <1> 	; waiting for (max.) 0.5 seconds
  7471                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  7472                              <1> 	;
  7473                              <1> 	; 17/12/2014
  7474                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  7475                              <1> 	;
  7476                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  7477                              <1> 	;		go on.
  7478                              <1> 	;INPUT:
  7479                              <1> 	;	AH=Mask for isolation bits.
  7480                              <1> 	;	AL=pattern to look for.
  7481                              <1> 	;	DX=Port to test for
  7482                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7483                              <1> 	;	     (normally 30 microseconds per period.)
  7484                              <1> 	;
  7485                              <1> 	;WFP_SHORT:  
  7486                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  7487                              <1> 	;
  7488                              <1> 
  7489                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  7490                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  7491 0000249E B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  7492                              <1> ;
  7493                              <1> ;WFPS_OUTER_LP:
  7494                              <1> ;	;
  7495                              <1> ;WFPS_CHECK_PORT:
  7496                              <1> J23:
  7497 000024A3 EC                  <1> 	IN	AL,DX			; GET STATUS
  7498 000024A4 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7499 000024A6 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7500 000024A8 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  7501                              <1> WFPS_HI:
  7502 000024AA E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  7503 000024AC A810                <1> 	TEST	AL,010H			; transition on memory
  7504 000024AE 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  7505                              <1> WFPS_LO:
  7506 000024B0 E461                <1> 	IN	AL, PORT_B		; SYS1
  7507 000024B2 A810                <1> 	TEST	AL,010H
  7508 000024B4 74FA                <1> 	JZ	SHORT WFPS_LO
  7509                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  7510 000024B6 E2EB                <1> 	loop	J23	; 27/02/2015
  7511                              <1> ;	;
  7512                              <1> ;	dec	bl
  7513                              <1> ;	jnz	short WFPS_OUTER_LP
  7514                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  7515                              <1> ;J23:
  7516                              <1> ;	IN	AL,DX			; GET STATUS
  7517                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7518                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7519                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  7520                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  7521                              <1> 	;DEC	BL			; DECREMENT COUNTER
  7522                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  7523                              <1>    
  7524                              <1> 	;;27/02/2015
  7525                              <1> 	;16/12/2014
  7526                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  7527                              <1> 	;;jb	short J23
  7528                              <1> 
  7529                              <1> ;WFPS_TIMEOUT:
  7530                              <1> 
  7531                              <1> ;-----	FALL THRU TO ERROR RETURN
  7532                              <1> 
  7533 000024B8 800D[7C6F0000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  7534                              <1> 	;POP	BX			; RESTORE REG.
  7535 000024BF 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  7536 000024C0 F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  7537 000024C1 C3                  <1> 	RETn
  7538                              <1> 
  7539                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  7540                              <1> 
  7541                              <1> J27:	
  7542 000024C2 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  7543 000024C4 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  7544 000024C6 EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  7545                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  7546                              <1> 	; 27/02/2015
  7547 000024C7 9C                  <1> 	PUSHF				; SAVE FLAGS
  7548 000024C8 B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  7549 000024CD E84AF0FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  7550 000024D2 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  7551                              <1> 	;POP	BX			; RESTORE REG
  7552 000024D3 C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  7553                              <1> 
  7554                              <1> ;-------------------------------------------------------------------------------
  7555                              <1> ; SEEK
  7556                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  7557                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  7558                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  7559                              <1> ;
  7560                              <1> ; ON ENTRY:	DI = DRIVE #
  7561                              <1> ;		CH = TRACK #
  7562                              <1> ;
  7563                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7564                              <1> ;		AX,BX,CX DX DESTROYED
  7565                              <1> ;-------------------------------------------------------------------------------
  7566                              <1> SEEK:
  7567 000024D4 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7568 000024D6 B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  7569 000024D8 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  7570 000024DA D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  7571 000024DC 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  7572 000024DE 8405[796F0000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  7573 000024E4 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  7574                              <1> 
  7575 000024E6 0805[796F0000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  7576 000024EC E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7577 000024F1 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  7578                              <1> 
  7579                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  7580                              <1> 
  7581 000024F3 C605[7C6F0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  7582 000024FA E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7583 000024FF 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  7584                              <1> 
  7585                              <1> AFT_RECAL:
  7586 00002501 C687[8D6F0000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  7587 00002508 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  7588 0000250A 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  7589                              <1> 
  7590                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  7591                              <1> 
  7592 0000250C F687[896F0000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  7593 00002513 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  7594 00002515 D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  7595                              <1> 
  7596 00002517 3AAF[8D6F0000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  7597 0000251D 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  7598                              <1> 
  7599 0000251F BA[52250000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  7600 00002524 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  7601 00002525 88AF[8D6F0000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  7602 0000252B B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  7603 0000252D E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  7604 00002532 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7605 00002534 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  7606 00002536 E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  7607 0000253B 8AA7[8D6F0000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  7608 00002541 E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  7609 00002546 E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  7610                              <1> 
  7611                              <1> ;-----	WAIT FOR HEAD SETTLE
  7612                              <1> 
  7613                              <1> DO_WAIT:
  7614 0000254B 9C                  <1> 	PUSHF				; SAVE STATUS
  7615 0000254C E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  7616 00002551 9D                  <1> 	POPF				; RESTORE STATUS
  7617                              <1> RB:
  7618                              <1> NEC_ERR:
  7619                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  7620                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  7621 00002552 C3                  <1> 	RETn				; RETURN TO CALLER
  7622                              <1> 
  7623                              <1> ;-------------------------------------------------------------------------------
  7624                              <1> ; RECAL
  7625                              <1> ;	RECALIBRATE DRIVE
  7626                              <1> ;
  7627                              <1> ; ON ENTRY:	DI = DRIVE #
  7628                              <1> ;
  7629                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  7630                              <1> ;-------------------------------------------------------------------------------
  7631                              <1> RECAL:
  7632 00002553 6651                <1> 	PUSH	CX
  7633 00002555 B8[71250000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  7634 0000255A 50                  <1> 	PUSH	eAX
  7635 0000255B B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  7636 0000255D E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  7637 00002562 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7638 00002564 88DC                <1> 	MOV	AH,BL
  7639 00002566 E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  7640 0000256B E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  7641 00002570 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  7642                              <1> RC_BACK:
  7643 00002571 6659                <1> 	POP	CX
  7644 00002573 C3                  <1> 	RETn
  7645                              <1> 
  7646                              <1> ;-------------------------------------------------------------------------------
  7647                              <1> ; CHK_STAT_2
  7648                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  7649                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  7650                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  7651                              <1> ;
  7652                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7653                              <1> ;-------------------------------------------------------------------------------
  7654                              <1> CHK_STAT_2:
  7655 00002574 B8[9C250000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  7656 00002579 50                  <1> 	PUSH	eAX
  7657 0000257A E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  7658 0000257F 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  7659 00002581 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  7660 00002583 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  7661 00002588 E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  7662 0000258D 720C                <1> 	JC	short J34
  7663 0000258F A0[7D6F0000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  7664 00002594 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  7665 00002596 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  7666 00002598 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  7667 0000259A F8                  <1> 	CLC				; GOOD RETURN
  7668                              <1> J34:
  7669 0000259B 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  7670                              <1> CS_BACK:
  7671 0000259C C3                  <1> 	RETn
  7672                              <1> J35:
  7673 0000259D 800D[7C6F0000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  7674 000025A4 F9                  <1> 	STC				; ERROR RETURN CODE
  7675 000025A5 EBF4                <1> 	JMP	SHORT J34
  7676                              <1> 
  7677                              <1> ;-------------------------------------------------------------------------------
  7678                              <1> ; WAIT_INT
  7679                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  7680                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  7681                              <1> ;	IF THE DRIVE IS NOT READY.
  7682                              <1> ;
  7683                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7684                              <1> ;-------------------------------------------------------------------------------
  7685                              <1> 
  7686                              <1> ; 17/12/2014
  7687                              <1> ; 2.5 seconds waiting !
  7688                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  7689                              <1> ; amount of time to wait for completion interrupt from NEC.
  7690                              <1> 
  7691                              <1> 
  7692                              <1> WAIT_INT:
  7693 000025A7 FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  7694 000025A8 F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  7695                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  7696                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  7697                              <1> 
  7698                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  7699                              <1> 	;
  7700                              <1> 	;WAIT_FOR_MEM:	
  7701                              <1> 	;	Waits for a bit at a specified memory location pointed
  7702                              <1> 	;	to by ES:[DI] to become set.
  7703                              <1> 	;INPUT:
  7704                              <1> 	;	AH=Mask to test with.
  7705                              <1> 	;	ES:[DI] = memory location to watch.
  7706                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7707                              <1> 	;	     (normally 30 microseconds per period.)
  7708                              <1> 
  7709                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  7710                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  7711                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  7712                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  7713                              <1> 	; 27/02/2015
  7714 000025A9 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  7715                              <1> WFMS_CHECK_MEM:
  7716 000025AE F605[796F0000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7717 000025B5 7516                <1>         jnz     short J37
  7718                              <1> WFMS_HI:
  7719 000025B7 E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  7720 000025B9 A810                <1> 	TEST	AL,010H			; transition on memory
  7721 000025BB 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  7722                              <1> WFMS_LO:
  7723 000025BD E461                <1> 	IN	AL,PORT_B		;SYS1
  7724 000025BF A810                <1> 	TEST	AL,010H
  7725 000025C1 74FA                <1> 	JZ	SHORT WFMS_LO
  7726 000025C3 E2E9                <1>         LOOP    WFMS_CHECK_MEM
  7727                              <1> ;WFMS_OUTER_LP:
  7728                              <1> ;;	or	bl, bl			; check outer counter
  7729                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  7730                              <1> ;	dec	bl
  7731                              <1> ;	jz	short J36A	
  7732                              <1> ;	jmp	short WFMS_CHECK_MEM
  7733                              <1> 
  7734                              <1> 	;17/12/2014
  7735                              <1> 	;16/12/2014
  7736                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  7737                              <1> ;J36:
  7738                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7739                              <1> ;	JNZ	short J37
  7740                              <1> 	;16/12/2014
  7741                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  7742                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  7743                              <1> 	;JNZ	short J36
  7744                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  7745                              <1> ;	jb	short J36
  7746                              <1> 
  7747                              <1> ;WFMS_TIMEOUT:
  7748                              <1> ;J36A:
  7749 000025C5 800D[7C6F0000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  7750 000025CC F9                  <1> 	STC				; ERROR RETURN
  7751                              <1> J37:
  7752 000025CD 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  7753 000025CE 8025[796F0000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  7754 000025D5 9D                  <1> 	POPF				; RECOVER CARRY
  7755 000025D6 C3                  <1> 	RETn				; GOOD RETURN CODE
  7756                              <1> 
  7757                              <1> ;-------------------------------------------------------------------------------
  7758                              <1> ; RESULTS
  7759                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  7760                              <1> ;	FOLLOWING AN INTERRUPT.
  7761                              <1> ;
  7762                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7763                              <1> ;		AX,BX,CX,DX DESTROYED
  7764                              <1> ;-------------------------------------------------------------------------------
  7765                              <1> RESULTS:
  7766 000025D7 57                  <1> 	PUSH	eDI
  7767 000025D8 BF[7D6F0000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  7768 000025DD B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  7769 000025DF 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  7770                              <1> 
  7771                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  7772                              <1> 
  7773                              <1> _R10: 
  7774                              <1> 	; 16/12/2014
  7775                              <1> 	; wait for (max) 0.5 seconds
  7776                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  7777                              <1> 	;XOR	CX,CX			; COUNTER
  7778                              <1> 
  7779                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  7780                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  7781                              <1> 	; 27/02/2015
  7782 000025E3 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  7783                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  7784                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  7785                              <1> 
  7786                              <1> WFPSR_OUTER_LP:
  7787                              <1> 	;
  7788                              <1> WFPSR_CHECK_PORT:
  7789                              <1> J39:					; WAIT FOR MASTER
  7790 000025E8 EC                  <1> 	IN	AL,DX			; GET STATUS
  7791 000025E9 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  7792 000025EB 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  7793 000025ED 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  7794                              <1> WFPSR_HI:
  7795 000025EF E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  7796 000025F1 A810                <1> 	TEST	AL,010H			; transition on memory
  7797 000025F3 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  7798                              <1> WFPSR_LO:
  7799 000025F5 E461                <1> 	IN	AL, PORT_B		; SYS1
  7800 000025F7 A810                <1> 	TEST	AL,010H
  7801 000025F9 74FA                <1> 	JZ	SHORT WFPSR_LO
  7802 000025FB E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  7803                              <1> 	;; 27/02/2015
  7804                              <1> 	;;dec	bh
  7805                              <1> 	;;jnz	short WFPSR_OUTER_LP
  7806                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  7807                              <1> 
  7808                              <1> 	;;mov	byte [wait_count], 0
  7809                              <1> ;J39:					; WAIT FOR MASTER
  7810                              <1> ;	IN	AL,DX			; GET STATUS
  7811                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  7812                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  7813                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  7814                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  7815                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  7816                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  7817                              <1> 	;
  7818                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  7819                              <1> 	;;jb	short J39	
  7820                              <1> 
  7821                              <1> ;WFPSR_TIMEOUT:
  7822 000025FD 800D[7C6F0000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  7823 00002604 F9                  <1> 	STC				; SET ERROR RETURN
  7824 00002605 EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  7825                              <1> 
  7826                              <1> ;-----	READ IN THE STATUS
  7827                              <1> 
  7828                              <1> J42:
  7829 00002607 EB00                <1> 	JMP	$+2			; I/O DELAY
  7830 00002609 6642                <1> 	INC	DX			; POINT AT DATA PORT
  7831 0000260B EC                  <1> 	IN	AL,DX			; GET THE DATA
  7832                              <1> 	; 16/12/2014
  7833                              <1> 	NEWIODELAY
  7834 0000260C E6EB                <2>  out 0ebh,al
  7835 0000260E 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  7836 00002610 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  7837                              <1> 	; 16/12/2014
  7838                              <1> ;	push	cx
  7839                              <1> ;	mov	cx, 30
  7840                              <1> ;wdw2:
  7841                              <1> ;	NEWIODELAY
  7842                              <1> ;	loop	wdw2
  7843                              <1> ;	pop	cx
  7844                              <1> 
  7845 00002611 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  7846 00002616 E801EFFFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  7847 0000261B 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  7848 0000261D EC                  <1> 	IN	AL,DX			; GET STATUS
  7849                              <1> 	; 16/12/2014
  7850                              <1> 	NEWIODELAY
  7851 0000261E E6EB                <2>  out 0ebh,al
  7852                              <1> 	;
  7853 00002620 A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  7854 00002622 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  7855                              <1> 
  7856 00002624 FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  7857 00002626 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  7858 00002628 800D[7C6F0000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  7859 0000262F F9                  <1> 	STC				; SET ERROR FLAG
  7860                              <1> 
  7861                              <1> ;-----	RESULT OPERATION IS DONE
  7862                              <1> POPRES:
  7863 00002630 5F                  <1> 	POP	eDI
  7864 00002631 C3                  <1> 	RETn				; RETURN WITH CARRY SET
  7865                              <1> 
  7866                              <1> ;-------------------------------------------------------------------------------
  7867                              <1> ; READ_DSKCHNG
  7868                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  7869                              <1> ;
  7870                              <1> ; ON ENTRY:	DI = DRIVE #
  7871                              <1> ;
  7872                              <1> ; ON EXIT:	DI = DRIVE #
  7873                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  7874                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  7875                              <1> ;		AX,CX,DX DESTROYED
  7876                              <1> ;-------------------------------------------------------------------------------
  7877                              <1> READ_DSKCHNG:
  7878 00002632 E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  7879 00002637 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  7880 0000263B EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  7881 0000263C A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  7882 0000263E C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  7883                              <1> 
  7884                              <1> ;-------------------------------------------------------------------------------
  7885                              <1> ; DRIVE_DET
  7886                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  7887                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  7888                              <1> ; ON ENTRY:	DI = DRIVE #
  7889                              <1> ;-------------------------------------------------------------------------------
  7890                              <1> DRIVE_DET:
  7891 0000263F E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  7892 00002644 E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7893 00002649 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  7894 0000264B B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  7895 0000264D E882FEFFFF          <1> 	CALL	SEEK
  7896 00002652 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  7897 00002654 B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  7898                              <1> SK_GIN:
  7899 00002656 FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  7900 00002658 6651                <1> 	PUSH	CX			; SAVE TRACK
  7901 0000265A E875FEFFFF          <1> 	CALL	SEEK
  7902 0000265F 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  7903 00002661 B8[9D260000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  7904 00002666 50                  <1> 	PUSH	eAX
  7905 00002667 B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  7906 00002669 E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  7907 0000266E 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  7908 00002671 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  7909 00002673 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  7910 00002678 E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  7911 0000267D 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  7912 0000267E 6659                <1> 	POP	CX			; RESTORE TRACK
  7913 00002680 F605[7D6F0000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  7914 00002687 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  7915 00002689 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  7916 0000268B 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  7917                              <1> 
  7918                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  7919                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  7920                              <1> 
  7921 0000268D 808F[896F0000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  7922 00002694 C3                  <1> 	RETn				; ALL INFORMATION SET
  7923                              <1> IS_80:
  7924 00002695 808F[896F0000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  7925                              <1> DD_BAC:
  7926 0000269C C3                  <1> 	RETn
  7927                              <1> POP_BAC:
  7928 0000269D 6659                <1> 	POP	CX			; THROW AWAY
  7929 0000269F C3                  <1> 	RETn
  7930                              <1> 
  7931                              <1> fdc_int:  
  7932                              <1> 	  ; 30/07/2015	
  7933                              <1> 	  ; 16/02/2015
  7934                              <1> ;int_0Eh: ; 11/12/2014
  7935                              <1> 
  7936                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  7937                              <1> ; DISK_INT
  7938                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  7939                              <1> ;
  7940                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  7941                              <1> ;-------------------------------------------------------------------------------
  7942                              <1> DISK_INT_1:
  7943                              <1> 
  7944 000026A0 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  7945 000026A2 1E                  <1> 	push	ds
  7946 000026A3 66B81000            <1> 	mov	ax, KDATA
  7947 000026A7 8ED8                <1> 	mov 	ds, ax
  7948 000026A9 800D[796F0000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  7949 000026B0 B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  7950 000026B2 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  7951 000026B4 1F                  <1> 	pop	ds
  7952 000026B5 6658                <1> 	POP	AX			; RECOVER REGISTER
  7953 000026B7 CF                  <1> 	IRET				; RETURN FROM INTERRUPT
  7954                              <1> 
  7955                              <1> ;-------------------------------------------------------------------------------
  7956                              <1> ; DSKETTE_SETUP
  7957                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  7958                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  7959                              <1> ;-------------------------------------------------------------------------------
  7960                              <1> DSKETTE_SETUP:
  7961                              <1> 	;PUSH	AX			; SAVE REGISTERS
  7962                              <1> 	;PUSH	BX
  7963                              <1> 	;PUSH	CX
  7964 000026B8 52                  <1> 	PUSH	eDX
  7965                              <1> 	;PUSH	DI
  7966                              <1> 	;;PUSH	DS
  7967                              <1> 	; 14/12/2014
  7968                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  7969                              <1> 	;mov	[DISK_POINTER+2], cs
  7970                              <1> 	;
  7971                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  7972 000026B9 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  7973 000026BB 66C705[896F0000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  7974 000026C3 00                  <1>
  7975 000026C4 8025[846F0000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  7976 000026CB 800D[846F0000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  7977 000026D2 C605[796F0000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  7978 000026D9 C605[7B6F0000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  7979 000026E0 C605[7A6F0000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  7980 000026E7 C605[7C6F0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  7981                              <1> 	;
  7982                              <1> 	; 28/02/2015
  7983                              <1> 	;mov	word [cfd], 100h 
  7984 000026EE E85FF2FFFF          <1> 	call	DSK_RESET
  7985 000026F3 5A                  <1> 	pop	edx
  7986 000026F4 C3                  <1> 	retn
  7987                              <1> 
  7988                              <1> ;SUP0:
  7989                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  7990                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7991                              <1> ;	; 02/01/2015
  7992                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  7993                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  7994                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  7995                              <1> ;       cmp     byte [fd1_type], 0	
  7996                              <1> ;	jna	short sup1
  7997                              <1> ;	or	di, di
  7998                              <1> ;	jnz	short sup1
  7999                              <1> ;	inc	di
  8000                              <1> ;       jmp     short SUP0
  8001                              <1> ;sup1:
  8002                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  8003                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  8004                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  8005                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  8006                              <1> ;	;POP	DI
  8007                              <1> ;	POP	eDX
  8008                              <1> ;	;POP	CX
  8009                              <1> ;	;POP	BX
  8010                              <1> ;	;POP	AX
  8011                              <1> ;	RETn
  8012                              <1> 
  8013                              <1> ;//////////////////////////////////////////////////////
  8014                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8015                              <1> ;
  8016                              <1> 
  8017                              <1> int13h: ; 21/02/2015
  8018 000026F5 9C                  <1> 	pushfd
  8019 000026F6 0E                  <1> 	push 	cs
  8020 000026F7 E859000000          <1> 	call 	DISK_IO
  8021 000026FC C3                  <1> 	retn
  8022                              <1> 
  8023                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  8024                              <1> ;/////////////////////////////////////////////////////////////////////
  8025                              <1> 
  8026                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  8027                              <1> ; 23/02/2015
  8028                              <1> ; 21/02/2015 (unix386.s)
  8029                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  8030                              <1> ;
  8031                              <1> ; Original Source Code:
  8032                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  8033                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  8034                              <1> ;
  8035                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  8036                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  8037                              <1> ;
  8038                              <1> 
  8039                              <1> 
  8040                              <1> ;The wait for controller to be not busy is 10 seconds.
  8041                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  8042                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  8043                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  8044                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  8045                              <1> 
  8046                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  8047                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  8048                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  8049                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  8050                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  8051                              <1> 
  8052                              <1> ;The wait for Data request on read and write longs is
  8053                              <1> ;2000 us. (?)
  8054                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  8055                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  8056                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  8057                              <1> 
  8058                              <1> ; Port 61h (PORT_B)
  8059                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  8060                              <1> 
  8061                              <1> ; 23/12/2014
  8062                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  8063                              <1> 
  8064                              <1> 
  8065                              <1> ;--- INT 13H -------------------------------------------------------------------
  8066                              <1> ;									       :
  8067                              <1> ; FIXED DISK I/O INTERFACE						       :
  8068                              <1> ;									       :
  8069                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  8070                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  8071                              <1> ;									       :
  8072                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  8073                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  8074                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  8075                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  8076                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  8077                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  8078                              <1> ;									       :
  8079                              <1> ;------------------------------------------------------------------------------:
  8080                              <1> ;									       :
  8081                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  8082                              <1> ;									       :
  8083                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  8084                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  8085                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  8086                              <1> ;			  DL > 80H - DISK				       :
  8087                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  8088                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  8089                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  8090                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  8091                              <1> ;	(AH)= 06H  UNUSED						       :
  8092                              <1> ;	(AH)= 07H  UNUSED						       :
  8093                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  8094                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  8095                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  8096                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  8097                              <1> ;	(AH)= 0AH  READ LONG						       :
  8098                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  8099                              <1> ;	(AH)= 0CH  SEEK 						       :
  8100                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  8101                              <1> ;	(AH)= 0EH  UNUSED						       :
  8102                              <1> ;	(AH)= 0FH  UNUSED						       :
  8103                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  8104                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  8105                              <1> ;	(AH)= 12H  UNUSED						       :
  8106                              <1> ;	(AH)= 13H  UNUSED						       :
  8107                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  8108                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  8109                              <1> ;									       :
  8110                              <1> ;-------------------------------------------------------------------------------
  8111                              <1> ;									       :
  8112                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  8113                              <1> ;									       :
  8114                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  8115                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  8116                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  8117                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  8118                              <1> ;									       :
  8119                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  8120                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  8121                              <1> ;				 (10 BITS TOTAL)			       :
  8122                              <1> ;									       :
  8123                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  8124                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  8125                              <1> ;									       :
  8126                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  8127                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  8128                              <1> ;									       :
  8129                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  8130                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  8131                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  8132                              <1> ;			       80H FOR A BAD SECTOR			       :
  8133                              <1> ;			   N = SECTOR NUMBER				       :
  8134                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  8135                              <1> ;			   THE TABLE SHOULD BE: 			       :
  8136                              <1> ;									       :
  8137                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  8138                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  8139                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  8140                              <1> ;									       :
  8141                              <1> ;-------------------------------------------------------------------------------
  8142                              <1> 
  8143                              <1> ;-------------------------------------------------------------------------------
  8144                              <1> ; OUTPUT								       :
  8145                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  8146                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  8147                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  8148                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  8149                              <1> ;									       :
  8150                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  8151                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  8152                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  8153                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  8154                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  8155                              <1> ;		REWRITTEN.						       :
  8156                              <1> ;									       :
  8157                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  8158                              <1> ;	   INPUT:							       :
  8159                              <1> ;	     (DL) = DRIVE NUMBER					       :
  8160                              <1> ;	   OUTPUT:							       :
  8161                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  8162                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  8163                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  8164                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  8165                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  8166                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  8167                              <1> ;									       :
  8168                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  8169                              <1> ;									       :
  8170                              <1> ;	AH = 0 - NOT PRESENT						       :
  8171                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  8172                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  8173                              <1> ;	     3 - FIXED DISK						       :
  8174                              <1> ;									       :
  8175                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  8176                              <1> ;									       :
  8177                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  8178                              <1> ;	INFORMATION.							       :
  8179                              <1> ;									       :
  8180                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  8181                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  8182                              <1> ;									       :
  8183                              <1> ;-------------------------------------------------------------------------------
  8184                              <1> 
  8185                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  8186                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  8187                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  8188                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  8189                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  8190                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  8191                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  8192                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  8193                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  8194                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  8195                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  8196                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  8197                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  8198                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  8199                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  8200                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  8201                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  8202                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  8203                              <1> 
  8204                              <1> ;--------------------------------------------------------
  8205                              <1> ;							:
  8206                              <1> ; FIXED DISK PARAMETER TABLE				:
  8207                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  8208                              <1> ;							:
  8209                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  8210                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  8211                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  8212                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  8213                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  8214                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  8215                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  8216                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  8217                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  8218                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  8219                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  8220                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  8221                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  8222                              <1> ;							:
  8223                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  8224                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  8225                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  8226                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  8227                              <1> ;							:
  8228                              <1> ;--------------------------------------------------------
  8229                              <1> 
  8230                              <1> ;--------------------------------------------------------
  8231                              <1> ;							:
  8232                              <1> ; HARDWARE SPECIFIC VALUES				:
  8233                              <1> ;							:
  8234                              <1> ;  -  CONTROLLER I/O PORT				:
  8235                              <1> ;							:
  8236                              <1> ;     > WHEN READ FROM: 				:
  8237                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  8238                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  8239                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  8240                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  8241                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  8242                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  8243                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  8244                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  8245                              <1> ;							:
  8246                              <1> ;     > WHEN WRITTEN TO:				:
  8247                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  8248                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  8249                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  8250                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  8251                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  8252                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  8253                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  8254                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  8255                              <1> ;							:
  8256                              <1> ;--------------------------------------------------------
  8257                              <1> 
  8258                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  8259                              <1> ;HF1_PORT	equ	0170h	
  8260                              <1> ;HF_REG_PORT	EQU	03F6H
  8261                              <1> ;HF1_REG_PORT	equ	0376h
  8262                              <1> 
  8263                              <1> HDC1_BASEPORT	equ	1F0h
  8264                              <1> HDC2_BASEPORT	equ	170h		
  8265                              <1> 
  8266 000026FD 90                  <1> align 2
  8267                              <1> 
  8268                              <1> ;-----		STATUS REGISTER
  8269                              <1> 
  8270                              <1> ST_ERROR	EQU	00000001B	;
  8271                              <1> ST_INDEX	EQU	00000010B	;
  8272                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  8273                              <1> ST_DRQ		EQU	00001000B	;
  8274                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  8275                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  8276                              <1> ST_READY	EQU	01000000B	;
  8277                              <1> ST_BUSY 	EQU	10000000B	;
  8278                              <1> 
  8279                              <1> ;-----		ERROR REGISTER
  8280                              <1> 
  8281                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  8282                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  8283                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  8284                              <1> ;		EQU	00001000B	; NOT USED
  8285                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  8286                              <1> ;		EQU	00100000B	; NOT USED
  8287                              <1> ERR_DATA_ECC	EQU	01000000B
  8288                              <1> ERR_BAD_BLOCK	EQU	10000000B
  8289                              <1> 
  8290                              <1> 
  8291                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  8292                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  8293                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  8294                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  8295                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  8296                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  8297                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  8298                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  8299                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  8300                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  8301                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  8302                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  8303                              <1> 
  8304                              <1> ;MAX_FILE	EQU	2
  8305                              <1> ;S_MAX_FILE	EQU	2
  8306                              <1> MAX_FILE	equ	4		; 22/12/2014
  8307                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  8308                              <1> 
  8309                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  8310                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  8311                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  8312                              <1> 
  8313                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  8314                              <1> 
  8315                              <1> ;-----		COMMAND BLOCK REFERENCE
  8316                              <1> 
  8317                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  8318                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  8319                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  8320                              <1> ; 19/12/2014
  8321                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  8322                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  8323                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8324                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8325                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  8326                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  8327                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  8328                              <1> 
  8329                              <1> align 2
  8330                              <1> 
  8331                              <1> ;----------------------------------------------------------------
  8332                              <1> ; FIXED DISK I/O SETUP						:
  8333                              <1> ;								:
  8334                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  8335                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  8336                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  8337                              <1> ;								:
  8338                              <1> ;----------------------------------------------------------------
  8339                              <1> 
  8340                              <1> DISK_SETUP:
  8341                              <1> 	;CLI
  8342                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  8343                              <1> 	;xor	ax,ax
  8344                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  8345                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  8346                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  8347                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  8348                              <1> 	;MOV	[DISK_VECTOR+2],AX
  8349                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  8350                              <1> 	;MOV	[ORG_VECTOR+2],CS
  8351                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  8352                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  8353                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  8354                              <1> 	;;MOV	[HDISK_INT+2],CS
  8355                              <1> 	;mov	[HDISK_INT1+2],CS
  8356                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  8357                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  8358                              <1> 	;mov	[HDISK_INT2+2],CS
  8359                              <1> 	;
  8360                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  8361                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  8362                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  8363                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  8364                              <1> 	;push	cs
  8365                              <1> 	;pop	ds
  8366                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  8367                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  8368 000026FE C705[946F0000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  8369 00002706 0900                <1>
  8370                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  8371                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  8372 00002708 C705[986F0000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  8373 00002710 0900                <1>
  8374                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  8375                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  8376 00002712 C705[9C6F0000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  8377 0000271A 0900                <1>
  8378                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  8379                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  8380 0000271C C705[A06F0000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  8381 00002724 0900                <1>
  8382                              <1> 	;
  8383                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  8384                              <1> 	;;;AND	AL,0BFH
  8385                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  8386                              <1> 	;;;JMP	$+2
  8387                              <1> 	;;IODELAY
  8388                              <1> 	;;OUT	INTB01,AL
  8389                              <1> 	;;IODELAY
  8390                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  8391                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  8392                              <1> 	;;;JMP	$+2
  8393                              <1> 	;;IODELAY
  8394                              <1> 	;;OUT	INTA01,AL
  8395                              <1> 	;
  8396                              <1> 	;STI
  8397                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  8398                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  8399                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  8400                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8401                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  8402                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  8403                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  8404                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  8405                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  8406                              <1> 	;mov	si, hd0_type
  8407 00002726 BE[F0690000]        <1> 	mov	esi, hd0_type
  8408                              <1> 	;mov	cx, 4
  8409 0000272B B904000000          <1> 	mov	ecx, 4
  8410                              <1> hde_l:
  8411 00002730 AC                  <1> 	lodsb
  8412 00002731 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  8413 00002733 7206                <1> 	jb	short _L4
  8414 00002735 FE05[906F0000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  8415                              <1> _L4: ; 26/02/2015
  8416 0000273B E2F3                <1> 	loop	hde_l	
  8417                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  8418                              <1> ;L4:
  8419                              <1> 	; 
  8420                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  8421                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  8422                              <1> 	;;mov 	cl, 3
  8423                              <1> 	;;
  8424                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  8425                              <1> ;;hdc_dl:
  8426                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  8427                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  8428                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  8429                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  8430                              <1> 	;;jnc	short hdc_reset0
  8431                              <1> 	;;loop	hdc_dl
  8432                              <1> 	;;; 27/12/2014
  8433                              <1> 	;;stc
  8434                              <1> 	;;retn
  8435                              <1> 	;
  8436                              <1> ;;hdc_reset0:
  8437                              <1> 	; 18/01/2015
  8438 0000273D 8A0D[906F0000]      <1> 	mov	cl, [HF_NUM]
  8439 00002743 20C9                <1> 	and	cl, cl
  8440 00002745 740D                <1> 	jz	short POD_DONE
  8441                              <1> 	;
  8442 00002747 B27F                <1> 	mov	dl, 7Fh
  8443                              <1> hdc_reset1:
  8444 00002749 FEC2                <1> 	inc	dl
  8445                              <1> 	;; 31/12/2015
  8446                              <1> 	;;push	dx
  8447                              <1> 	;;push	cx
  8448                              <1> 	;;push	ds
  8449                              <1> 	;;sub	ax, ax
  8450                              <1> 	;;mov	ds, ax
  8451                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  8452                              <1> 	;;pop	ds
  8453                              <1> 	;;MOV	BX,AX
  8454                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  8455                              <1> 	;;MOV	CX,AX
  8456                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  8457                              <1> 	;;
  8458                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  8459                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  8460                              <1> 	;;pop	cx
  8461                              <1> 	;;pop	dx
  8462                              <1> 	;;
  8463                              <1> 	; 18/01/2015
  8464 0000274B B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  8465                              <1> 	;int	13h
  8466 0000274D E8A3FFFFFF          <1> 	call	int13h
  8467 00002752 E2F5                <1> 	loop	hdc_reset1
  8468                              <1> POD_DONE:
  8469 00002754 C3                  <1> 	RETn
  8470                              <1> 
  8471                              <1> ;;-----	POD_ERROR
  8472                              <1> 
  8473                              <1> ;;CTL_ERRX:
  8474                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  8475                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  8476                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8477                              <1> ;	;JMP	short POD_DONE
  8478                              <1> 
  8479                              <1> ;;HD_RESET_1:
  8480                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  8481                              <1> ;;	;PUSH	CX
  8482                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  8483                              <1> ;;	INT	13H
  8484                              <1> ;;	JC	short RES_2
  8485                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  8486                              <1> ;;	INT	13H
  8487                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  8488                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  8489                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8490                              <1> ;;					; (30 seconds)		
  8491                              <1> ;;	;cmc
  8492                              <1> ;;	;JNC	short RES_1
  8493                              <1> ;;	jb	short RES_1
  8494                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  8495                              <1> ;;	;TEST	DL,1
  8496                              <1> ;;	;JNZ	RES_E1
  8497                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  8498                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  8499                              <1> ;;	;JMP	SHORT RES_E1
  8500                              <1> ;;RES_ER: ; 22/12/2014
  8501                              <1> ;;RES_OK:
  8502                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8503                              <1> ;;	;POP	BX
  8504                              <1> ;;	RETn
  8505                              <1> ;;
  8506                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  8507                              <1> ;;	INT	13H
  8508                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  8509                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  8510                              <1> ;;	INT	13H
  8511                              <1> ;;	JC	short RES_ER
  8512                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  8513                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  8514                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  8515                              <1> ;;	INT	13H
  8516                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  8517                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  8518                              <1> ;;	JE	short RES_OK
  8519                              <1> ;;	CMP	AH,DATA_CORRECTED
  8520                              <1> ;;	JE	short RES_OK
  8521                              <1> ;;	CMP	AH,BAD_ECC
  8522                              <1> ;;	JE	short RES_OK
  8523                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  8524                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8525                              <1> ;;					; (60 seconds)		
  8526                              <1> ;;	cmc
  8527                              <1> ;;	JC	short RES_ER		; FAILED
  8528                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  8529                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  8530                              <1> ;;	AND	AL,3FH
  8531                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  8532                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  8533                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  8534                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  8535                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  8536                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  8537                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  8538                              <1> ;;	;TEST	DL,1
  8539                              <1> ;;	;JNZ	short RES_E1
  8540                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  8541                              <1> ;;;RES_E1:
  8542                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8543                              <1> ;;;RES_OK:
  8544                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8545                              <1> ;;	;POP	BX
  8546                              <1> ;;	;RETn
  8547                              <1> ;
  8548                              <1> ;;SET_FAIL:
  8549                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  8550                              <1> ;	;CALL	CMOS_READ
  8551                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  8552                              <1> ;	;XCHG	AH,AL			; SAVE IT
  8553                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  8554                              <1> ;	;RETn
  8555                              <1> ;
  8556                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  8557                              <1> ;	;POP	AX			; SAVE RETURN
  8558                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  8559                              <1> ;	;POP	BX
  8560                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  8561                              <1> ;	;PUSH	CX
  8562                              <1> ;	;PUSH	AX
  8563                              <1> ;	;push	ds
  8564                              <1> ;	;xor	ax, ax
  8565                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  8566                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  8567                              <1> ;	;				; BX = START TIME
  8568                              <1> ;	;				; CX = END TIME
  8569                              <1> ;	;pop	ds
  8570                              <1> ;	;CMP	BX,CX
  8571                              <1> ;	;JB	short TCHK1		; START < END
  8572                              <1> ;	;CMP	BX,AX
  8573                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  8574                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  8575                              <1> ;;TCHK1: CMP	AX,BX
  8576                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  8577                              <1> ;;TCHK2: CMP	AX,CX
  8578                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  8579                              <1> ;;					; OR CURRENT < END < START
  8580                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  8581                              <1> ;;	RETn
  8582                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  8583                              <1> ;;	RETn
  8584                              <1> ;;
  8585                              <1> ;;int_13h:
  8586                              <1> 
  8587                              <1> ;----------------------------------------
  8588                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  8589                              <1> ;----------------------------------------
  8590                              <1> 
  8591                              <1> DISK_IO:
  8592 00002755 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  8593                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  8594                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  8595                              <1> 	;;call	int40h
  8596 00002758 0F8224F1FFFF        <1> 	jb	DISKETTE_IO_1
  8597                              <1> ;RET_2:
  8598                              <1> 	;RETf	2			; BACK TO CALLER
  8599                              <1> ;	retf	4
  8600                              <1> A1:
  8601 0000275E FB                  <1> 	STI				; ENABLE INTERRUPTS
  8602                              <1> 	;; 04/01/2015
  8603                              <1> 	;;OR	AH,AH
  8604                              <1> 	;;JNZ	short A2
  8605                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  8606                              <1> 	;;SUB	AH,AH
  8607 0000275F 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  8608 00002762 772C                <1> 	JA	short RET_2
  8609                              <1> 	; 18/01/2015
  8610 00002764 08E4                <1> 	or	ah,ah
  8611 00002766 742B                <1> 	jz	short A4
  8612 00002768 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  8613 0000276B 7504                <1> 	jne	short A2
  8614 0000276D 28E4                <1> 	sub	ah,ah	; Reset
  8615 0000276F EB22                <1> 	jmp	short A4
  8616                              <1> A2:
  8617 00002771 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  8618                              <1> 	;JNZ	short A3
  8619                              <1>         ;JMP    GET_PARM_N
  8620 00002774 0F841C030000        <1> 	je	GET_PARM_N
  8621 0000277A 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  8622                              <1> 	;JNZ	short A4
  8623                              <1>         ;JMP    READ_DASD_TYPE
  8624 0000277D 0F84C7020000        <1>         je      READ_DASD_TYPE
  8625                              <1> 	; 02/02/2015
  8626 00002783 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  8627                              <1> 	; 12/01/2015
  8628 00002786 F5                  <1> 	cmc
  8629 00002787 730A                <1> 	jnc	short A4
  8630                              <1> 	; 30/01/2015
  8631                              <1> 	;mov     byte [CS:DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  8632 00002789 C605[8F6F0000]01    <1>         mov     byte [DISK_STATUS1], BAD_CMD
  8633                              <1> 	;jmp	short RET_2
  8634                              <1> RET_2:
  8635 00002790 CA0400              <1> 	retf	4
  8636                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  8637 00002793 C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  8638 00002797 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  8639 00002798 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  8640 00002799 52                  <1> 	PUSH	eDX
  8641 0000279A 1E                  <1> 	PUSH	DS
  8642 0000279B 06                  <1> 	PUSH	ES
  8643 0000279C 56                  <1> 	PUSH	eSI
  8644 0000279D 57                  <1> 	PUSH	eDI
  8645                              <1> 	;;04/01/2015
  8646                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  8647                              <1> 	;;JNZ	short A5
  8648                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  8649                              <1> ;;A5:	
  8650                              <1> 	;push	cs
  8651                              <1> 	;pop	ds
  8652                              <1> 	; 21/02/2015
  8653 0000279E 6650                <1> 	push	ax
  8654 000027A0 66B81000            <1> 	mov	ax, KDATA
  8655 000027A4 8ED8                <1> 	mov	ds, ax
  8656 000027A6 8EC0                <1> 	mov	es, ax	
  8657 000027A8 6658                <1> 	pop	ax
  8658 000027AA E889000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  8659                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  8660 000027AF 8A25[8F6F0000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  8661 000027B5 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  8662 000027B8 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  8663 000027B9 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  8664 000027BA 5E                  <1> 	POP	eSI
  8665 000027BB 07                  <1>         POP     ES
  8666 000027BC 1F                  <1>         POP     DS
  8667 000027BD 5A                  <1> 	POP	eDX
  8668 000027BE 59                  <1> 	POP	eCX
  8669 000027BF 5B                  <1> 	POP	eBX
  8670 000027C0 C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  8671                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  8672 000027C1 CA0400              <1> 	retf	4
  8673                              <1> ; 21/02/2015
  8674                              <1> ;       dw --> dd
  8675                              <1> M1:					; FUNCTION TRANSFER TABLE
  8676 000027C4 [86290000]          <1> 	dd	DISK_RESET		; 000H
  8677 000027C8 [FD290000]          <1> 	dd	RETURN_STATUS		; 001H
  8678 000027CC [0A2A0000]          <1> 	dd	DISK_READ		; 002H
  8679 000027D0 [132A0000]          <1> 	dd	DISK_WRITE		; 003H
  8680 000027D4 [1C2A0000]          <1> 	dd	DISK_VERF		; 004H
  8681 000027D8 [342A0000]          <1> 	dd	FMT_TRK 		; 005H
  8682 000027DC [7C290000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  8683 000027E0 [7C290000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  8684 000027E4 [7C290000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  8685 000027E8 [FB2A0000]          <1> 	dd	INIT_DRV		; 009H
  8686 000027EC [5A2B0000]          <1> 	dd	RD_LONG 		; 00AH
  8687 000027F0 [632B0000]          <1> 	dd	WR_LONG 		; 00BH
  8688 000027F4 [6C2B0000]          <1> 	dd	DISK_SEEK		; 00CH
  8689 000027F8 [86290000]          <1> 	dd	DISK_RESET		; 00DH
  8690 000027FC [7C290000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  8691 00002800 [7C290000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  8692 00002804 [942B0000]          <1> 	dd	TST_RDY 		; 010H
  8693 00002808 [B82B0000]          <1> 	dd	HDISK_RECAL		; 011H
  8694 0000280C [7C290000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  8695 00002810 [7C290000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  8696 00002814 [EE2B0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  8697                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  8698 00002818 [7C290000]          <1> 	dd	BAD_COMMAND		; 015h
  8699 0000281C [7C290000]          <1> 	dd	BAD_COMMAND		; 016h
  8700 00002820 [7C290000]          <1> 	dd	BAD_COMMAND		; 017h
  8701 00002824 [7C290000]          <1> 	dd	BAD_COMMAND		; 018h
  8702 00002828 [7C290000]          <1> 	dd	BAD_COMMAND		; 019h
  8703 0000282C [7C290000]          <1> 	dd	BAD_COMMAND		; 01Ah
  8704 00002830 [0A2A0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  8705 00002834 [132A0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  8706                              <1> M1L     EQU    $-M1
  8707                              <1> 
  8708                              <1> DISK_IO_CONT:
  8709                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  8710 00002838 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  8711                              <1> 	;;JNZ	short SU0
  8712                              <1>         ;;JMP    RETURN_STATUS
  8713 0000283B 0F84BC010000        <1> 	je	RETURN_STATUS
  8714                              <1> SU0:
  8715 00002841 C605[8F6F0000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8716                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  8717                              <1> 	;mov	si, bx ;; 14/02/2015
  8718 00002848 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  8719 0000284A 8A1D[906F0000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  8720                              <1> 	;; 04/01/2015
  8721                              <1> 	;;PUSH	AX
  8722 00002850 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  8723                              <1> 					; (get drive number as 0 to 3)
  8724 00002853 38D3                <1> 	CMP	BL,DL
  8725                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  8726 00002855 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  8727                              <1>         ;
  8728                              <1> 	;;03/01/2015
  8729 0000285B 29DB                <1> 	sub	ebx, ebx
  8730 0000285D 88D3                <1> 	mov	bl, dl
  8731                              <1> 	;sub	bh, bh
  8732 0000285F 883D[A46F0000]      <1> 	mov	[LBAMode], bh 	; 0
  8733                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  8734                              <1> 	;test	byte [ebx+hd0_type], 1
  8735                              <1> 	;jz	short su1		; no
  8736                              <1> 	;inc	byte [LBAMode]
  8737                              <1> ;su1:
  8738                              <1> 	; 21/02/2015 (32 bit modification)
  8739                              <1> 	;04/01/2015
  8740 00002865 6650                <1> 	push	ax ; ***
  8741                              <1> 	;PUSH	ES ; **
  8742 00002867 6652                <1> 	PUSH	DX ; *
  8743 00002869 6650                <1> 	push	ax
  8744 0000286B E85C060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  8745                              <1> 	; 02/02/2015
  8746                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  8747 00002870 668B4310            <1> 	mov	ax, [ebx+16]
  8748 00002874 66A3[E4690000]      <1> 	mov	[HF_PORT], ax
  8749                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  8750 0000287A 668B5312            <1> 	mov	dx, [ebx+18]
  8751 0000287E 668915[E6690000]    <1> 	mov	[HF_REG_PORT], dx
  8752                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  8753 00002885 8A4314              <1> 	mov	al, [ebx+20]
  8754                              <1> 	; 23/02/2015
  8755 00002888 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  8756 0000288A 7406                <1> 	jz 	short su1
  8757 0000288C FE05[A46F0000]      <1> 	inc	byte [LBAMode] ; 1 
  8758                              <1> su1: 	 
  8759 00002892 C0E804              <1> 	shr 	al, 4
  8760 00002895 2401                <1> 	and	al, 1			
  8761 00002897 A2[E8690000]        <1> 	mov	[hf_m_s], al 
  8762                              <1> 	;
  8763                              <1> 	; 03/01/2015
  8764                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  8765 0000289C 8A4308              <1> 	mov	al, [ebx+8]
  8766                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  8767 0000289F EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  8768                              <1> 					; Control Byte:  (= 08h, here)
  8769                              <1> 					; bit 0 - 0
  8770                              <1> 					; bit 1 - nIEN (1 = disable irq)
  8771                              <1> 					; bit 2 - SRST (software RESET)
  8772                              <1> 					; bit 3 - use extra heads (8 to 15)
  8773                              <1> 					;         -always set to 1-	
  8774                              <1> 					; (bits 3 to 7 are reserved
  8775                              <1> 					;          for ATA devices)
  8776 000028A0 8A25[916F0000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  8777 000028A6 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  8778 000028A9 08C4                <1> 	OR	AH,AL
  8779 000028AB 8825[916F0000]      <1> 	MOV	[CONTROL_BYTE],AH	
  8780                              <1> 	; 04/01/2015
  8781 000028B1 6658                <1> 	pop	ax
  8782 000028B3 665A                <1> 	pop	dx ; * ;; 14/02/2015
  8783 000028B5 20E4                <1> 	and	ah, ah	; Reset function ?
  8784 000028B7 7507                <1> 	jnz	short su2
  8785                              <1> 	;;pop	dx ; * ;; 14/02/2015
  8786                              <1> 	;pop	es ; **
  8787 000028B9 6658                <1> 	pop	ax ; ***
  8788                              <1> 	;;pop	bx
  8789 000028BB E9C6000000          <1>         jmp     DISK_RESET
  8790                              <1> su2:
  8791 000028C0 803D[A46F0000]00    <1> 	cmp	byte [LBAMode], 0
  8792 000028C7 7661                <1> 	jna	short su3
  8793                              <1> 	;
  8794                              <1> 	; 02/02/2015 (LBA read/write function calls)
  8795 000028C9 80FC1B              <1> 	cmp	ah, 1Bh
  8796 000028CC 720B                <1> 	jb	short lbarw1
  8797 000028CE 80FC1C              <1> 	cmp	ah, 1Ch
  8798 000028D1 775C                <1> 	ja 	short invldfnc
  8799                              <1> 	;;pop	dx ; * ; 14/02/2015
  8800                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  8801 000028D3 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  8802                              <1> 	;; 14/02/2015
  8803 000028D5 88D1                <1> 	mov	cl, dl ; 14/02/2015
  8804                              <1> 	;;mov	dx, bx
  8805                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  8806                              <1> 	;;mov	bx, di
  8807                              <1> 	;mov	si, di ; Buffer offset
  8808 000028D7 EB31                <1> 	jmp	short lbarw2
  8809                              <1> lbarw1:
  8810                              <1> 	; convert CHS to LBA
  8811                              <1> 	;
  8812                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  8813                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  8814                              <1> 	;	+ Sector - 1
  8815 000028D9 6652                <1> 	push	dx ; * ;; 14/02/2015
  8816                              <1> 	;xor	dh, dh
  8817 000028DB 31D2                <1> 	xor	edx, edx
  8818                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  8819 000028DD 8A530E              <1> 	mov	dl, [ebx+14]
  8820                              <1> 	;xor	ah, ah
  8821 000028E0 31C0                <1> 	xor	eax, eax
  8822                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  8823 000028E2 8A4302              <1> 	mov	al, [ebx+2]
  8824 000028E5 FEC8                <1> 	dec	al
  8825 000028E7 6640                <1> 	inc	ax		; 0 =  256
  8826 000028E9 66F7E2              <1> 	mul 	dx
  8827                              <1> 		; AX = # of Heads" * Sectors/Track
  8828 000028EC 6689CA              <1> 	mov	dx, cx
  8829                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  8830 000028EF 83E13F              <1> 	and	ecx, 3fh
  8831 000028F2 86D6                <1> 	xchg	dl, dh
  8832 000028F4 C0EE06              <1> 	shr	dh, 6
  8833                              <1> 		; DX = cylinder (0 to 1023)
  8834                              <1> 	;mul 	dx
  8835                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  8836 000028F7 F7E2                <1> 	mul	edx
  8837 000028F9 FEC9                <1> 	dec	cl  ; sector - 1
  8838                              <1> 	;add	ax, cx
  8839                              <1> 	;adc	dx, 0
  8840                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  8841 000028FB 01C8                <1> 	add	eax, ecx
  8842 000028FD 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  8843                              <1> 	;push	dx
  8844                              <1> 	;push	ax
  8845 000028FF 50                  <1> 	push	eax
  8846                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  8847 00002900 8A430E              <1> 	mov	al, [ebx+14]
  8848 00002903 F6E5                <1> 	mul	ch
  8849                              <1> 		;  AX = Head * Sectors/Track
  8850 00002905 6699                <1>         cwd
  8851                              <1> 	;pop	dx
  8852 00002907 5A                  <1> 	pop	edx
  8853                              <1> 	;add	ax, dx
  8854                              <1> 	;pop	dx
  8855                              <1> 	;adc	dx, 0 ; add carry bit
  8856 00002908 01D0                <1> 	add	eax, edx
  8857                              <1> lbarw2:
  8858 0000290A 29D2                <1> 	sub	edx, edx ; 21/02/2015
  8859 0000290C 88CA                <1> 	mov	dl, cl ; 21/02/2015
  8860 0000290E C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  8861                              <1> 				; NOTE: Features register (1F1h, 171h)
  8862                              <1> 				; is not used for ATA device R/W functions. 
  8863                              <1> 				; It is old/obsolete 'write precompensation'
  8864                              <1> 				; register and error register
  8865                              <1> 				; for old ATA/IDE devices.
  8866                              <1> 	; 18/01/2014
  8867                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  8868 00002912 8A0D[E8690000]      <1> 	mov	cl, [hf_m_s]
  8869                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  8870                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  8871                              <1> 				; bit 6 = 1 = LBA mode
  8872                              <1> 				; bit 7 = 1
  8873 00002918 80C90E              <1> 	or	cl, 0Eh ; 1110b
  8874                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  8875 0000291B 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  8876 00002920 C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  8877                              <1> 	;or	dh, ch
  8878 00002923 09C8                <1> 	or	eax, ecx	
  8879                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  8880                              <1> 				  ; (Sector Number Register)
  8881                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  8882                              <1> 				  ; (Cylinder Low Register)
  8883                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  8884                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  8885                              <1> 				  ; (Cylinder High Register)
  8886                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  8887                              <1> 				  ; (Drive/Head Register)
  8888                              <1> 	
  8889                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  8890 00002925 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  8891                              <1> 	;14/02/2015
  8892                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  8893 00002928 EB38                <1> 	jmp	short su4
  8894                              <1> su3:
  8895                              <1> 	; 02/02/2015 
  8896                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  8897 0000292A 80FC14              <1> 	cmp 	ah, 14h
  8898 0000292D 7604                <1> 	jna 	short chsfnc
  8899                              <1> invldfnc:
  8900                              <1>         ; 14/02/2015  
  8901                              <1> 	;pop	es ; **
  8902 0000292F 6658                <1>         pop     ax ; ***
  8903                              <1>         ;jmp     short BAD_COMMAND_POP
  8904 00002931 EB49                <1>         jmp     short BAD_COMMAND
  8905                              <1> chsfnc:	
  8906                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  8907 00002933 668B4305            <1> 	mov	ax, [ebx+5]
  8908 00002937 66C1E802            <1> 	SHR	AX,2
  8909 0000293B 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  8910                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  8911                              <1> 	;;PUSH	DX
  8912                              <1> 	;;MOV	DX,[HF_REG_PORT]
  8913                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  8914                              <1> 	;;POP	DX ; * 
  8915                              <1> 	;;POP	ES ; **
  8916                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  8917                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  8918                              <1> 	;;OR	AH,AL
  8919                              <1> 	;;MOV	[CONTROL_BYTE],AH
  8920                              <1> 	;
  8921 0000293E 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  8922 00002940 243F                <1> 	AND	AL,3FH
  8923 00002942 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  8924 00002945 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  8925 00002948 88C8                <1> 	MOV	AL,CL
  8926 0000294A C0E806              <1> 	SHR	AL,6
  8927 0000294D 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  8928                              <1> 	;;05/01/2015
  8929                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  8930 00002950 A0[E8690000]        <1> 	mov	al, [hf_m_s]
  8931 00002955 C0E004              <1> 	SHL	AL,4
  8932 00002958 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  8933 0000295B 08F0                <1> 	OR	AL,DH
  8934                              <1> 	;OR	AL,80H or 20H
  8935 0000295D 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  8936 0000295F 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  8937                              <1> su4:
  8938                              <1> 	;POP	ES ; **
  8939                              <1>         ;; 14/02/2015
  8940                              <1>         ;;POP   AX
  8941                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  8942                              <1>         ;;PUSH  AX
  8943                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  8944                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  8945                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  8946 00002962 6658                <1>         pop     ax ; ***
  8947 00002964 8845F9              <1>         mov     [CMD_BLOCK+1], al
  8948 00002967 29DB                <1>         sub	ebx, ebx
  8949 00002969 88E3                <1> 	mov     bl, ah
  8950                              <1>         ;xor     bh, bh
  8951                              <1>         ;sal     bx, 1
  8952 0000296B 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  8953                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  8954                              <1>         ;;CMP   AX,M1L                  ; TEST WITHIN RANGE
  8955                              <1>         ;;JNB   short BAD_COMMAND_POP
  8956                              <1>         ;cmp     bx, M1L
  8957 0000296F 83FB74              <1> 	cmp	ebx, M1L
  8958 00002972 7308                <1> 	jnb	short BAD_COMMAND
  8959                              <1>         ;xchg    bx, si
  8960 00002974 87DE                <1>         xchg	ebx, esi
  8961                              <1> 	;;;POP	AX			; RESTORE AX
  8962                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  8963                              <1> 	
  8964                              <1> 	;;PUSH	CX
  8965                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  8966                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  8967                              <1> 	;SHR	CX,4
  8968                              <1> 	;MOV	AX,ES
  8969                              <1> 	;ADD	AX,CX
  8970                              <1> 	;MOV	ES,AX
  8971                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  8972                              <1> 	;;POP	AX
  8973                              <1> 	;;POP	CX
  8974                              <1> 	;;JMP	word [CS:SI+M1]
  8975                              <1> 	;jmp	word [SI+M1]
  8976 00002976 FFA6[C4270000]      <1> 	jmp	dword [esi+M1]
  8977                              <1> ;;BAD_COMMAND_POP:
  8978                              <1> ;;	POP	AX
  8979                              <1> ;;	POP	BX
  8980                              <1> BAD_COMMAND:
  8981 0000297C C605[8F6F0000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  8982 00002983 B000                <1> 	MOV	AL,0
  8983 00002985 C3                  <1> 	RETn
  8984                              <1> 
  8985                              <1> ;----------------------------------------
  8986                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  8987                              <1> ;----------------------------------------
  8988                              <1> 
  8989                              <1> ; 18-1-2015 : one controller reset (not other one)
  8990                              <1> 
  8991                              <1> DISK_RESET:
  8992 00002986 FA                  <1> 	CLI
  8993 00002987 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  8994                              <1> 	;JMP	$+2
  8995                              <1> 	IODELAY
  8996 00002989 EB00                <2>  jmp short $+2
  8997 0000298B EB00                <2>  jmp short $+2
  8998                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  8999 0000298D 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  9000 0000298F E6A1                <1> 	OUT	INTB01,AL
  9001 00002991 FB                  <1> 	STI				; START INTERRUPTS
  9002                              <1> 	; 14/02/2015
  9003 00002992 6689D7              <1> 	mov	di, dx	
  9004                              <1> 	; 04/01/2015
  9005                              <1> 	;xor	di,di
  9006                              <1> drst0:
  9007 00002995 B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  9008                              <1> 	;MOV	DX,HF_REG_PORT
  9009 00002997 668B15[E6690000]    <1> 	MOV	DX,[HF_REG_PORT]
  9010 0000299E EE                  <1> 	OUT	DX,AL			; RESET
  9011                              <1> ;	MOV	CX,10			; DELAY COUNT
  9012                              <1> ;DRD:	DEC	CX
  9013                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  9014                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  9015 0000299F B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  9016 000029A4 E873EBFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  9017                              <1>                                         ; 40 micro seconds)
  9018 000029A9 A0[916F0000]        <1> 	mov	al,[CONTROL_BYTE]
  9019 000029AE 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  9020 000029B0 EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  9021 000029B1 E80E040000          <1> 	CALL	NOT_BUSY
  9022 000029B6 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  9023 000029B8 668B15[E4690000]    <1> 	MOV	DX,[HF_PORT]
  9024 000029BF FEC2                <1> 	inc	dl  ; HF_PORT+1
  9025                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  9026                              <1>         ;mov     cl, 10
  9027 000029C1 B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  9028                              <1> drst1:
  9029 000029C6 EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  9030 000029C7 3C01                <1> 	CMP	AL,1
  9031                              <1> 	; 04/01/2015
  9032 000029C9 740A                <1> 	jz	short drst2
  9033                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  9034                              <1>         	; Drive/Head Register - bit 4
  9035 000029CB E2F9                <1> 	loop	drst1
  9036                              <1> DRERR:	
  9037 000029CD C605[8F6F0000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  9038 000029D4 C3                  <1> 	RETn
  9039                              <1> drst2:
  9040                              <1> 	; 14/02/2015
  9041 000029D5 6689FA              <1> 	mov	dx,di
  9042                              <1> ;drst3:
  9043                              <1> ;	; 05/01/2015
  9044                              <1> ;	shl 	di,1
  9045                              <1> ;	; 04/01/2015
  9046                              <1> ;	mov	ax,[di+hd_cports]
  9047                              <1> ;	cmp	ax,[HF_REG_PORT]
  9048                              <1> ;	je	short drst4
  9049                              <1> ;	mov	[HF_REG_PORT], ax
  9050                              <1> ;	; 03/01/2015
  9051                              <1> ;	mov	ax,[di+hd_ports]
  9052                              <1> ;       mov     [HF_PORT], ax
  9053                              <1> ;	; 05/01/2014
  9054                              <1> ;	shr	di,1
  9055                              <1> ;	; 04/01/2015
  9056                              <1> ;	jmp	short drst0	; reset other controller
  9057                              <1> ;drst4:
  9058                              <1> ;	; 05/01/2015
  9059                              <1> ;	shr	di,1
  9060                              <1> ;	mov	al,[di+hd_dregs]
  9061                              <1> ;	and	al,10h ; bit 4 only
  9062                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  9063                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  9064                              <1> 	;
  9065 000029D8 A0[E8690000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  9066 000029DD A801                <1> 	test	al,1
  9067                              <1> ;	jnz	short drst6
  9068 000029DF 7516                <1>         jnz     short drst4
  9069 000029E1 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  9070                              <1> ;drst5:
  9071                              <1> drst3:
  9072 000029E5 E811010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  9073                              <1> 	;mov	dx,di
  9074 000029EA E8C9010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  9075                              <1> 	; 04/01/2014
  9076                              <1> ;	inc	di
  9077                              <1> ;	mov	dx,di
  9078                              <1> ;	cmp	dl,[HF_NUM]
  9079                              <1> ;	jb	short drst3
  9080                              <1> ;DRE:
  9081 000029EF C605[8F6F0000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  9082 000029F6 C3                  <1> 	RETn
  9083                              <1> ;drst6:
  9084                              <1> drst4:		; Drive/Head Register - bit 4
  9085 000029F7 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  9086                              <1>         ;jmp    short drst5
  9087 000029FB EBE8                <1>         jmp     short drst3
  9088                              <1> 
  9089                              <1> ;----------------------------------------
  9090                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  9091                              <1> ;----------------------------------------
  9092                              <1> 
  9093                              <1> RETURN_STATUS:
  9094 000029FD A0[8F6F0000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  9095 00002A02 C605[8F6F0000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  9096 00002A09 C3                  <1> 	RETn
  9097                              <1> 
  9098                              <1> ;----------------------------------------
  9099                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  9100                              <1> ;----------------------------------------
  9101                              <1> 
  9102                              <1> DISK_READ:
  9103 00002A0A C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  9104 00002A0E E930020000          <1>         JMP     COMMANDI
  9105                              <1> 
  9106                              <1> ;----------------------------------------
  9107                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  9108                              <1> ;----------------------------------------
  9109                              <1> 
  9110                              <1> DISK_WRITE:
  9111 00002A13 C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  9112 00002A17 E97C020000          <1>         JMP     COMMANDO
  9113                              <1> 
  9114                              <1> ;----------------------------------------
  9115                              <1> ;	DISK VERIFY	     (AH = 04H) :
  9116                              <1> ;----------------------------------------
  9117                              <1> 
  9118                              <1> DISK_VERF:
  9119 00002A1C C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  9120 00002A20 E8EA020000          <1> 	CALL	COMMAND
  9121 00002A25 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  9122 00002A27 E85C030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  9123 00002A2C 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  9124 00002A2E E8E9030000          <1> 	CALL	CHECK_STATUS
  9125                              <1> VERF_EXIT:
  9126 00002A33 C3                  <1> 	RETn
  9127                              <1> 
  9128                              <1> ;----------------------------------------
  9129                              <1> ;	FORMATTING	     (AH = 05H) :
  9130                              <1> ;----------------------------------------
  9131                              <1> 
  9132                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  9133 00002A34 C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  9134                              <1> 	;PUSH	ES
  9135                              <1> 	;PUSH	BX
  9136 00002A38 53                  <1> 	push	ebx
  9137 00002A39 E88E040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  9138                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  9139 00002A3E 8A430E              <1> 	mov	al, [ebx+14]
  9140 00002A41 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  9141 00002A44 5B                  <1> 	pop	ebx
  9142                              <1> 	;POP	BX
  9143                              <1> 	;POP	ES
  9144 00002A45 E955020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  9145                              <1> 
  9146                              <1> ;----------------------------------------
  9147                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  9148                              <1> ;----------------------------------------
  9149                              <1> 
  9150                              <1> READ_DASD_TYPE:
  9151                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  9152 00002A4A 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9153                              <1> 	;PUSH	ES
  9154 00002A4B 53                  <1> 	PUSH	eBX
  9155                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  9156                              <1> 	;push	cs
  9157                              <1> 	;pop	ds
  9158 00002A4C 66BB1000            <1>         mov	bx, KDATA
  9159 00002A50 8EDB                <1> 	mov	ds, bx
  9160                              <1> 	;mov	es, bx
  9161 00002A52 C605[8F6F0000]00    <1> 	MOV     byte [DISK_STATUS1],0
  9162 00002A59 8A1D[906F0000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  9163 00002A5F 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  9164 00002A62 38D3                <1> 	CMP	BL,DL
  9165 00002A64 7625                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  9166 00002A66 E861040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  9167                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  9168 00002A6B 8A4302              <1> 	mov	al, [ebx+2]
  9169                              <1> 	;MOV	CL,[ES:BX+14]
  9170 00002A6E 8A4B0E              <1> 	mov	cl, [ebx+14]
  9171 00002A71 F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  9172                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  9173 00002A73 668B0B              <1> 	mov	cx ,[ebx]
  9174                              <1> 	;
  9175                              <1> 	; 02/01/2015 
  9176                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  9177                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  9178 00002A76 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  9179                              <1> 	;
  9180 00002A78 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  9181 00002A7B 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  9182 00002A7E 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  9183                              <1> 	;SUB	AX,AX
  9184 00002A81 28C0                <1> 	sub	al, al
  9185 00002A83 B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  9186 00002A85 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  9187                              <1> 	;POP	ES
  9188 00002A86 1F                  <1> 	POP	DS
  9189 00002A87 F8                  <1> 	CLC				; CLEAR CARRY
  9190                              <1> 	;RETf	2
  9191 00002A88 CA0400              <1> 	retf	4
  9192                              <1> RDT_NOT_PRESENT:
  9193 00002A8B 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  9194 00002A8E 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  9195 00002A91 6689C2              <1> 	MOV	DX,AX
  9196 00002A94 EBEF                <1> 	JMP	short RDT2
  9197                              <1> 
  9198                              <1> ;----------------------------------------
  9199                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  9200                              <1> ;----------------------------------------
  9201                              <1> 
  9202                              <1> GET_PARM_N:
  9203                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  9204 00002A96 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9205                              <1> 	;PUSH	ES
  9206 00002A97 53                  <1> 	PUSH	eBX
  9207                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  9208                              <1> 	;MOV	DS,AX
  9209                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  9210                              <1> 	;JZ	short G0
  9211                              <1> 	;LES	BX,@HF1_TBL_VEC
  9212                              <1> 	;JMP	SHORT G1
  9213                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  9214                              <1> ;G1:
  9215                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  9216                              <1> 	; 22/12/2014
  9217                              <1> 	;push	cs
  9218                              <1> 	;pop	ds
  9219 00002A98 66BB1000            <1> 	mov	bx, KDATA
  9220 00002A9C 8EDB                <1> 	mov	ds, bx
  9221                              <1> 	;mov	es, bx
  9222                              <1> 	;
  9223 00002A9E 80EA80              <1> 	SUB	DL,80H
  9224 00002AA1 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  9225 00002AA4 7341                <1> 	JAE	short G4
  9226                              <1> 	;
  9227 00002AA6 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  9228                              <1> 	; 22/12/2014
  9229 00002AA8 88D3                <1> 	mov	bl, dl
  9230                              <1> 	;xor	bh, bh  
  9231 00002AAA C0E302              <1> 	shl	bl, 2			; convert index to offset
  9232                              <1> 	;add	bx, HF_TBL_VEC
  9233 00002AAD 81C3[946F0000]      <1> 	add	ebx, HF_TBL_VEC
  9234                              <1> 	;mov	ax, [bx+2]
  9235                              <1> 	;mov	es, ax			; dpt segment
  9236                              <1> 	;mov	bx, [bx]		; dpt offset
  9237 00002AB3 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  9238                              <1> 
  9239 00002AB5 C605[8F6F0000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9240                              <1>         ;MOV     AX,[ES:BX]              ; MAX NUMBER OF CYLINDERS
  9241 00002ABC 668B03              <1> 	mov	ax, [ebx]
  9242                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  9243 00002ABF 6648                <1> 	dec	ax			; max. cylinder number
  9244 00002AC1 88C5                <1> 	MOV	CH,AL
  9245 00002AC3 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  9246 00002AC7 66D1E8              <1> 	SHR	AX,1
  9247 00002ACA 66D1E8              <1> 	SHR	AX,1
  9248                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  9249 00002ACD 0A430E              <1> 	or	al, [ebx+14]
  9250 00002AD0 88C1                <1> 	MOV	CL,AL
  9251                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  9252 00002AD2 8A7302              <1> 	mov	dh, [ebx+2]
  9253 00002AD5 FECE                <1> 	DEC	DH			; 0-N RANGE
  9254 00002AD7 8A15[906F0000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  9255 00002ADD 6629C0              <1> 	SUB	AX,AX
  9256                              <1>         ;27/12/2014 
  9257                              <1> 	; ES:DI = Address of disk parameter table from BIOS
  9258                              <1> 	;(Programmer's Guide to the AMIBIOS - 1993)
  9259                              <1> 	;mov	di, bx			; HDPT offset
  9260 00002AE0 89DF                <1> 	mov	edi, ebx
  9261                              <1> G5:
  9262 00002AE2 5B                  <1> 	POP	eBX			; RESTORE REGISTERS
  9263                              <1> 	;POP	ES
  9264 00002AE3 1F                  <1> 	POP	DS
  9265                              <1> 	;RETf	2
  9266 00002AE4 CA0400              <1> 	retf	4
  9267                              <1> G4:
  9268 00002AE7 C605[8F6F0000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  9269 00002AEE B407                <1> 	MOV	AH,INIT_FAIL
  9270 00002AF0 28C0                <1> 	SUB	AL,AL
  9271 00002AF2 6629D2              <1> 	SUB	DX,DX
  9272 00002AF5 6629C9              <1> 	SUB	CX,CX
  9273 00002AF8 F9                  <1> 	STC				; SET ERROR FLAG
  9274 00002AF9 EBE7                <1> 	JMP	short G5
  9275                              <1> 
  9276                              <1> ;----------------------------------------
  9277                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  9278                              <1> ;----------------------------------------
  9279                              <1> 	; 03/01/2015
  9280                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  9281                              <1> 	; logical sector per logical track
  9282                              <1> 	; and logical heads - 1 would be set but
  9283                              <1> 	; it is seen as it will be good
  9284                              <1> 	; if physical parameters will be set here
  9285                              <1> 	; because, number of heads <= 16.
  9286                              <1> 	; (logical heads usually more than 16)
  9287                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  9288                              <1> 	;	== INT 13h physical parameters
  9289                              <1> 
  9290                              <1> ;INIT_DRV:
  9291                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  9292                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  9293                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  9294                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  9295                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  9296                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  9297                              <1> ;	OR	AH,AL			; TO MAX HEAD
  9298                              <1> ;	MOV	[CMD_BLOCK+5],AH
  9299                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  9300                              <1> ;	MOV	[CMD_BLOCK+1],AL
  9301                              <1> ;	SUB	AX,AX
  9302                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  9303                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  9304                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  9305                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  9306                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  9307                              <1> ;	CALL	CHECK_STATUS
  9308                              <1> ;INIT_EXIT:
  9309                              <1> ;	RETn
  9310                              <1> 
  9311                              <1> ; 04/01/2015
  9312                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  9313                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  9314                              <1> INIT_DRV:
  9315                              <1> 	;xor	ah,ah
  9316 00002AFB 31C0                <1> 	xor	eax, eax ; 21/02/2015
  9317 00002AFD B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  9318 00002AFF 3825[A46F0000]      <1>         cmp     [LBAMode], ah   ; 0
  9319 00002B05 7702                <1> 	ja	short idrv0
  9320 00002B07 B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  9321                              <1> idrv0:
  9322                              <1> 	; DL = drive number (0 based)
  9323 00002B09 E8BE030000          <1> 	call	GET_VEC
  9324                              <1> 	;push	bx
  9325 00002B0E 53                  <1> 	push	ebx ; 21/02/2015
  9326                              <1> 	;add	bx,ax
  9327 00002B0F 01C3                <1> 	add	ebx, eax
  9328                              <1> 	;; 05/01/2015
  9329 00002B11 8A25[E8690000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  9330                              <1> 	;;and 	ah,1 
  9331 00002B17 C0E404              <1> 	shl	ah,4
  9332 00002B1A 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  9333                              <1> 	;mov	al,[es:bx]
  9334 00002B1D 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  9335 00002B1F FEC8                <1> 	dec	al	 ; last head number 
  9336                              <1> 	;and	al,0Fh
  9337 00002B21 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  9338                              <1> 	;
  9339 00002B23 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  9340 00002B27 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  9341                              <1> 	;pop	bx
  9342 00002B2A 5B                  <1> 	pop	ebx
  9343 00002B2B 29C0                <1> 	sub	eax, eax ; 21/02/2015
  9344 00002B2D B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  9345 00002B2F 803D[A46F0000]00    <1> 	cmp	byte [LBAMode], 0
  9346 00002B36 7702                <1> 	ja	short idrv1
  9347 00002B38 B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  9348                              <1> idrv1:
  9349                              <1> 	;xor	ah,ah
  9350                              <1> 	;add	bx,ax
  9351 00002B3A 01C3                <1> 	add	ebx, eax ; 21/02/2015
  9352                              <1> 	;mov	al,[es:bx]
  9353                              <1> 			; sector number
  9354 00002B3C 8A03                <1> 	mov	al, [ebx]
  9355 00002B3E 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  9356 00002B41 28C0                <1> 	sub	al,al
  9357 00002B43 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  9358 00002B46 E8C4010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  9359 00002B4B 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  9360 00002B4D E872020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  9361 00002B52 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  9362 00002B54 E8C3020000          <1> 	call	CHECK_STATUS
  9363                              <1> INIT_EXIT:
  9364 00002B59 C3                  <1> 	RETn
  9365                              <1> 
  9366                              <1> ;----------------------------------------
  9367                              <1> ;	READ LONG	     (AH = 0AH) :
  9368                              <1> ;----------------------------------------
  9369                              <1> 
  9370                              <1> RD_LONG:
  9371                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  9372 00002B5A C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  9373 00002B5E E9E0000000          <1>         JMP     COMMANDI
  9374                              <1> 
  9375                              <1> ;----------------------------------------
  9376                              <1> ;	WRITE LONG	     (AH = 0BH) :
  9377                              <1> ;----------------------------------------
  9378                              <1> 
  9379                              <1> WR_LONG:
  9380                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  9381 00002B63 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  9382 00002B67 E92C010000          <1>         JMP     COMMANDO
  9383                              <1> 
  9384                              <1> ;----------------------------------------
  9385                              <1> ;	SEEK		     (AH = 0CH) :
  9386                              <1> ;----------------------------------------
  9387                              <1> 
  9388                              <1> DISK_SEEK:
  9389 00002B6C C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  9390 00002B70 E89A010000          <1> 	CALL	COMMAND
  9391 00002B75 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  9392 00002B77 E80C020000          <1> 	CALL	_WAIT
  9393 00002B7C 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  9394 00002B7E E899020000          <1> 	CALL	CHECK_STATUS
  9395 00002B83 803D[8F6F0000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  9396 00002B8A 7507                <1> 	JNE	short DS_EXIT
  9397 00002B8C C605[8F6F0000]00    <1>         MOV     byte [DISK_STATUS1],0
  9398                              <1> DS_EXIT:
  9399 00002B93 C3                  <1> 	RETn
  9400                              <1> 
  9401                              <1> ;----------------------------------------
  9402                              <1> ;	TEST DISK READY      (AH = 10H) :
  9403                              <1> ;----------------------------------------
  9404                              <1> 
  9405                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  9406 00002B94 E82B020000          <1> 	CALL	NOT_BUSY
  9407 00002B99 751C                <1> 	JNZ	short TR_EX
  9408 00002B9B 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  9409 00002B9E 668B15[E4690000]    <1> 	MOV	DX,[HF_PORT]
  9410 00002BA5 80C206              <1> 	add	dl,6
  9411 00002BA8 EE                  <1> 	OUT	DX,AL
  9412 00002BA9 E886020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  9413 00002BAE 7507                <1> 	JNZ	short TR_EX
  9414 00002BB0 C605[8F6F0000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  9415                              <1> TR_EX:	
  9416 00002BB7 C3                  <1> 	RETn
  9417                              <1> 
  9418                              <1> ;----------------------------------------
  9419                              <1> ;	RECALIBRATE	     (AH = 11H) :
  9420                              <1> ;----------------------------------------
  9421                              <1> 
  9422                              <1> HDISK_RECAL:
  9423 00002BB8 C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  9424 00002BBC E84E010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  9425 00002BC1 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  9426 00002BC3 E8C0010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  9427 00002BC8 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  9428 00002BCA E8B9010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  9429 00002BCF 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  9430                              <1> RECAL_X:
  9431 00002BD1 E846020000          <1> 	CALL	CHECK_STATUS
  9432 00002BD6 803D[8F6F0000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  9433 00002BDD 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  9434 00002BDF C605[8F6F0000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9435                              <1> RECAL_EXIT:
  9436 00002BE6 803D[8F6F0000]00    <1>         CMP     byte [DISK_STATUS1],0
  9437 00002BED C3                  <1> 	RETn
  9438                              <1> 
  9439                              <1> ;----------------------------------------
  9440                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  9441                              <1> ;----------------------------------------
  9442                              <1> 
  9443                              <1> CTLR_DIAGNOSTIC:
  9444 00002BEE FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  9445 00002BEF E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9446                              <1> 	;AND	AL,0BFH
  9447 00002BF1 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  9448                              <1> 	;JMP	$+2
  9449                              <1> 	IODELAY
  9450 00002BF3 EB00                <2>  jmp short $+2
  9451 00002BF5 EB00                <2>  jmp short $+2
  9452 00002BF7 E6A1                <1> 	OUT	INTB01,AL
  9453                              <1> 	IODELAY
  9454 00002BF9 EB00                <2>  jmp short $+2
  9455 00002BFB EB00                <2>  jmp short $+2
  9456 00002BFD E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9457 00002BFF 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9458                              <1> 	;JMP	$+2
  9459                              <1> 	IODELAY
  9460 00002C01 EB00                <2>  jmp short $+2
  9461 00002C03 EB00                <2>  jmp short $+2
  9462 00002C05 E621                <1> 	OUT	INTA01,AL
  9463 00002C07 FB                  <1> 	STI
  9464 00002C08 E8B7010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  9465 00002C0D 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  9466                              <1> 	;MOV	DX, HF_PORT+7
  9467 00002C0F 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]
  9468 00002C16 80C207              <1> 	add	dl, 7
  9469 00002C19 B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  9470 00002C1B EE                  <1> 	OUT	DX,AL
  9471 00002C1C E8A3010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  9472 00002C21 B480                <1> 	MOV	AH,TIME_OUT
  9473 00002C23 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  9474                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  9475 00002C25 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]
  9476 00002C2C FEC2                <1> 	inc	dl
  9477 00002C2E EC                  <1> 	IN	AL,DX
  9478 00002C2F A2[866F0000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  9479 00002C34 B400                <1> 	MOV	AH,0
  9480 00002C36 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  9481 00002C38 7402                <1> 	JE	SHORT CD_EXIT
  9482 00002C3A B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  9483                              <1> CD_EXIT:
  9484 00002C3C 8825[8F6F0000]      <1> 	MOV	[DISK_STATUS1],AH
  9485 00002C42 C3                  <1> 	RETn
  9486                              <1> 
  9487                              <1> ;----------------------------------------
  9488                              <1> ; COMMANDI				:
  9489                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  9490                              <1> ;	NSECTOR RETURNS ZERO		:
  9491                              <1> ;----------------------------------------
  9492                              <1> COMMANDI:
  9493 00002C43 E85A020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9494 00002C48 724D                <1> 	JC	short CMD_ABORT
  9495                              <1> 	;MOV	DI,BX
  9496 00002C4A 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  9497 00002C4C E8BE000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9498 00002C51 7544                <1> 	JNZ	short CMD_ABORT
  9499                              <1> CMD_I1:
  9500 00002C53 E830010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  9501 00002C58 753D                <1> 	JNZ	short TM_OUT		; TIME OUT
  9502                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  9503 00002C5A B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  9504                              <1> 	;MOV	DX,HF_PORT
  9505 00002C5F 668B15[E4690000]    <1> 	mov	dx,[HF_PORT]
  9506 00002C66 FA                  <1> 	CLI
  9507 00002C67 FC                  <1> 	CLD
  9508 00002C68 F3666D              <1> 	REP	INSW			; GET THE SECTOR
  9509 00002C6B FB                  <1> 	STI
  9510 00002C6C F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  9511 00002C70 7419                <1> 	JZ	CMD_I3
  9512 00002C72 E87A010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9513 00002C77 721E                <1> 	JC	short TM_OUT
  9514                              <1> 	;MOV	DX,HF_PORT
  9515 00002C79 668B15[E4690000]    <1> 	mov	dx,[HF_PORT]
  9516                              <1> 	;MOV	CX,4			; GET ECC BYTES
  9517 00002C80 B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  9518 00002C85 EC                  <1> CMD_I2: IN	AL,DX
  9519                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  9520 00002C86 8807                <1> 	mov 	[edi], al ; 21/02/2015
  9521 00002C88 47                  <1> 	INC	eDI
  9522 00002C89 E2FA                <1> 	LOOP	CMD_I2
  9523 00002C8B E88C010000          <1> CMD_I3: CALL	CHECK_STATUS
  9524 00002C90 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  9525 00002C92 FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  9526 00002C95 75BC                <1> 	JNZ	SHORT CMD_I1
  9527                              <1> CMD_ABORT:
  9528 00002C97 C3                  <1> TM_OUT: RETn
  9529                              <1> 
  9530                              <1> ;----------------------------------------
  9531                              <1> ; COMMANDO				:
  9532                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  9533                              <1> ;	NSECTOR RETURNS ZERO		:
  9534                              <1> ;----------------------------------------
  9535                              <1> COMMANDO:
  9536 00002C98 E805020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9537 00002C9D 72F8                <1> 	JC	short CMD_ABORT
  9538 00002C9F 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  9539 00002CA1 E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9540 00002CA6 75EF                <1> 	JNZ	short CMD_ABORT
  9541 00002CA8 E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9542 00002CAD 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  9543                              <1> CMD_O1: ;PUSH	DS
  9544                              <1> 	;PUSH	ES			; MOVE ES TO DS
  9545                              <1> 	;POP	DS
  9546                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  9547                              <1> 	;MOV	DX,HF_PORT
  9548                              <1> 	; 01/02/2015
  9549 00002CAF 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]
  9550                              <1> 	;push	es
  9551                              <1> 	;pop	ds
  9552                              <1> 	;mov	cx, 256
  9553 00002CB6 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  9554 00002CBB FA                  <1> 	CLI
  9555 00002CBC FC                  <1> 	CLD
  9556 00002CBD F3666F              <1> 	REP	OUTSW
  9557 00002CC0 FB                  <1> 	STI
  9558                              <1> 	;POP	DS			; RESTORE DS
  9559 00002CC1 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  9560 00002CC5 7419                <1> 	JZ	short CMD_O3
  9561 00002CC7 E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9562 00002CCC 72C9                <1> 	JC	short TM_OUT
  9563                              <1> 	;MOV	DX,HF_PORT
  9564 00002CCE 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]
  9565                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  9566 00002CD5 B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  9567                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  9568 00002CDA 8A06                <1> 	mov	al, [esi]
  9569 00002CDC EE                  <1> 	OUT	DX,AL
  9570 00002CDD 46                  <1> 	INC	eSI
  9571 00002CDE E2FA                <1> 	LOOP	CMD_O2
  9572                              <1> CMD_O3:
  9573 00002CE0 E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  9574 00002CE5 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  9575 00002CE7 E830010000          <1> 	CALL	CHECK_STATUS
  9576 00002CEC 75A9                <1> 	JNZ	short CMD_ABORT
  9577 00002CEE F605[856F0000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  9578 00002CF5 75B8                <1> 	JNZ	SHORT CMD_O1
  9579                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  9580 00002CF7 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]
  9581                              <1> 	;add	dl, 2
  9582 00002CFE FEC2                <1> 	inc	dl
  9583 00002D00 FEC2                <1> 	inc	dl
  9584 00002D02 EC                  <1> 	IN	AL,DX			;
  9585 00002D03 A8FF                <1> 	TEST	AL,0FFH 		;
  9586 00002D05 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  9587 00002D07 C605[8F6F0000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  9588                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  9589                              <1> CMD_O4:
  9590 00002D0E C3                  <1> 	RETn
  9591                              <1> 
  9592                              <1> ;--------------------------------------------------------
  9593                              <1> ; COMMAND						:
  9594                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  9595                              <1> ; OUTPUT						:
  9596                              <1> ;	BL = STATUS					:
  9597                              <1> ;	BH = ERROR REGISTER				:
  9598                              <1> ;--------------------------------------------------------
  9599                              <1> 
  9600                              <1> COMMAND:
  9601 00002D0F 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  9602                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  9603                              <1> COMMAND1:
  9604                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  9605 00002D10 E87FFEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  9606                              <1> 	;;POP	CX
  9607 00002D15 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  9608 00002D17 803D[8F6F0000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  9609                              <1> 	;JZ	short CMD_TIMEOUT
  9610                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  9611                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  9612 00002D1E 7507                <1> 	jne	short COMMAND4
  9613                              <1> CMD_TIMEOUT:
  9614 00002D20 C605[8F6F0000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9615                              <1> COMMAND4:
  9616 00002D27 5B                  <1> 	POP	eBX
  9617 00002D28 803D[8F6F0000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  9618 00002D2F C3                  <1> 	RETn
  9619                              <1> COMMAND2:
  9620 00002D30 5B                  <1> 	POP	eBX
  9621 00002D31 57                  <1> 	PUSH	eDI
  9622 00002D32 C605[876F0000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  9623 00002D39 FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  9624 00002D3A E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9625                              <1> 	;AND	AL,0BFH
  9626 00002D3C 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  9627                              <1> 	;JMP	$+2
  9628                              <1> 	IODELAY
  9629 00002D3E EB00                <2>  jmp short $+2
  9630 00002D40 EB00                <2>  jmp short $+2
  9631 00002D42 E6A1                <1> 	OUT	INTB01,AL
  9632 00002D44 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9633 00002D46 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9634                              <1> 	;JMP	$+2
  9635                              <1> 	IODELAY
  9636 00002D48 EB00                <2>  jmp short $+2
  9637 00002D4A EB00                <2>  jmp short $+2
  9638 00002D4C E621                <1> 	OUT	INTA01,AL
  9639 00002D4E FB                  <1> 	STI
  9640 00002D4F 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  9641                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  9642 00002D51 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]
  9643 00002D58 FEC2                <1> 	inc	dl
  9644 00002D5A F605[916F0000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  9645 00002D61 7411                <1> 	JZ	short COMMAND3
  9646 00002D63 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  9647 00002D66 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  9648 00002D68 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  9649 00002D6A 7208                <1> 	JB	short COMMAND3
  9650 00002D6C 3C40                <1> 	CMP	AL,40H
  9651 00002D6E 7704                <1> 	JA	short COMMAND3
  9652 00002D70 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  9653                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  9654                              <1> COMMAND3:
  9655 00002D74 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  9656 00002D78 EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  9657                              <1> 	IODELAY
  9658 00002D79 EB00                <2>  jmp short $+2
  9659 00002D7B EB00                <2>  jmp short $+2
  9660 00002D7D 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  9661 00002D7E 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  9662 00002D80 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  9663 00002D84 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  9664 00002D86 5F                  <1> 	POP	eDI
  9665 00002D87 C3                  <1> 	RETn				; ZERO FLAG IS SET
  9666                              <1> 
  9667                              <1> ;CMD_TIMEOUT:
  9668                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9669                              <1> ;COMMAND4:
  9670                              <1> ;	POP	BX
  9671                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9672                              <1> ;	RETn
  9673                              <1> 
  9674                              <1> ;----------------------------------------
  9675                              <1> ;	WAIT FOR INTERRUPT		:
  9676                              <1> ;----------------------------------------
  9677                              <1> ;WAIT:
  9678                              <1> _WAIT:
  9679 00002D88 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  9680                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  9681                              <1> 	;CLC
  9682                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  9683                              <1> 	;INT	15H
  9684                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  9685                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  9686                              <1> 
  9687                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  9688                              <1> 	;; 21/02/2015
  9689                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  9690                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  9691 00002D89 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  9692                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  9693                              <1> ;-----	WAIT LOOP
  9694                              <1> 
  9695                              <1> WT1:	
  9696                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
  9697 00002D8E F605[876F0000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  9698                              <1> 	;LOOPZ	WT1
  9699 00002D95 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
  9700                              <1> 	;DEC	BL
  9701                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
  9702                              <1> 
  9703                              <1> WT1_hi:
  9704 00002D97 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  9705 00002D99 A810                <1> 	test	al, 10h			; transition on memory
  9706 00002D9B 75FA                <1> 	jnz	short WT1_hi		; refresh.
  9707                              <1> WT1_lo:
  9708 00002D9D E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  9709 00002D9F A810                <1> 	test	al, 10h			
  9710 00002DA1 74FA                <1> 	jz	short WT1_lo
  9711 00002DA3 E2E9                <1> 	loop	WT1
  9712                              <1> 	;;or	bl, bl
  9713                              <1> 	;;jz	short WT2	
  9714                              <1> 	;;dec	bl
  9715                              <1> 	;;jmp	short WT1
  9716                              <1> 	;dec	bl
  9717                              <1> 	;jnz	short WT1	
  9718                              <1> 
  9719 00002DA5 C605[8F6F0000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  9720 00002DAC EB0E                <1> 	JMP	SHORT WT4
  9721 00002DAE C605[8F6F0000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  9722 00002DB5 C605[876F0000]00    <1> 	MOV	byte [HF_INT_FLAG],0
  9723 00002DBC 803D[8F6F0000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9724 00002DC3 C3                  <1> 	RETn
  9725                              <1> 
  9726                              <1> ;----------------------------------------
  9727                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  9728                              <1> ;----------------------------------------
  9729                              <1> NOT_BUSY:
  9730 00002DC4 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  9731                              <1> 	;PUSH	eBX
  9732                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  9733 00002DC5 668B15[E4690000]    <1> 	mov	DX, [HF_PORT]
  9734 00002DCC 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  9735                              <1> 	;MOV	BL,DELAY_1
  9736                              <1> 					; wait for 10 seconds
  9737                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  9738                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  9739                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  9740 00002DCF B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  9741                              <1> 	;
  9742                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
  9743                              <1> NB1:	
  9744 00002DD4 EC                  <1> 	IN	AL,DX			; CHECK STATUS
  9745                              <1> 	;TEST	AL,ST_BUSY
  9746 00002DD5 2480                <1> 	and	al, ST_BUSY
  9747                              <1> 	;LOOPNZ	NB1
  9748 00002DD7 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
  9749                              <1> 	;DEC	BL			
  9750                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
  9751                              <1> 
  9752 00002DD9 E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  9753 00002DDB A810                <1> 	TEST	AL,010H			; transition on memory
  9754 00002DDD 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  9755 00002DDF E461                <1> NB1_lo: IN	AL,SYS1
  9756 00002DE1 A810                <1> 	TEST	AL,010H
  9757 00002DE3 74FA                <1> 	JZ	short NB1_lo
  9758 00002DE5 E2ED                <1> 	LOOP	NB1
  9759                              <1> 	;dec	bl
  9760                              <1> 	;jnz	short NB1
  9761                              <1> 	;
  9762                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  9763                              <1> ;;	jb	short NB1
  9764                              <1> 	;
  9765                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
  9766                              <1> 	;JMP	SHORT NB3
  9767 00002DE7 B080                <1> 	mov	al, TIME_OUT
  9768                              <1> NB2:	
  9769                              <1> 	;MOV	byte [DISK_STATUS1],0
  9770                              <1> ;NB3:	
  9771                              <1> 	;POP	eBX
  9772 00002DE9 A2[8F6F0000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  9773                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9774 00002DEE 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  9775 00002DF0 C3                  <1> 	RETn
  9776                              <1> 
  9777                              <1> ;----------------------------------------
  9778                              <1> ;	WAIT FOR DATA REQUEST		:
  9779                              <1> ;----------------------------------------
  9780                              <1> WAIT_DRQ:
  9781                              <1> 	;MOV	CX,DELAY_3
  9782                              <1> 	;MOV	DX,HF_PORT+7
  9783 00002DF1 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]
  9784 00002DF8 80C207              <1> 	add	dl, 7
  9785                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
  9786                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  9787                              <1> 					; (but it is written as 2000
  9788                              <1> 					; micro seconds in ATORGS.ASM file
  9789                              <1> 					; of Award Bios - 1999, D1A0622)
  9790 00002DFB B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  9791 00002E00 EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  9792 00002E01 A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  9793 00002E03 7516                <1> 	JNZ	short WQ_OK
  9794                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  9795                              <1> WQ_hi:	
  9796 00002E05 E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  9797 00002E07 A810                <1> 	TEST	AL,010H			; transition on memory
  9798 00002E09 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  9799 00002E0B E461                <1> WQ_lo:  IN      AL,SYS1
  9800 00002E0D A810                <1> 	TEST	AL,010H
  9801 00002E0F 74FA                <1> 	JZ	SHORT WQ_lo
  9802 00002E11 E2ED                <1> 	LOOP	WQ_1
  9803                              <1> 
  9804 00002E13 C605[8F6F0000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  9805 00002E1A F9                  <1> 	STC
  9806                              <1> WQ_OK:
  9807 00002E1B C3                  <1> 	RETn
  9808                              <1> ;WQ_OK:	;CLC
  9809                              <1> ;	RETn
  9810                              <1> 
  9811                              <1> ;----------------------------------------
  9812                              <1> ;	CHECK FIXED DISK STATUS 	:
  9813                              <1> ;----------------------------------------
  9814                              <1> CHECK_STATUS:
  9815 00002E1C E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  9816 00002E21 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  9817 00002E23 A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  9818 00002E25 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  9819 00002E27 E847000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  9820                              <1> CHECK_S1:
  9821 00002E2C 803D[8F6F0000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  9822 00002E33 C3                  <1> 	RETn
  9823                              <1> 
  9824                              <1> ;----------------------------------------
  9825                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  9826                              <1> ;----------------------------------------
  9827                              <1> CHECK_ST:
  9828                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
  9829 00002E34 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]
  9830 00002E3B 80C207              <1> 	add	dl, 7
  9831 00002E3E EC                  <1> 	IN	AL,DX
  9832 00002E3F A2[856F0000]        <1> 	MOV	[HF_STATUS],AL
  9833 00002E44 B400                <1> 	MOV	AH,0
  9834 00002E46 A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  9835 00002E48 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  9836 00002E4A B4CC                <1> 	MOV	AH,WRITE_FAULT
  9837 00002E4C A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  9838 00002E4E 7514                <1> 	JNZ	short CKST_EXIT
  9839 00002E50 B4AA                <1> 	MOV	AH,NOT_RDY
  9840 00002E52 A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  9841 00002E54 740E                <1> 	JZ	short CKST_EXIT
  9842 00002E56 B440                <1> 	MOV	AH,BAD_SEEK
  9843 00002E58 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  9844 00002E5A 7408                <1> 	JZ	short CKST_EXIT
  9845 00002E5C B411                <1> 	MOV	AH,DATA_CORRECTED
  9846 00002E5E A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  9847 00002E60 7502                <1> 	JNZ	short CKST_EXIT
  9848 00002E62 B400                <1> 	MOV	AH,0
  9849                              <1> CKST_EXIT:
  9850 00002E64 8825[8F6F0000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  9851 00002E6A 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  9852 00002E6D 7403                <1> 	JZ	short CKST_EX1
  9853 00002E6F 80FC00              <1> 	CMP	AH,0
  9854                              <1> CKST_EX1:
  9855 00002E72 C3                  <1> 	RETn
  9856                              <1> 
  9857                              <1> ;----------------------------------------
  9858                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  9859                              <1> ;----------------------------------------
  9860                              <1> CHECK_ER:
  9861                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
  9862 00002E73 668B15[E4690000]    <1> 	mov	dx, [HF_PORT]		;
  9863 00002E7A FEC2                <1> 	inc	dl
  9864 00002E7C EC                  <1> 	IN	AL,DX
  9865 00002E7D A2[866F0000]        <1> 	MOV	[HF_ERROR],AL
  9866 00002E82 53                  <1> 	PUSH	eBX ; 21/02/2015
  9867 00002E83 B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  9868 00002E88 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  9869 00002E8A 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  9870 00002E8C E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  9871 00002E8E BB[D8690000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  9872 00002E93 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  9873                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  9874                              <1> 	;mov	ah, [bx]
  9875 00002E95 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  9876 00002E97 8825[8F6F0000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  9877 00002E9D 5B                  <1> 	POP	eBX
  9878 00002E9E 80FC00              <1> 	CMP	AH,0
  9879 00002EA1 C3                  <1> 	RETn
  9880                              <1> 
  9881                              <1> ;--------------------------------------------------------
  9882                              <1> ; CHECK_DMA						:
  9883                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  9884                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  9885                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  9886                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  9887                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  9888                              <1> ;  -ERROR OTHERWISE					:
  9889                              <1> ;--------------------------------------------------------
  9890                              <1> CHECK_DMA:
  9891 00002EA2 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  9892 00002EA4 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  9893 00002EA8 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  9894 00002EAC 7404                <1> 	JZ	short CKD1
  9895 00002EAE 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  9896 00002EB2 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  9897 00002EB5 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  9898 00002EB7 7208                <1> 	JB	short CKDERR		; TOO MANY
  9899 00002EB9 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  9900 00002EBB 7204                <1> 	JB	short CKDERR		; ERROR
  9901 00002EBD F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  9902 00002EBE 6658                <1> 	POP	AX
  9903 00002EC0 C3                  <1> 	RETn				; NORMAL RETURN
  9904 00002EC1 F9                  <1> CKDERR: STC				; INDICATE ERROR
  9905 00002EC2 C605[8F6F0000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  9906 00002EC9 6658                <1> 	POP	AX
  9907 00002ECB C3                  <1> 	RETn
  9908                              <1> 
  9909                              <1> ;----------------------------------------
  9910                              <1> ;	SET UP ES:BX-> DISK PARMS	:
  9911                              <1> ;----------------------------------------
  9912                              <1> 					
  9913                              <1> ; INPUT -> DL = 0 based drive number
  9914                              <1> ; OUTPUT -> ES:BX = disk parameter table address
  9915                              <1> 
  9916                              <1> GET_VEC:
  9917                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
  9918                              <1> 	;MOV	ES,AX
  9919                              <1> 	;TEST	DL,1
  9920                              <1> 	;JZ	short GV_0
  9921                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  9922                              <1> ;	JMP	SHORT GV_EXIT
  9923                              <1> ;GV_0:
  9924                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  9925                              <1> ;
  9926                              <1> 	;xor	bh, bh
  9927 00002ECC 31DB                <1> 	xor	ebx, ebx
  9928 00002ECE 88D3                <1> 	mov	bl, dl
  9929                              <1> 	;;02/01/2015
  9930                              <1> 	;;shl	bl, 1			; port address offset
  9931                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  9932                              <1> 	;;shl	bl, 1			; dpt pointer offset
  9933 00002ED0 C0E302              <1> 	shl	bl, 2	;;
  9934                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  9935 00002ED3 81C3[946F0000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  9936                              <1> 	;push	word [bx+2]		; dpt segment
  9937                              <1> 	;pop	es
  9938                              <1> 	;mov	bx, [bx]		; dpt offset
  9939 00002ED9 8B1B                <1> 	mov	ebx, [ebx]		
  9940                              <1> ;GV_EXIT:
  9941 00002EDB C3                  <1> 	RETn
  9942                              <1> 
  9943                              <1> hdc1_int: ; 21/02/2015
  9944                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  9945                              <1> ;								:
  9946                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  9947                              <1> ;								:
  9948                              <1> ;----------------------------------------------------------------
  9949                              <1> 
  9950                              <1> ; 22/12/2014
  9951                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  9952                              <1> ;	 '11/15/85'
  9953                              <1> ; AWARD BIOS 1999 (D1A0622) 
  9954                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  9955                              <1> 
  9956                              <1> ;int_76h:
  9957                              <1> HD_INT:
  9958 00002EDC 6650                <1> 	PUSH	AX
  9959 00002EDE 1E                  <1> 	PUSH	DS
  9960                              <1> 	;CALL	DDS
  9961                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  9962 00002EDF 66B81000            <1> 	mov	ax, KDATA
  9963 00002EE3 8ED8                <1> 	mov 	ds, ax
  9964                              <1> 	;
  9965                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  9966                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
  9967 00002EE5 C605[876F0000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  9968                              <1> 	;
  9969 00002EEC 6652                <1> 	push	dx
  9970 00002EEE 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  9971                              <1> 					; Clear Controller
  9972                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  9973 00002EF2 EC                  <1> 	in	al, dx			;
  9974 00002EF3 665A                <1> 	pop	dx
  9975                              <1> 	NEWIODELAY
  9976 00002EF5 E6EB                <2>  out 0ebh,al
  9977                              <1> 	;
  9978 00002EF7 B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  9979 00002EF9 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  9980                              <1> 	;JMP	$+2			; WAIT
  9981                              <1> 	NEWIODELAY
  9982 00002EFB E6EB                <2>  out 0ebh,al
  9983 00002EFD E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  9984 00002EFF 1F                  <1> 	POP	DS
  9985                              <1> 	;STI				; RE-ENABLE INTERRUPTS
  9986                              <1> 	;MOV	AX,9100H		; DEVICE POST
  9987                              <1> 	;INT	15H			;  INTERRUPT
  9988                              <1> irq15_iret: ; 25/02/2015
  9989 00002F00 6658                <1> 	POP	AX
  9990 00002F02 CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  9991                              <1> 
  9992                              <1> hdc2_int: ; 21/02/2015
  9993                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
  9994                              <1> ;								:
  9995                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  9996                              <1> ;								:
  9997                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9998                              <1> 
  9999                              <1> ;int_77h:
 10000                              <1> HD1_INT:
 10001 00002F03 6650                <1> 	PUSH	AX
 10002                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
 10003                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 10004 00002F05 B00B                <1> 	mov	al, 0Bh  ; In-Service Register
 10005 00002F07 E6A0                <1> 	out	0A0h, al
 10006 00002F09 EB00                <1>         jmp short $+2
 10007 00002F0B EB00                <1> 	jmp short $+2
 10008 00002F0D E4A0                <1> 	in	al, 0A0h
 10009 00002F0F 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
 10010 00002F11 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
 10011                              <1> 	;
 10012 00002F13 1E                  <1> 	PUSH	DS
 10013                              <1> 	;CALL	DDS
 10014                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
 10015 00002F14 66B81000            <1> 	mov	ax, KDATA
 10016 00002F18 8ED8                <1> 	mov 	ds, ax
 10017                              <1> 	;
 10018                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
 10019                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
 10020 00002F1A 800D[876F0000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
 10021                              <1> 	;
 10022 00002F21 6652                <1> 	push	dx
 10023 00002F23 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
 10024                              <1> 					; Clear Controller (Award BIOS 1999)
 10025 00002F27 EBC9                <1> 	jmp	short Clear_IRQ1415
 10026                              <1> 
 10027                              <1> 
 10028                              <1> ;%include 'diskdata.inc' ; 11/03/2015
 10029                              <1> ;%include 'diskbss.inc' ; 11/03/2015
 10030                              <1> 
 10031                              <1> 
 10032                              <1> ;////////////////////////////////////////////////////////////////////
 10033                              <1> ;; END OF DISK I/O SYTEM ///
 10034                                  %include 'memory.s'  ; 09/03/2015
 10035                              <1> ; Retro UNIX 386 v2 - memory.s - 26/01/2020
 10036                              <1> ; Last Modification: 30/11/2021
 10037                              <1> ; ----------------------------------------------------------------------------
 10038                              <1> ;
 10039                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
 10040                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
 10041                              <1> ; 18/10/2015 (!not completed!)
 10042                              <1> ;
 10043                              <1> ; Source code for NASM - Netwide Assembler (2.11)
 10044                              <1> 
 10045                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
 10046                              <1> 
 10047                              <1> ;;04/11/2014 (unix386.s)	
 10048                              <1> ;PDE_A_PRESENT	equ 1		; Present flag for PDE
 10049                              <1> ;PDE_A_WRITE	equ 2		; Writable (write permission) flag
 10050                              <1> ;PDE_A_USER	equ 4		; User (non-system/kernel) page flag
 10051                              <1> ;;
 10052                              <1> ;PTE_A_PRESENT	equ 1		; Present flag for PTE (bit 0)
 10053                              <1> ;PTE_A_WRITE	equ 2		; Writable (write permission) flag (bit 1)
 10054                              <1> ;PTE_A_USER	equ 4		; User (non-system/kernel) page flag (bit 2)
 10055                              <1> ;PTE_A_ACCESS   equ 32		; Accessed flag (bit 5) ; 09/03/2015
 10056                              <1> 
 10057                              <1> ; 27/04/2015
 10058                              <1> ; 09/03/2015
 10059                              <1> PAGE_SIZE 	equ 4096	; page size in bytes
 10060                              <1> PAGE_SHIFT 	equ 12		; page table shift count
 10061                              <1> PAGE_D_SHIFT 	equ 22 ; 12+10	; page directory shift count
 10062                              <1> PAGE_OFF	equ 0FFFh	; 12 bit byte offset in page frame
 10063                              <1> PTE_MASK 	equ 03FFh	; page table entry mask
 10064                              <1> PTE_DUPLICATED  equ 200h	; duplicated page sign (AVL bit 0)
 10065                              <1> PDE_A_CLEAR	equ 0F000h	; to clear PDE attribute bits
 10066                              <1> PTE_A_CLEAR	equ 0F000h	; to clear PTE attribute bits
 10067                              <1> LOGIC_SECT_SIZE equ 512		; logical sector size
 10068                              <1> ERR_MAJOR_PF	equ 0E0h	; major error: page fault
 10069                              <1> ; 15/10/2016 (TRDOS 386 v2)
 10070                              <1> ERR_MINOR_IM	equ 4 ;15/10/2016 (1->4); insufficient (out of) memory
 10071                              <1> ERR_MINOR_PV	equ 6 ;15/10/2016 (3->6); protection violation
 10072                              <1> SWP_DISK_READ_ERR 	   equ 40
 10073                              <1> SWP_DISK_NOT_PRESENT_ERR   equ 41
 10074                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 42
 10075                              <1> SWP_NO_FREE_SPACE_ERR      equ 43
 10076                              <1> SWP_DISK_WRITE_ERR         equ 44
 10077                              <1> SWP_NO_PAGE_TO_SWAP_ERR    equ 45
 10078                              <1> PTE_A_ACCESS_BIT equ 5	; Bit 5 (accessed flag)        
 10079                              <1> SECTOR_SHIFT     equ 3	; sector shift (to convert page block number)
 10080                              <1> ; 10/06/2021 (Retro UNIX 386 v2)
 10081                              <1> ; 12/07/2016 (TRDOS 386 v2) 
 10082                              <1> PTE_SHARED	 equ 400h		; AVL bit 1, direct memory access bit	
 10083                              <1> 					; (Indicates that the page is not allocated
 10084                              <1> 					; for the process, it is a shared or system
 10085                              <1>                                         ; page, it must not be deallocated!)
 10086                              <1> ; 14/12/2020
 10087                              <1> ; (Linear Frame Buffer - video memory mark : AVL bit 1, outside M.A.T.)
 10088                              <1> PDE_EXTERNAL	equ 400h	; Page directory entry for external memory blocks
 10089                              <1> PTE_EXTERNAL	equ 400h	; Allocated kernel pages for Linear Frame Buffer
 10090                              <1> 				; (Out of memory allocation table)	
 10091                              <1> ;
 10092                              <1> ;; Retro Unix 386 v1 - paging method/principles
 10093                              <1> ;;
 10094                              <1> ;; 10/10/2014
 10095                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
 10096                              <1> ;;
 10097                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
 10098                              <1> ;;	(virtual address = physical address)
 10099                              <1> ;; KERNEL PAGE TABLES:
 10100                              <1> ;;	Kernel page directory and all page tables are
 10101                              <1> ;;	on memory as initialized, as equal to physical memory
 10102                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
 10103                              <1> ;;
 10104                              <1> ;;	what for: User pages may be swapped out, when accessing
 10105                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
 10106                              <1> ;;	kernel would have to swap it in! But it is also may be
 10107                              <1> ;;	in use by a user process. (In system/kernel mode
 10108                              <1> ;;	kernel can access all memory pages even if they are
 10109                              <1> ;;	reserved/allocated for user processes. Swap out/in would
 10110                              <1> ;;	cause conflicts.) 
 10111                              <1> ;;	
 10112                              <1> ;;	As result of these conditions,
 10113                              <1> ;;	all kernel pages must be initialized as equal to 
 10114                              <1> ;;	physical layout for preventing page faults. 
 10115                              <1> ;;	Also, calling "allocate page" procedure after
 10116                              <1> ;;	a page fault can cause another page fault (double fault)
 10117                              <1> ;;	if all kernel page tables would not be initialized.
 10118                              <1> ;;
 10119                              <1> ;;	[first_page] = Beginning of users space, as offset to 
 10120                              <1> ;;	memory allocation table. (double word aligned)
 10121                              <1> ;;
 10122                              <1> ;;	[next_page] = first/next free space to be searched
 10123                              <1> ;;	as offset to memory allocation table. (dw aligned)
 10124                              <1> ;;
 10125                              <1> ;;	[last_page] = End of memory (users space), as offset
 10126                              <1> ;;	to memory allocation table. (double word aligned)
 10127                              <1> ;;
 10128                              <1> ;; USER PAGE TABLES:
 10129                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
 10130                              <1> ;;		'ready only' marked copies of the 
 10131                              <1> ;;		parent process's page table entries (for
 10132                              <1> ;;		same physical memory).
 10133                              <1> ;;		(A page will be copied to a new page after
 10134                              <1> ;;		 if it causes R/W page fault.)
 10135                              <1> ;;
 10136                              <1> ;;	Every user process has own (different)
 10137                              <1> ;;	page directory and page tables.	
 10138                              <1> ;;
 10139                              <1> ;;	Code starts at virtual address 0, always.
 10140                              <1> ;;	(Initial value of EIP is 0 in user mode.)
 10141                              <1> ;;	(Programs can be written/developed as simple
 10142                              <1> ;;	 flat memory programs.)
 10143                              <1> ;;
 10144                              <1> ;; MEMORY ALLOCATION STRATEGY:
 10145                              <1> ;;	Memory page will be allocated by kernel only 
 10146                              <1> ;;		(in kernel/system mode only).
 10147                              <1> ;;	* After a
 10148                              <1> ;;	  - 'not present' page fault
 10149                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
 10150                              <1> ;;	* For loading (opening, reading) a file or disk/drive
 10151                              <1> ;;	* As responce to 'allocate additional memory blocks' 
 10152                              <1> ;;	  request by running process.
 10153                              <1> ;;	* While creating a process, allocating a new buffer,
 10154                              <1> ;;	  new page tables etc.
 10155                              <1> ;;
 10156                              <1> ;;	At first,
 10157                              <1> ;;	- 'allocate page' procedure will be called;
 10158                              <1> ;,	   if it will return with a valid (>0) physical address
 10159                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
 10160                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
 10161                              <1> ;;	- 'allocate page' will be called for allocating page
 10162                              <1> ;;	   directory, page table and running space (data/code).
 10163                              <1> ;;	- every successful 'allocate page' call will decrease
 10164                              <1> ;;	  'free_pages' count (pointer).
 10165                              <1> ;;	- 'out of (insufficient) memory error' will be returned
 10166                              <1> ;;	  if 'free_pages' points to a ZERO.
 10167                              <1> ;;	- swapping out and swapping in (if it is not a new page)
 10168                              <1> ;;	  procedures will be called as responce to 'out of memory'
 10169                              <1> ;;	  error except errors caused by attribute conflicts.
 10170                              <1> ;;	 (swapper functions)	 
 10171                              <1> ;;					
 10172                              <1> ;;	At second,
 10173                              <1> ;;	- page directory entry will be updated then page table
 10174                              <1> ;;	  entry will be updated.		
 10175                              <1> ;;
 10176                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
 10177                              <1> ;;	- M.A.T. has a size according to available memory as
 10178                              <1> ;;	  follows:
 10179                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
 10180                              <1> ;;		  - a bit with value of 0 means allocated page
 10181                              <1> ;;		  - a bit with value of 1 means a free page
 10182                              <1> ;,	- 'free_pages' pointer holds count of free pages
 10183                              <1> ;;	  depending on M.A.T.
 10184                              <1> ;;		(NOTE: Free page count will not be checked
 10185                              <1> ;;		again -on M.A.T.- after initialization. 
 10186                              <1> ;;		Kernel will trust on initial count.)
 10187                              <1> ;,	- 'free_pages' count will be decreased by allocation
 10188                              <1> ;;	  and it will be increased by deallocation procedures.
 10189                              <1> ;;	
 10190                              <1> ;;	- Available memory will be calculated during
 10191                              <1> ;;	  the kernel's initialization stage (in real mode).
 10192                              <1> ;;	  Memory allocation table and kernel page tables 
 10193                              <1> ;;	  will be formatted/sized as result of available
 10194                              <1> ;;	  memory calculation before paging is enabled.
 10195                              <1> ;;
 10196                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
 10197                              <1> ;;	- Memory Allocation Table size will be 128 KB.
 10198                              <1> ;;	- Memory allocation for kernel page directory size 
 10199                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10200                              <1> ;;	  for page tables)
 10201                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
 10202                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
 10203                              <1> ;;	- User (available) space will be started 
 10204                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
 10205                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10206                              <1> ;;	  memory allocation table and kernel's page directory
 10207                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10208                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10209                              <1> ;; 	  for buffers.
 10210                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10211                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10212                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
 10213                              <1> ;;
 10214                              <1> ;; For 1GB Available Memory:
 10215                              <1> ;;	- Memory Allocation Table size will be 32 KB.
 10216                              <1> ;;	- Memory allocation for kernel page directory size 
 10217                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10218                              <1> ;;	  for page tables)
 10219                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
 10220                              <1> ;;	  is 1 MB (256*4*1024 bytes).
 10221                              <1> ;;	- User (available) space will be started 
 10222                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
 10223                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10224                              <1> ;;	  memory allocation table and kernel's page directory
 10225                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10226                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10227                              <1> ;; 	  for buffers.
 10228                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10229                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10230                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
 10231                              <1> ;;
 10232                              <1> ;;
 10233                              <1> 
 10234                              <1> ;;************************************************************************************
 10235                              <1> ;; 
 10236                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
 10237                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
 10238                              <1> 
 10239                              <1> ;; Main factor: "sys fork" system call 
 10240                              <1> ;;	
 10241                              <1> ;; 		FORK
 10242                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
 10243                              <1> ;;  writable pages ---->|
 10244                              <1> ;;                      |----> child - duplicated PTEs, read only pages
 10245                              <1> ;; 
 10246                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
 10247                              <1> ;; 
 10248                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
 10249                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
 10250                              <1> ;;       -while R/W bit is 0-. 
 10251                              <1> ;; 
 10252                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
 10253                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
 10254                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
 10255                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
 10256                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
 10257                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
 10258                              <1> ;; 
 10259                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
 10260                              <1> ;; # Parent's read only pages are copied to new child pages. 
 10261                              <1> ;;   Parent's PTE attributes are not changed.
 10262                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
 10263                              <1> ;;    destroy/mix previous fork result).
 10264                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
 10265                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
 10266                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
 10267                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
 10268                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
 10269                              <1> ;;   as Child's Page Table Entries without copying actual page.
 10270                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
 10271                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
 10272                              <1> ;; 
 10273                              <1> ;; !? WHAT FOR (duplication after duplication):
 10274                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
 10275                              <1> ;; program/executable code continues from specified location as child process, 
 10276                              <1> ;; returns back previous code location as parent process, every child after 
 10277                              <1> ;; every sys fork uses last image of code and data just prior the fork.
 10278                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
 10279                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
 10280                              <1> ;; was copied to child's process segment (all of code and data) according to
 10281                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
 10282                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
 10283                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
 10284                              <1> ;; (complete running image of parent process) to the child process; 
 10285                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
 10286                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
 10287                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
 10288                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
 10289                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
 10290                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
 10291                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
 10292                              <1> ;; new/fresh pages will be used to load and run new executable/program.
 10293                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
 10294                              <1> ;; for sharing same read only pages between parent and child processes.
 10295                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
 10296                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
 10297                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
 10298                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
 10299                              <1> ;; -deallocation problem-.
 10300                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
 10301                              <1> ;; 
 10302                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10303                              <1> ;; # Page fault handler will do those:
 10304                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10305                              <1> ;;   - If it is reset/clear, there is a child uses same page.
 10306                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
 10307                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
 10308                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
 10309                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
 10310                              <1> ;;     read only page will be converted to writable and unique page which belongs
 10311                              <1> ;;     to child process.)	
 10312                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10313                              <1> ;; # Page fault handler will do those:
 10314                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10315                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
 10316                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
 10317                              <1> ;;     address or not. 
 10318                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
 10319                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
 10320                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
 10321                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
 10322                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
 10323                              <1> ;; 
 10324                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
 10325                              <1> ;;       will be set as writable (and unique) in case of child process was using 
 10326                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
 10327                              <1> ;;       duplication method details, it is not possible multiple child processes
 10328                              <1> ;;       were using same page with duplicated PTEs.
 10329                              <1> ;; 
 10330                              <1> ;;************************************************************************************   
 10331                              <1> 
 10332                              <1> ;; 08/10/2014
 10333                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
 10334                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
 10335                              <1> 
 10336                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
 10337                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
 10338                              <1> ;; (25/08/2014, Revision: 5057) file 
 10339                              <1> ;; by KolibriOS Team (2004-2012)
 10340                              <1> 
 10341                              <1> allocate_page:
 10342                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 10343                              <1> 	;	 (temporary modifications)
 10344                              <1> 	; 01/07/2015
 10345                              <1> 	; 05/05/2015
 10346                              <1> 	; 30/04/2015
 10347                              <1> 	; 16/10/2014
 10348                              <1> 	; 08/10/2014
 10349                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
 10350                              <1> 	;
 10351                              <1> 	; INPUT -> none
 10352                              <1> 	;
 10353                              <1> 	; OUTPUT ->
 10354                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10355                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
 10356                              <1> 	;
 10357                              <1> 	;	CF = 1 and EAX = 0 
 10358                              <1> 	; 		   if there is not a free page to be allocated	
 10359                              <1> 	;
 10360                              <1> 	; Modified Registers -> none (except EAX)
 10361                              <1> 	;
 10362 00002F29 A1[006F0000]        <1> 	mov	eax, [free_pages]
 10363 00002F2E 21C0                <1> 	and	eax, eax
 10364 00002F30 7438                <1> 	jz	short out_of_memory
 10365                              <1> 	;
 10366 00002F32 53                  <1> 	push	ebx
 10367 00002F33 51                  <1> 	push	ecx
 10368                              <1> 	;
 10369 00002F34 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
 10370 00002F39 89D9                <1> 	mov	ecx, ebx
 10371                              <1>  				     ; NOTE: 32 (first_page) is initial
 10372                              <1> 				     ; value of [next_page].
 10373                              <1> 				     ; It points to the first available
 10374                              <1> 				     ; page block for users (ring 3) ...	
 10375                              <1> 				     ; (MAT offset 32 = 1024/32)	
 10376                              <1> 				     ; (at the of the first 4 MB)		
 10377 00002F3B 031D[046F0000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
 10378                              <1> 				 ; next_free_page >> 5
 10379 00002F41 030D[086F0000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
 10380                              <1> 				 ; (total_pages - 1) >> 5
 10381                              <1> al_p_scan:
 10382 00002F47 39CB                <1> 	cmp	ebx, ecx
 10383 00002F49 770A                <1> 	ja	short al_p_notfound
 10384                              <1> 	;
 10385                              <1> 	; 01/07/2015
 10386                              <1> 	; AMD64 Architecture Programmers Manual
 10387                              <1> 	; Volume 3:
 10388                              <1> 	; General-Purpose and System Instructions
 10389                              <1> 	;
 10390                              <1> 	; BSF - Bit Scan Forward
 10391                              <1> 	;
 10392                              <1> 	;   Searches the value in a register or a memory location
 10393                              <1> 	;   (second operand) for the least-significant set bit. 
 10394                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
 10395                              <1> 	;   and stores the index of the least-significant set bit in a destination
 10396                              <1> 	;   register (first operand). If the second operand contains 0, 
 10397                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
 10398                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
 10399                              <1> 	;   of the searched value
 10400                              <1> 	;
 10401 00002F4B 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 10402                              <1> 			   ; Clear ZF if a bit is found set (1) and 
 10403                              <1> 			   ; loads the destination with an index to
 10404                              <1> 			   ; first set bit. (0 -> 31) 
 10405                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 10406 00002F4E 751C                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
 10407                              <1> 			 ;
 10408                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
 10409                              <1> 			 ;	  with value of 1 means 
 10410                              <1> 			 ;	  the corresponding page is free 
 10411                              <1> 			 ;	  (Retro UNIX 386 v1 feature only!)
 10412 00002F50 83C304              <1> 	add	ebx, 4
 10413                              <1> 			 ; We return back for searching next page block
 10414                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
 10415                              <1> 			 ;	 we always will find at least 1 free page here.
 10416 00002F53 EBF2                <1>         jmp     short al_p_scan
 10417                              <1> 	;
 10418                              <1> al_p_notfound:
 10419 00002F55 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10420 00002F5B 890D[046F0000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
 10421                              <1> 				 ; (deallocate_page procedure will change it)
 10422 00002F61 31C0                <1> 	xor	eax, eax
 10423 00002F63 A3[006F0000]        <1> 	mov	[free_pages], eax ; 0
 10424 00002F68 59                  <1> 	pop	ecx
 10425 00002F69 5B                  <1> 	pop	ebx
 10426                              <1> 	;
 10427                              <1> ; 17/04/2021
 10428                              <1> ; ('swap_out' procedure call is disabled as temporary)
 10429                              <1> 
 10430                              <1> out_of_memory:
 10431                              <1> ;	call	swap_out
 10432                              <1> ;	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
 10433                              <1> ;	;
 10434                              <1> ;	sub 	eax, eax ; 0
 10435 00002F6A F9                  <1> 	stc
 10436 00002F6B C3                  <1> 	retn
 10437                              <1> 
 10438                              <1> al_p_found:
 10439 00002F6C 89D9                <1> 	mov	ecx, ebx
 10440 00002F6E 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10441 00002F74 890D[046F0000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
 10442                              <1> 				 ; address/offset (to the next)
 10443 00002F7A FF0D[006F0000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
 10444                              <1> 	;
 10445 00002F80 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 10446                              <1> 				 ; is copied into the Carry Flag and then cleared
 10447                              <1> 				 ; in the destination.
 10448                              <1> 				 ;
 10449                              <1> 				 ; Reset the bit which is corresponding to the 
 10450                              <1> 				 ; (just) allocated page.
 10451                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
 10452 00002F83 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
 10453 00002F86 01C8                <1> 	add	eax, ecx	 ; = page number
 10454 00002F88 C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
 10455                              <1> 	; EAX = physical address of memory page
 10456                              <1> 	;
 10457                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
 10458                              <1> 	;       according to this EAX value...
 10459 00002F8B 59                  <1> 	pop	ecx
 10460 00002F8C 5B                  <1> 	pop	ebx
 10461                              <1> al_p_ok:
 10462 00002F8D C3                  <1> 	retn
 10463                              <1> 
 10464                              <1> make_page_dir:
 10465                              <1> 	; 18/04/2015
 10466                              <1> 	; 12/04/2015
 10467                              <1> 	; 23/10/2014
 10468                              <1> 	; 16/10/2014
 10469                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10470                              <1> 	;
 10471                              <1> 	; INPUT ->
 10472                              <1> 	;	none
 10473                              <1> 	; OUTPUT ->
 10474                              <1> 	;	(EAX = 0)
 10475                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10476                              <1> 	;	cf = 0 ->
 10477                              <1> 	;	u.pgdir = page directory (physical) address of the current
 10478                              <1> 	;		  process/user.
 10479                              <1> 	;
 10480                              <1> 	; Modified Registers -> EAX
 10481                              <1> 	;
 10482 00002F8E E896FFFFFF          <1> 	call	allocate_page
 10483 00002F93 7216                <1> 	jc	short mkpd_error
 10484                              <1> 	;
 10485 00002F95 A3[58700000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
 10486                              <1> 				  ; (Physical address)
 10487                              <1> clear_page:
 10488                              <1> 	; 18/04/2015
 10489                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10490                              <1> 	;
 10491                              <1> 	; INPUT ->
 10492                              <1> 	;	EAX = physical address of the page
 10493                              <1> 	; OUTPUT ->
 10494                              <1> 	;	all bytes of the page will be cleared
 10495                              <1> 	;
 10496                              <1> 	; Modified Registers -> none
 10497                              <1> 	;
 10498 00002F9A 57                  <1> 	push	edi
 10499 00002F9B 51                  <1> 	push	ecx
 10500 00002F9C 50                  <1> 	push	eax
 10501 00002F9D B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 10502 00002FA2 89C7                <1> 	mov	edi, eax
 10503 00002FA4 31C0                <1> 	xor	eax, eax
 10504 00002FA6 F3AB                <1> 	rep	stosd
 10505 00002FA8 58                  <1> 	pop	eax
 10506 00002FA9 59                  <1> 	pop	ecx
 10507 00002FAA 5F                  <1> 	pop	edi
 10508                              <1> mkpd_error:
 10509                              <1> mkpt_error:
 10510 00002FAB C3                  <1> 	retn
 10511                              <1> 
 10512                              <1> make_page_table:
 10513                              <1> 	; 23/06/2015
 10514                              <1> 	; 18/04/2015
 10515                              <1> 	; 12/04/2015
 10516                              <1> 	; 16/10/2014
 10517                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10518                              <1> 	;
 10519                              <1> 	; INPUT ->
 10520                              <1> 	;	EBX = virtual (linear) address
 10521                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10522                              <1> 	;	      (higher 20 bits must be ZERO)
 10523                              <1> 	;	      (bit 0 must be 1)	 
 10524                              <1> 	;	u.pgdir = page directory (physical) address
 10525                              <1> 	; OUTPUT ->
 10526                              <1> 	;	EDX = Page directory entry address
 10527                              <1> 	;	EAX = Page table address
 10528                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10529                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
 10530                              <1> 	;
 10531                              <1> 	; Modified Registers -> EAX, EDX
 10532                              <1> 	;
 10533 00002FAC E878FFFFFF          <1> 	call	allocate_page
 10534 00002FB1 72F8                <1> 	jc	short mkpt_error
 10535 00002FB3 E811000000          <1> 	call	set_pde	
 10536 00002FB8 EBE0                <1> 	jmp	short clear_page
 10537                              <1> 
 10538                              <1> make_page:
 10539                              <1> 	; 24/07/2015
 10540                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
 10541                              <1> 	;
 10542                              <1> 	; INPUT ->
 10543                              <1> 	;	EBX = virtual (linear) address
 10544                              <1> 	;	ECX = page attributes (lower 12 bits)
 10545                              <1> 	;	      (higher 20 bits must be ZERO)
 10546                              <1> 	;	      (bit 0 must be 1)	 
 10547                              <1> 	;	u.pgdir = page directory (physical) address
 10548                              <1> 	; OUTPUT ->
 10549                              <1> 	;	EBX = Virtual address
 10550                              <1> 	;	(EDX = PTE value)
 10551                              <1> 	;	EAX = Physical address
 10552                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10553                              <1> 	;
 10554                              <1> 	; Modified Registers -> EAX, EDX
 10555                              <1> 	;
 10556 00002FBA E86AFFFFFF          <1> 	call	allocate_page
 10557 00002FBF 7207                <1> 	jc	short mkp_err
 10558 00002FC1 E821000000          <1> 	call	set_pte	
 10559 00002FC6 73D2                <1> 	jnc	short clear_page ; 18/04/2015
 10560                              <1> mkp_err:
 10561 00002FC8 C3                  <1> 	retn
 10562                              <1> 
 10563                              <1> 
 10564                              <1> set_pde:	; Set page directory entry (PDE)
 10565                              <1> 	; 20/07/2015
 10566                              <1> 	; 18/04/2015
 10567                              <1> 	; 12/04/2015
 10568                              <1> 	; 23/10/2014
 10569                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10570                              <1> 	;
 10571                              <1> 	; INPUT ->
 10572                              <1> 	;	EAX = physical address
 10573                              <1> 	;	      (use present value if EAX = 0)
 10574                              <1> 	;	EBX = virtual (linear) address
 10575                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10576                              <1> 	;	      (higher 20 bits must be ZERO)
 10577                              <1> 	;	      (bit 0 must be 1)	 
 10578                              <1> 	;	u.pgdir = page directory (physical) address
 10579                              <1> 	; OUTPUT ->
 10580                              <1> 	;	EDX = PDE address
 10581                              <1> 	;	EAX = page table address (physical)
 10582                              <1> 	;	;(CF=1 -> Invalid page address)
 10583                              <1> 	;
 10584                              <1> 	; Modified Registers -> EDX
 10585                              <1> 	;
 10586 00002FC9 89DA                <1> 	mov	edx, ebx
 10587 00002FCB C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
 10588 00002FCE C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
 10589 00002FD1 0315[58700000]      <1> 	add	edx, [u.pgdir]
 10590                              <1> 	;
 10591 00002FD7 21C0                <1> 	and	eax, eax
 10592 00002FD9 7506                <1> 	jnz	short spde_1
 10593                              <1> 	;
 10594 00002FDB 8B02                <1> 	mov	eax, [edx]  ; old PDE value
 10595                              <1> 	;test	al, 1
 10596                              <1> 	;jz	short spde_2
 10597 00002FDD 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
 10598                              <1> spde_1:
 10599                              <1> 	;and	cx, 0FFFh
 10600 00002FE1 8902                <1> 	mov	[edx], eax
 10601 00002FE3 66090A              <1> 	or	[edx], cx
 10602 00002FE6 C3                  <1> 	retn
 10603                              <1> ;spde_2: ; error
 10604                              <1> ;	stc
 10605                              <1> ;	retn
 10606                              <1> 
 10607                              <1> set_pte:	; Set page table entry (PTE)
 10608                              <1> 	; 24/07/2015
 10609                              <1> 	; 20/07/2015
 10610                              <1> 	; 23/06/2015
 10611                              <1> 	; 18/04/2015
 10612                              <1> 	; 12/04/2015
 10613                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10614                              <1> 	;
 10615                              <1> 	; INPUT ->
 10616                              <1> 	;	EAX = physical page address
 10617                              <1> 	;	      (use present value if EAX = 0)
 10618                              <1> 	;	EBX = virtual (linear) address
 10619                              <1> 	;	ECX = page attributes (lower 12 bits)
 10620                              <1> 	;	      (higher 20 bits must be ZERO)
 10621                              <1> 	;	      (bit 0 must be 1)	 
 10622                              <1> 	;	u.pgdir = page directory (physical) address
 10623                              <1> 	; OUTPUT ->
 10624                              <1> 	;	EAX = physical page address
 10625                              <1> 	;	(EDX = PTE value)
 10626                              <1> 	;	EBX = virtual address
 10627                              <1> 	;
 10628                              <1> 	;	CF = 1 -> error
 10629                              <1> 	;
 10630                              <1> 	; Modified Registers -> EAX, EDX
 10631                              <1> 	;
 10632 00002FE7 50                  <1> 	push	eax
 10633 00002FE8 A1[58700000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
 10634 00002FED E837000000          <1> 	call 	get_pde
 10635                              <1> 		; EDX = PDE address
 10636                              <1> 		; EAX = PDE value
 10637 00002FF2 5A                  <1> 	pop	edx ; physical page address
 10638 00002FF3 722A                <1> 	jc	short spte_err ; PDE not present
 10639                              <1> 	;
 10640 00002FF5 53                  <1> 	push	ebx ; 24/07/2015
 10641 00002FF6 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10642                              <1> 			    ; EDX = PT address (physical)	
 10643 00002FFA C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
 10644 00002FFD 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
 10645                              <1> 			 ; clear higher 10 bits (PD bits)
 10646 00003003 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
 10647 00003006 01C3                <1> 	add	ebx, eax
 10648                              <1> 	;
 10649 00003008 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
 10650 0000300A A801                <1> 	test	al, 1
 10651 0000300C 740C                <1> 	jz	short spte_0
 10652 0000300E 09D2                <1> 	or	edx, edx
 10653 00003010 750F                <1> 	jnz	short spte_1
 10654 00003012 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10655 00003016 89C2                <1> 	mov	edx, eax
 10656 00003018 EB09                <1> 	jmp	short spte_2	
 10657                              <1> spte_0:
 10658                              <1> 	; If this PTE contains a swap (disk) address,
 10659                              <1> 	; it can be updated by using 'swap_in' procedure
 10660                              <1> 	; only!
 10661 0000301A 21C0                <1> 	and	eax, eax
 10662 0000301C 7403                <1> 	jz	short spte_1
 10663                              <1> 	; 24/07/2015
 10664                              <1> 	; swapped page ! (on disk)
 10665 0000301E 5B                  <1> 	pop	ebx
 10666                              <1> spte_err:
 10667 0000301F F9                  <1> 	stc
 10668 00003020 C3                  <1> 	retn
 10669                              <1> spte_1: 
 10670 00003021 89D0                <1> 	mov	eax, edx
 10671                              <1> spte_2:
 10672 00003023 09CA                <1> 	or	edx, ecx
 10673                              <1> 	; 23/06/2015
 10674 00003025 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
 10675                              <1> 	; 24/07/2015
 10676 00003027 5B                  <1> 	pop	ebx
 10677 00003028 C3                  <1> 	retn
 10678                              <1> 
 10679                              <1> get_pde:	; Get present value of the relevant PDE
 10680                              <1> 	; 20/07/2015
 10681                              <1> 	; 18/04/2015
 10682                              <1> 	; 12/04/2015
 10683                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10684                              <1> 	;
 10685                              <1> 	; INPUT ->
 10686                              <1> 	;	EBX = virtual (linear) address
 10687                              <1> 	;	EAX = page directory (physical) address
 10688                              <1> 	; OUTPUT ->
 10689                              <1> 	;	EDX = Page directory entry address
 10690                              <1> 	;	EAX = Page directory entry value
 10691                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 10692                              <1> 	; Modified Registers -> EDX, EAX
 10693                              <1> 	;
 10694 00003029 89DA                <1> 	mov	edx, ebx
 10695 0000302B C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
 10696 0000302E C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
 10697 00003031 01C2                <1> 	add	edx, eax ; page directory address (physical)
 10698 00003033 8B02                <1> 	mov	eax, [edx]
 10699 00003035 A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
 10700 00003037 751F                <1> 	jnz	short gpte_retn
 10701 00003039 F9                  <1> 	stc
 10702                              <1> gpde_retn:	
 10703 0000303A C3                  <1> 	retn
 10704                              <1> 
 10705                              <1> get_pte:
 10706                              <1> 		; Get present value of the relevant PTE
 10707                              <1> 	; 29/07/2015
 10708                              <1> 	; 20/07/2015
 10709                              <1> 	; 18/04/2015
 10710                              <1> 	; 12/04/2015
 10711                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10712                              <1> 	;
 10713                              <1> 	; INPUT ->
 10714                              <1> 	;	EBX = virtual (linear) address
 10715                              <1> 	;	EAX = page directory (physical) address
 10716                              <1> 	; OUTPUT ->
 10717                              <1> 	;	EDX = Page table entry address (if CF=0)
 10718                              <1> 	;	      Page directory entry address (if CF=1)
 10719                              <1> 	;            (Bit 0 value is 0 if PT is not present)
 10720                              <1> 	;	EAX = Page table entry value (page address)
 10721                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 10722                              <1> 	; Modified Registers -> EAX, EDX
 10723                              <1> 	;
 10724 0000303B E8E9FFFFFF          <1> 	call 	get_pde
 10725 00003040 72F8                <1> 	jc	short gpde_retn	; page table is not present
 10726                              <1> 	;jnc	short gpte_1
 10727                              <1> 	;retn
 10728                              <1> ;gpte_1:
 10729 00003042 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10730 00003046 89DA                <1> 	mov	edx, ebx
 10731 00003048 C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
 10732 0000304B 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
 10733                              <1> 			 ; clear higher 10 bits (PD bits)
 10734 00003051 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
 10735 00003054 01C2                <1> 	add	edx, eax
 10736 00003056 8B02                <1> 	mov	eax, [edx]
 10737                              <1> gpte_retn:
 10738 00003058 C3                  <1> 	retn
 10739                              <1> 
 10740                              <1> deallocate_page_dir:
 10741                              <1> 	; 15/09/2015
 10742                              <1> 	; 05/08/2015
 10743                              <1> 	; 30/04/2015
 10744                              <1> 	; 28/04/2015
 10745                              <1> 	; 17/10/2014
 10746                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10747                              <1> 	;
 10748                              <1> 	; INPUT ->
 10749                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
 10750                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 10751                              <1> 	; OUTPUT ->
 10752                              <1> 	;	All of page tables in the page directory
 10753                              <1> 	;	and page dir's itself will be deallocated
 10754                              <1> 	;	except 'read only' duplicated pages (will be converted
 10755                              <1> 	;	to writable pages).
 10756                              <1> 	;
 10757                              <1> 	; Modified Registers -> EAX
 10758                              <1> 	;
 10759                              <1> 	;
 10760 00003059 56                  <1> 	push	esi
 10761 0000305A 51                  <1> 	push	ecx
 10762 0000305B 50                  <1> 	push	eax
 10763 0000305C 89C6                <1> 	mov	esi, eax 
 10764 0000305E 31C9                <1> 	xor	ecx, ecx
 10765                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
 10766                              <1> 	; it must not be deallocated
 10767 00003060 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
 10768                              <1> dapd_0:
 10769 00003062 AD                  <1> 	lodsd
 10770 00003063 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
 10771 00003065 7409                <1> 	jz	short dapd_1	
 10772 00003067 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 10773 0000306B E812000000          <1> 	call	deallocate_page_table			
 10774                              <1> dapd_1:
 10775 00003070 41                  <1> 	inc	ecx ; page directory entry index
 10776 00003071 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
 10777 00003077 72E9                <1> 	jb	short dapd_0
 10778                              <1> dapd_2:
 10779 00003079 58                  <1> 	pop	eax
 10780 0000307A E872000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
 10781 0000307F 59                  <1> 	pop	ecx
 10782 00003080 5E                  <1> 	pop	esi
 10783 00003081 C3                  <1> 	retn
 10784                              <1> 
 10785                              <1> deallocate_page_table:
 10786                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 10787                              <1> 	;	 (temporary modifications)
 10788                              <1> 	; 12/07/2016 (TRDOS 386 v2)
 10789                              <1> 	; 19/09/2015
 10790                              <1> 	; 15/09/2015
 10791                              <1> 	; 05/08/2015
 10792                              <1> 	; 30/04/2015
 10793                              <1> 	; 28/04/2015
 10794                              <1> 	; 24/10/2014
 10795                              <1> 	; 23/10/2014
 10796                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10797                              <1> 	;
 10798                              <1> 	; INPUT ->
 10799                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
 10800                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 10801                              <1> 	;	(ECX = page directory entry index)
 10802                              <1> 	; OUTPUT ->
 10803                              <1> 	;	All of pages in the page table and page table's itself
 10804                              <1> 	;	will be deallocated except 'read only' duplicated pages
 10805                              <1> 	;	(will be converted to writable pages).
 10806                              <1> 	;
 10807                              <1> 	; Modified Registers -> EAX
 10808                              <1> 	;
 10809 00003082 56                  <1> 	push	esi
 10810 00003083 57                  <1> 	push	edi
 10811 00003084 52                  <1> 	push	edx
 10812 00003085 50                  <1> 	push	eax ; *
 10813 00003086 89C6                <1> 	mov	esi, eax 
 10814 00003088 31FF                <1> 	xor	edi, edi ; 0
 10815                              <1> dapt_0:
 10816 0000308A AD                  <1> 	lodsd
 10817 0000308B A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
 10818 0000308D 7455                <1> 	jz	short dapt_1
 10819                              <1> 	;
 10820 0000308F A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
 10821                              <1> 				  ; (must be 1)
 10822 00003091 753F                <1> 	jnz	short dapt_3
 10823                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
 10824 00003093 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
 10825                              <1> 				   ; as child's page ?
 10826 00003097 7444                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
 10827                              <1> 	; check the parent's PTE value is read only & same page or not.. 
 10828                              <1> 	; ECX = page directory entry index (0-1023)
 10829 00003099 53                  <1> 	push	ebx
 10830 0000309A 51                  <1> 	push	ecx
 10831 0000309B 66C1E102            <1> 	shl	cx, 2 ; *4 
 10832 0000309F 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
 10833 000030A1 8B0B                <1> 	mov	ecx, [ebx]
 10834 000030A3 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
 10835 000030A6 7428                <1> 	jz	short dapt_2	; parent process does not use this page
 10836 000030A8 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 10837                              <1> 	; EDI = page table entry index (0-1023)
 10838 000030AD 89FA                <1> 	mov	edx, edi 
 10839 000030AF 66C1E202            <1> 	shl	dx, 2 ; *4 
 10840 000030B3 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
 10841 000030B5 8B1A                <1> 	mov	ebx, [edx]
 10842 000030B7 F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
 10843 000030BA 7414                <1> 	jz	short dapt_2	; parent process does not use this page
 10844 000030BC 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
 10845 000030C0 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
 10846 000030C5 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
 10847 000030C7 7507                <1> 	jne	short dapt_2	; not same page
 10848                              <1> 				; deallocate the child's page
 10849 000030C9 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
 10850 000030CC 59                  <1> 	pop	ecx
 10851 000030CD 5B                  <1> 	pop	ebx
 10852 000030CE EB0D                <1> 	jmp	short dapt_4
 10853                              <1> 
 10854                              <1> ; 17/04/2021
 10855                              <1> ; ('dapt_1' is disabled as temporary)
 10856                              <1> ;
 10857                              <1> ;dapt_1:
 10858                              <1> ;	or	eax, eax	; swapped page ?
 10859                              <1> ;	jz	short dapt_5	; no
 10860                              <1> ;				; yes
 10861                              <1> ;	shr	eax, 1
 10862                              <1> ;	call	unlink_swap_block ; Deallocate swapped page block
 10863                              <1> ;				  ; on the swap disk (or in file)
 10864                              <1> ;	jmp	short dapt_5
 10865                              <1> dapt_2:
 10866 000030D0 59                  <1> 	pop	ecx
 10867 000030D1 5B                  <1> 	pop	ebx
 10868                              <1> dapt_3:	
 10869                              <1> 	; 12/07/2016
 10870 000030D2 66A90004            <1> 	test	ax, PTE_SHARED ; shared or direct memory access indicator
 10871 000030D6 7505                <1> 	jnz	short dapt_4   ; AVL bit 1 = 1, do not deallocate this page!
 10872                              <1> 	;
 10873                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 10874 000030D8 E814000000          <1> 	call	deallocate_page ; set the mem allocation bit of this page
 10875                              <1> dapt_4:
 10876 000030DD C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
 10877                              <1> dapt_1:	; 17/04/2021 (temporary)
 10878                              <1> dapt_5:
 10879 000030E4 47                  <1> 	inc	edi ; page table entry index
 10880 000030E5 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
 10881 000030EB 729D                <1> 	jb	short dapt_0
 10882                              <1> 	;
 10883 000030ED 58                  <1> 	pop	eax ; *
 10884 000030EE 5A                  <1> 	pop	edx
 10885 000030EF 5F                  <1> 	pop	edi	
 10886 000030F0 5E                  <1> 	pop	esi
 10887                              <1> 	;
 10888                              <1> 	;call	deallocate_page	; deallocate the page table's itself
 10889                              <1> 	;retn
 10890                              <1> 
 10891                              <1> deallocate_page:
 10892                              <1> 	; 15/09/2015
 10893                              <1> 	; 28/04/2015
 10894                              <1> 	; 10/03/2015
 10895                              <1> 	; 17/10/2014
 10896                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10897                              <1> 	;
 10898                              <1> 	; INPUT -> 
 10899                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10900                              <1> 	; OUTPUT ->
 10901                              <1> 	;	[free_pages] is increased
 10902                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
 10903                              <1> 	;	CF = 1 if the page is already deallocated
 10904                              <1> 	; 	       (or not allocated) before.  
 10905                              <1> 	;
 10906                              <1> 	; Modified Registers -> EAX
 10907                              <1> 	;
 10908 000030F1 53                  <1> 	push	ebx
 10909 000030F2 52                  <1> 	push	edx
 10910                              <1> 	;
 10911 000030F3 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
 10912                              <1> 				     ; 12 bits right
 10913                              <1> 				     ; to get page number
 10914 000030F6 89C2                <1> 	mov	edx, eax
 10915                              <1> 	; 15/09/2015
 10916 000030F8 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
 10917                              <1> 				     ; (1 allocation bit = 1 page)
 10918                              <1> 				     ; (1 allocation bytes = 8 pages)
 10919 000030FB 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 10920                              <1> 				     ; (to get 32 bit position)			
 10921                              <1> 	;
 10922 000030FE BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
 10923 00003103 01D3                <1> 	add	ebx, edx
 10924 00003105 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 10925                              <1> 				     ; (allocation bit position)	 
 10926 00003108 3B15[046F0000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
 10927                              <1> 				     ; than the address in 'next_page' ?
 10928                              <1> 				     ; (next/first free page value)		
 10929 0000310E 7306                <1> 	jnb	short dap_1	     ; no	
 10930 00003110 8915[046F0000]      <1> 	mov	[next_page], edx     ; yes
 10931                              <1> dap_1:
 10932 00003116 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
 10933                              <1> 				     ; set relevant bit to 1.
 10934                              <1> 				     ; set CF to the previous bit value	
 10935                              <1> 	;cmc			     ; complement carry flag	
 10936                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
 10937                              <1> 				     ; if the page is already deallocated
 10938                              <1> 				     ; before.	
 10939 00003119 FF05[006F0000]      <1>         inc     dword [free_pages]
 10940                              <1> dap_2:
 10941 0000311F 5A                  <1> 	pop	edx
 10942 00003120 5B                  <1> 	pop	ebx
 10943 00003121 C3                  <1> 	retn
 10944                              <1> 
 10945                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 10946                              <1> ;;                                                              ;;
 10947                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
 10948                              <1> ;; Distributed under terms of the GNU General Public License    ;;
 10949                              <1> ;;                                                              ;;
 10950                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 10951                              <1> 
 10952                              <1> ;;$Revision: 5057 $
 10953                              <1> 
 10954                              <1> 
 10955                              <1> ;;align 4
 10956                              <1> ;;proc alloc_page
 10957                              <1> 
 10958                              <1> ;;        pushfd
 10959                              <1> ;;        cli
 10960                              <1> ;;        push    ebx
 10961                              <1> ;;;//-
 10962                              <1> ;;        cmp     [pg_data.pages_free], 1
 10963                              <1> ;;        jle     .out_of_memory
 10964                              <1> ;;;//-
 10965                              <1> ;;
 10966                              <1> ;;        mov     ebx, [page_start]
 10967                              <1> ;;        mov     ecx, [page_end]
 10968                              <1> ;;.l1:
 10969                              <1> ;;        bsf     eax, [ebx];
 10970                              <1> ;;        jnz     .found
 10971                              <1> ;;        add     ebx, 4
 10972                              <1> ;;        cmp     ebx, ecx
 10973                              <1> ;;        jb      .l1
 10974                              <1> ;;        pop     ebx
 10975                              <1> ;;        popfd
 10976                              <1> ;;        xor     eax, eax
 10977                              <1> ;;        ret
 10978                              <1> ;;.found:
 10979                              <1> ;;;//-
 10980                              <1> ;;        dec     [pg_data.pages_free]
 10981                              <1> ;;        jz      .out_of_memory
 10982                              <1> ;;;//-
 10983                              <1> ;;        btr     [ebx], eax
 10984                              <1> ;;        mov     [page_start], ebx
 10985                              <1> ;;        sub     ebx, sys_pgmap
 10986                              <1> ;;        lea     eax, [eax+ebx*8]
 10987                              <1> ;;        shl     eax, 12
 10988                              <1> ;;;//-       dec [pg_data.pages_free]
 10989                              <1> ;;        pop     ebx
 10990                              <1> ;;        popfd
 10991                              <1> ;;        ret
 10992                              <1> ;;;//-
 10993                              <1> ;;.out_of_memory:
 10994                              <1> ;;        mov     [pg_data.pages_free], 1
 10995                              <1> ;;        xor     eax, eax
 10996                              <1> ;;        pop     ebx
 10997                              <1> ;;        popfd
 10998                              <1> ;;        ret
 10999                              <1> ;;;//-
 11000                              <1> ;;endp
 11001                              <1> 
 11002                              <1> duplicate_page_dir:
 11003                              <1> 	; 21/09/2015
 11004                              <1> 	; 31/08/2015
 11005                              <1> 	; 20/07/2015
 11006                              <1> 	; 28/04/2015
 11007                              <1> 	; 27/04/2015
 11008                              <1> 	; 18/04/2015
 11009                              <1> 	; 12/04/2015
 11010                              <1> 	; 18/10/2014
 11011                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 11012                              <1> 	;
 11013                              <1> 	; INPUT -> 
 11014                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 11015                              <1> 	;		    page directory.
 11016                              <1> 	; OUTPUT ->
 11017                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 11018                              <1> 	;	       page directory.
 11019                              <1> 	;	(New page directory with new page table entries.)
 11020                              <1> 	;	(New page tables with read only copies of the parent's
 11021                              <1> 	;	pages.)
 11022                              <1> 	;	EAX = 0 -> Error (CF = 1)
 11023                              <1> 	;
 11024                              <1> 	; Modified Registers -> none (except EAX)
 11025                              <1> 	;
 11026 00003122 E802FEFFFF          <1> 	call	allocate_page
 11027 00003127 723E                <1> 	jc	short dpd_err
 11028                              <1> 	;
 11029 00003129 55                  <1> 	push	ebp ; 20/07/2015
 11030 0000312A 56                  <1> 	push	esi
 11031 0000312B 57                  <1> 	push	edi
 11032 0000312C 53                  <1> 	push	ebx
 11033 0000312D 51                  <1> 	push	ecx
 11034 0000312E 8B35[58700000]      <1> 	mov	esi, [u.pgdir]
 11035 00003134 89C7                <1> 	mov	edi, eax
 11036 00003136 50                  <1> 	push	eax ; save child's page directory address
 11037                              <1> 	; 31/08/2015
 11038                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 11039                              <1> 	; (use same system space for all user page tables) 
 11040 00003137 A5                  <1> 	movsd
 11041 00003138 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 11042 0000313D B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 11043                              <1> dpd_0:	
 11044 00003142 AD                  <1> 	lodsd
 11045                              <1> 	;or	eax, eax
 11046                              <1>         ;jnz     short dpd_1
 11047 00003143 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 11048 00003145 7508                <1> 	jnz	short dpd_1
 11049                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
 11050 00003147 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 11051 0000314D EB0F                <1> 	jmp	short dpd_2
 11052                              <1> dpd_1:	
 11053 0000314F 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 11054 00003153 89C3                <1> 	mov	ebx, eax
 11055                              <1> 	; EBX = Parent's page table address
 11056 00003155 E81F000000          <1> 	call	duplicate_page_table
 11057 0000315A 720C                <1> 	jc	short dpd_p_err
 11058                              <1> 	; EAX = Child's page table address
 11059 0000315C 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 11060                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 11061                              <1> 			 ; (present, writable, user)
 11062                              <1> dpd_2:
 11063 0000315E AB                  <1> 	stosd
 11064 0000315F E2E1                <1> 	loop	dpd_0
 11065                              <1> 	;
 11066 00003161 58                  <1> 	pop	eax  ; restore child's page directory address
 11067                              <1> dpd_3:
 11068 00003162 59                  <1> 	pop	ecx
 11069 00003163 5B                  <1> 	pop	ebx
 11070 00003164 5F                  <1> 	pop	edi
 11071 00003165 5E                  <1> 	pop	esi
 11072 00003166 5D                  <1> 	pop	ebp ; 20/07/2015
 11073                              <1> dpd_err:
 11074 00003167 C3                  <1> 	retn
 11075                              <1> dpd_p_err:
 11076                              <1> 	; release the allocated pages missing (recover free space)
 11077 00003168 58                  <1> 	pop	eax  ; the new page directory address (physical)
 11078 00003169 8B1D[58700000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 11079 0000316F E8E5FEFFFF          <1> 	call 	deallocate_page_dir
 11080 00003174 29C0                <1> 	sub	eax, eax ; 0
 11081 00003176 F9                  <1> 	stc
 11082 00003177 EBE9                <1> 	jmp	short dpd_3	
 11083                              <1> 
 11084                              <1> duplicate_page_table:
 11085                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 11086                              <1> 	;	 (temporary modifications)
 11087                              <1> 	; 16/04/2021 (Retro UNIX 386 v2)
 11088                              <1> 	; 20/02/2017 (TRDOS 386 v2)
 11089                              <1> 	; 21/09/2015
 11090                              <1> 	; 20/07/2015
 11091                              <1> 	; 05/05/2015
 11092                              <1> 	; 28/04/2015
 11093                              <1> 	; 27/04/2015
 11094                              <1> 	; 18/04/2015
 11095                              <1> 	; 18/10/2014
 11096                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 11097                              <1> 	;
 11098                              <1> 	; INPUT -> 
 11099                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 11100                              <1> 	;       20/02/2017		 
 11101                              <1> 	;	EBP = Linear address of the page (from 'duplicate_page_dir')
 11102                              <1> 	;	      (Linear address = CORE + user's virtual address) 	
 11103                              <1> 	; OUTPUT ->
 11104                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 11105                              <1> 	;	      (with 'read only' attribute of page table entries)
 11106                              <1> 	;	20/02/2017
 11107                              <1> 	;	EBP = Next linear page address (for 'duplicate_page_dir')
 11108                              <1> 	;	
 11109                              <1> 	;	CF = 1 -> error 
 11110                              <1> 	;
 11111                              <1> 	; Modified Registers -> EBP (except EAX)
 11112                              <1> 	;
 11113 00003179 E8ABFDFFFF          <1> 	call	allocate_page
 11114 0000317E 7258                <1> 	jc	short dpt_err
 11115                              <1> 	;
 11116 00003180 50                  <1> 	push	eax ; *
 11117 00003181 56                  <1> 	push	esi
 11118 00003182 57                  <1> 	push	edi
 11119 00003183 52                  <1> 	push	edx
 11120 00003184 51                  <1> 	push	ecx
 11121                              <1> 	;
 11122 00003185 89DE                <1> 	mov	esi, ebx
 11123 00003187 89C7                <1> 	mov	edi, eax
 11124 00003189 89C2                <1> 	mov	edx, eax
 11125 0000318B 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 11126                              <1> dpt_0:
 11127 00003191 AD                  <1> 	lodsd
 11128 00003192 21C0                <1> 	and	eax, eax
 11129 00003194 7432                <1> 	jz	short dpt_3
 11130 00003196 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 11131                              <1> 	; 17/04/2021 (temporary)
 11132                              <1> 	;jnz	short dpt_1
 11133 00003198 7439                <1> 	jz	short dpt_p_err
 11134                              <1> 
 11135                              <1> ; 17/04/2021
 11136                              <1> ; ('reload_page' procedure call is disabled as temporary)
 11137                              <1> ;
 11138                              <1> ;	; 20/07/2015
 11139                              <1> ;	; ebp = virtual (linear) address of the memory page
 11140                              <1> ;	call	reload_page ; 28/04/2015
 11141                              <1> ;	jc	short dpt_p_err
 11142                              <1> dpt_1:
 11143                              <1> 	; 21/09/2015
 11144 0000319A 89C1                <1> 	mov	ecx, eax
 11145 0000319C 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11146 000031A0 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
 11147 000031A3 751A                <1> 	jnz	short dpt_2
 11148                              <1> 	; Read only (parent) page
 11149                              <1> 	; 	- there is a third process which uses this page -
 11150                              <1> 	; Allocate a new page for the child process
 11151 000031A5 E87FFDFFFF          <1> 	call	allocate_page
 11152 000031AA 7227                <1> 	jc	short dpt_p_err
 11153 000031AC 57                  <1> 	push	edi
 11154 000031AD 56                  <1> 	push	esi
 11155 000031AE 89CE                <1> 	mov	esi, ecx
 11156 000031B0 89C7                <1> 	mov	edi, eax
 11157 000031B2 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 11158 000031B7 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 11159 000031B9 5E                  <1> 	pop	esi
 11160 000031BA 5F                  <1> 	pop	edi
 11161                              <1> 	;
 11162                              <1> 
 11163                              <1> ; 17/04/2021
 11164                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)
 11165                              <1> ; 
 11166                              <1> ;	push	ebx
 11167                              <1> ;	push	eax
 11168                              <1> ;	; 20/07/2015
 11169                              <1> ;	mov	ebx, ebp
 11170                              <1> ;	; ebx = virtual (linear) address of the memory page
 11171                              <1> ;	call	add_to_swap_queue
 11172                              <1> ;	pop	eax
 11173                              <1> ;	pop	ebx
 11174                              <1> 
 11175                              <1> 	; 21/09/2015
 11176 000031BB 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 11177                              <1> 		; user + writable + present page
 11178 000031BD EB09                <1> 	jmp	short dpt_3
 11179                              <1> dpt_2:
 11180                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 11181 000031BF 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
 11182                              <1> 		    ; (read only page!)
 11183 000031C1 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
 11184 000031C4 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
 11185                              <1> dpt_3:
 11186 000031C8 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 11187                              <1> 	;
 11188 000031C9 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 11189                              <1> 	;
 11190 000031CF 39D7                <1> 	cmp	edi, edx
 11191 000031D1 72BE                <1> 	jb	short dpt_0
 11192                              <1> dpt_p_err:
 11193 000031D3 59                  <1> 	pop	ecx
 11194 000031D4 5A                  <1> 	pop	edx
 11195 000031D5 5F                  <1> 	pop	edi
 11196 000031D6 5E                  <1> 	pop	esi
 11197 000031D7 58                  <1> 	pop	eax ; *
 11198                              <1> dpt_err:
 11199 000031D8 C3                  <1> 	retn
 11200                              <1> 
 11201                              <1> page_fault_handler:	; CPU EXCEPTION 0Eh (14) : Page Fault !
 11202                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 11203                              <1> 	;	 (temporary modifications)
 11204                              <1> 	; 21/09/2015
 11205                              <1> 	; 19/09/2015
 11206                              <1> 	; 17/09/2015
 11207                              <1> 	; 28/08/2015
 11208                              <1> 	; 20/07/2015
 11209                              <1> 	; 28/06/2015
 11210                              <1> 	; 03/05/2015
 11211                              <1> 	; 30/04/2015
 11212                              <1> 	; 18/04/2015
 11213                              <1> 	; 12/04/2015
 11214                              <1> 	; 30/10/2014
 11215                              <1> 	; 11/09/2014
 11216                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
 11217                              <1> 	;
 11218                              <1> 	; Note: This is not an interrupt/exception handler.
 11219                              <1> 	;	This is a 'page fault remedy' subroutine 
 11220                              <1> 	;	which will be called by standard/uniform
 11221                              <1> 	;	exception handler.
 11222                              <1> 	;
 11223                              <1> 	; INPUT -> 
 11224                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
 11225                              <1> 	;
 11226                              <1> 	;	cr2 = the virtual (linear) address 
 11227                              <1> 	;	      which has caused to page fault (19/09/2015)
 11228                              <1> 	;
 11229                              <1> 	; OUTPUT ->
 11230                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11231                              <1> 	;	EAX = 0 -> no error
 11232                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
 11233                              <1> 	;
 11234                              <1> 	; Modified Registers -> none (except EAX)
 11235                              <1> 	;	
 11236                              <1>         ;
 11237                              <1>         ; ERROR CODE:
 11238                              <1> 	;	 31  .....	4   3	2   1	0
 11239                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11240                              <1> 	;	|   Reserved  | I | R | U | W | P |
 11241                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11242                              <1> 	;
 11243                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
 11244                              <1>     	;		a page-protection violation. When not set,
 11245                              <1> 	;		it was caused by a non-present page.
 11246                              <1> 	; W : WRITE   -	When set, the page fault was caused by
 11247                              <1> 	;		a page write. When not set, it was caused
 11248                              <1> 	;		by a page read.
 11249                              <1> 	; U : USER    -	When set, the page fault was caused 
 11250                              <1> 	;		while CPL = 3. 
 11251                              <1> 	;		This does not necessarily mean that
 11252                              <1> 	;		the page fault was a privilege violation.
 11253                              <1> 	; R : RESERVD -	When set, the page fault was caused by
 11254                              <1> 	;     WRITE	reading a 1 in a reserved field.
 11255                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
 11256                              <1> 	;     FETCH	an instruction fetch
 11257                              <1> 	;
 11258                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
 11259                              <1> 	;  31               22                  12 11                    0
 11260                              <1> 	; +-------------------+-------------------+-----------------------+
 11261                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
 11262                              <1>        	; +-------------------+-------------------+-----------------------+
 11263                              <1> 	;
 11264                              <1> 
 11265                              <1> 	;; CR3 REGISTER (Control Register 3)
 11266                              <1> 	;  31                                   12             5 4 3 2   0
 11267                              <1> 	; +---------------------------------------+-------------+---+-----+
 11268                              <1>       	; |                                       |  		|P|P|     |
 11269                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
 11270                              <1>       	; |                                       | 		|D|T|     |
 11271                              <1>    	; +---------------------------------------+-------------+---+-----+
 11272                              <1> 	;
 11273                              <1> 	;	PWT    - WRITE THROUGH
 11274                              <1> 	;	PCD    - CACHE DISABLE		
 11275                              <1> 	;
 11276                              <1> 	;
 11277                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
 11278                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11279                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11280                              <1>       	; |                                       |     | | | | |P|P|U|R| |
 11281                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
 11282                              <1>       	; |                                       |     | | | | |D|T|S|W| |
 11283                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11284                              <1> 	;
 11285                              <1>         ;       P      - PRESENT
 11286                              <1>         ;       R/W    - READ/WRITE
 11287                              <1>         ;       U/S    - USER/SUPERVISOR
 11288                              <1> 	;	PWT    - WRITE THROUGH
 11289                              <1> 	;	PCD    - CACHE DISABLE	
 11290                              <1> 	;	A      - ACCESSED	
 11291                              <1>         ;       D      - DIRTY (IGNORED)
 11292                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11293                              <1> 	;	G      - GLOBAL	(IGNORED) 
 11294                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11295                              <1> 	;
 11296                              <1> 	;
 11297                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
 11298                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11299                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11300                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
 11301                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
 11302                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
 11303                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11304                              <1> 	;
 11305                              <1>         ;       P      - PRESENT
 11306                              <1>         ;       R/W    - READ/WRITE
 11307                              <1>         ;       U/S    - USER/SUPERVISOR
 11308                              <1> 	;	PWT    - WRITE THROUGH
 11309                              <1> 	;	PCD    - CACHE DISABLE	
 11310                              <1> 	;	A      - ACCESSED	
 11311                              <1>         ;       D      - DIRTY
 11312                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11313                              <1> 	;	G      - GLOBAL	 
 11314                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11315                              <1> 	;
 11316                              <1> 	;
 11317                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
 11318                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11319                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11320                              <1>       	; |                                       |     | | | | | | |U|R| |
 11321                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
 11322                              <1>       	; |                                       |     | | | | | | |S|W| |
 11323                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11324                              <1> 	;
 11325                              <1>         ;       P      - PRESENT
 11326                              <1>         ;       R/W    - READ/WRITE
 11327                              <1>         ;       U/S    - USER/SUPERVISOR
 11328                              <1>         ;       D      - DIRTY
 11329                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11330                              <1> 	;
 11331                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
 11332                              <1> 	;
 11333                              <1> 	;
 11334                              <1> 	;; Invalid Page Table Entry
 11335                              <1> 	; 31                                                           1 0
 11336                              <1>       	; +-------------------------------------------------------------+-+
 11337                              <1>       	; |                                                             | |
 11338                              <1>       	; |                          AVAILABLE                          |0|
 11339                              <1>       	; |                                                             | |
 11340                              <1>       	; +-------------------------------------------------------------+-+
 11341                              <1> 	;
 11342                              <1> 
 11343 000031D9 53                  <1> 	push	ebx
 11344 000031DA 52                  <1> 	push	edx
 11345 000031DB 51                  <1> 	push	ecx
 11346                              <1> 	;
 11347                              <1> 	; 21/09/2015 (debugging)
 11348 000031DC FF05[6E700000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
 11349 000031E2 FF05[88810000]      <1> 	inc	dword [PF_Count] ; total page fault count	
 11350                              <1> 	; 28/06/2015
 11351                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
 11352 000031E8 8A15[80810000]      <1> 	mov	dl, [error_code]
 11353                              <1> 	;
 11354 000031EE F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
 11355                              <1> 			; sign
 11356 000031F1 741A                <1> 	jz	short pfh_alloc_np
 11357                              <1> 	; 
 11358                              <1> 	; If it is not a 'write on read only page' type page fault
 11359                              <1> 	; major page fault error with minor reason must be returned without 
 11360                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
 11361                              <1> 	; after return here!
 11362                              <1> 	; Page fault will be remedied, by copying page contents
 11363                              <1> 	; to newly allocated page with write permission;
 11364                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
 11365                              <1> 	; used for working with minimum possible memory usage. 
 11366                              <1> 	; sys_fork will duplicate page directory and tables of parent  
 11367                              <1> 	; process with 'read only' flag. If the child process attempts to
 11368                              <1> 	; write on these read only pages, page fault will be directed here
 11369                              <1> 	; for allocating a new page with same data/content. 
 11370                              <1> 	;
 11371                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
 11372                              <1> 	; will not force to separate CODE and DATA space 
 11373                              <1> 	; in a process/program... 
 11374                              <1> 	; CODE segment/section may contain DATA!
 11375                              <1> 	; It is flat, smoth and simplest programming method already as in 
 11376                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
 11377                              <1> 	;	
 11378 000031F3 F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
 11379                              <1> 			; sign
 11380 000031F6 0F8481000000        <1>         jz      pfh_p_err
 11381                              <1> 	; 31/08/2015
 11382 000031FC F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
 11383                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
 11384 000031FF 747C                <1>         jz	pfh_pv_err
 11385                              <1> 	;
 11386                              <1> 	; make a new page and copy the parent's page content
 11387                              <1> 	; as the child's new page content
 11388                              <1> 	;
 11389 00003201 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
 11390                              <1> 			 ; which has caused to page fault
 11391 00003204 E87C000000          <1> 	call 	copy_page
 11392 00003209 726B                <1>         jc      pfh_im_err ; insufficient memory
 11393                              <1> 	;
 11394 0000320B EB63                <1>         jmp     pfh_cpp_ok
 11395                              <1> 	;
 11396                              <1> pfh_alloc_np:
 11397 0000320D E817FDFFFF          <1> 	call	allocate_page	; (allocate a new page)
 11398 00003212 7262                <1>         jc      pfh_im_err	; 'insufficient memory' error
 11399                              <1> pfh_chk_cpl:
 11400                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11401                              <1> 		; (Lower 12 bits are ZERO, because 
 11402                              <1> 		;	the address is on a page boundary)
 11403 00003214 80E204              <1> 	and	dl, 4	; CPL = 3 ?
 11404 00003217 7505                <1> 	jnz	short pfh_um
 11405                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
 11406 00003219 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
 11407                              <1> 			 ; of the current/active page directory
 11408                              <1> 			 ; (Always kernel/system mode page directory, here!)
 11409                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
 11410 0000321C EB06                <1> 	jmp	short pfh_get_pde
 11411                              <1> 	;
 11412                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
 11413 0000321E 8B1D[58700000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
 11414                              <1> 			; Physical address of the USER's page directory
 11415                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
 11416                              <1> pfh_get_pde:
 11417 00003224 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
 11418 00003227 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
 11419                              <1> 			 ; which has been caused to page fault
 11420                              <1> 			 ;
 11421 0000322A C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
 11422 0000322D 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
 11423                              <1> 	;
 11424 00003230 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
 11425 00003232 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
 11426 00003234 F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
 11427 00003237 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
 11428                              <1> 			  	  ; set/validate page directory entry
 11429 00003239 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 11430 0000323E 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
 11431 00003240 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
 11432 00003242 EB16                <1> 	jmp	short pfh_get_pte
 11433                              <1> pfh_set_pde:
 11434                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
 11435                              <1> 	;;	 (So, we know this PDE is empty or invalid)
 11436                              <1> 	;
 11437 00003244 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
 11438 00003246 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
 11439 00003248 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
 11440 0000324A 89C3                <1> 	mov	ebx, eax
 11441 0000324C E8D8FCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
 11442 00003251 7223                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
 11443                              <1> pfh_spde_1:
 11444                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11445 00003253 89C1                <1> 	mov	ecx, eax
 11446 00003255 E840FDFFFF          <1> 	call	clear_page ; Clear page content
 11447                              <1> pfh_get_pte:
 11448 0000325A 0F20D0              <1> 	mov	eax, cr2 ; virtual address
 11449                              <1> 			 ; which has been caused to page fault
 11450 0000325D 89C7                <1> 	mov	edi, eax ; 20/07/2015
 11451 0000325F C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
 11452                              <1> 			 ; higher 20 bits of the page fault address 
 11453 00003262 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
 11454 00003267 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
 11455 0000326A 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
 11456                              <1> ; 17/04/2021 temporary
 11457                              <1> ;	mov	eax, [ebx] ; get previous value of pte
 11458                              <1> ;		; bit 0 of EAX is always 0 (otherwise we would not be here)
 11459                              <1> 
 11460                              <1> ; 17/04/2021
 11461                              <1> ; ('swap_in' procedure call has been disabled as temporary)
 11462                              <1> ;
 11463                              <1> ;	and	eax, eax
 11464                              <1> ;	jz	short pfh_gpte_1
 11465                              <1> ;	; 20/07/2015
 11466                              <1> ;	xchg	ebx, ecx ; new page address (physical)
 11467                              <1> ;	push	ebp ; 20/07/2015
 11468                              <1> ;	mov	ebp, cr2
 11469                              <1> ;		; ECX = physical address of the page table entry
 11470                              <1> ;		; EBX = Memory page address (physical!)
 11471                              <1> ;		; EAX = Swap disk (offset) address
 11472                              <1> ;		; EBP = virtual address (page fault address)
 11473                              <1> ;	call	swap_in
 11474                              <1> ;	pop	ebp
 11475                              <1> ;	jc      short pfh_err_retn
 11476                              <1> ;	xchg	ecx, ebx
 11477                              <1> ;		; EBX = physical address of the page table entry
 11478                              <1> ;		; ECX = new page
 11479                              <1> pfh_gpte_1:
 11480 0000326C 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
 11481 0000326E 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
 11482                              <1> pfh_cpp_ok:
 11483                              <1> ; 17/04/2021
 11484                              <1> ; ('add_to_swap_queue' procedure call has been disabled as temporary)
 11485                              <1> ;
 11486                              <1> ;	; 20/07/2015
 11487                              <1> ;	mov	ebx, cr2
 11488                              <1> ;	call 	add_to_swap_queue
 11489                              <1> 	;
 11490                              <1> 	; The new PTE (which contains the new page) will be added to 
 11491                              <1> 	; the swap queue, here. 
 11492                              <1> 	; (Later, if memory will become insufficient, 
 11493                              <1> 	; one page will be swapped out which is at the head of 
 11494                              <1> 	; the swap queue by using FIFO and access check methods.)
 11495                              <1> 	;
 11496 00003270 31C0                <1> 	xor	eax, eax  ; 0
 11497                              <1> 	;
 11498                              <1> pfh_err_retn:
 11499 00003272 59                  <1> 	pop	ecx
 11500 00003273 5A                  <1> 	pop	edx
 11501 00003274 5B                  <1> 	pop	ebx
 11502 00003275 C3                  <1> 	retn 
 11503                              <1> 	
 11504                              <1> pfh_im_err:
 11505 00003276 B8E4000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
 11506                              <1> 			; Major (Primary) Error: Page Fault
 11507                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
 11508 0000327B EBF5                <1> 	jmp	short pfh_err_retn
 11509                              <1> 
 11510                              <1> pfh_p_err: ; 09/03/2015
 11511                              <1> pfh_pv_err:
 11512                              <1> 	; Page fault was caused by a protection-violation
 11513 0000327D B8E6000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
 11514                              <1> 			; Major (Primary) Error: Page Fault
 11515                              <1> 			; Minor (Secondary) Error: Protection violation !
 11516 00003282 F9                  <1> 	stc
 11517 00003283 EBED                <1> 	jmp	short pfh_err_retn
 11518                              <1> 
 11519                              <1> copy_page:
 11520                              <1> 	; 16/04/2021
 11521                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11522                              <1> 	; 22/09/2015
 11523                              <1> 	; 21/09/2015
 11524                              <1> 	; 19/09/2015
 11525                              <1> 	; 07/09/2015
 11526                              <1> 	; 31/08/2015
 11527                              <1> 	; 20/07/2015
 11528                              <1> 	; 05/05/2015
 11529                              <1> 	; 03/05/2015
 11530                              <1> 	; 18/04/2015
 11531                              <1> 	; 12/04/2015
 11532                              <1> 	; 30/10/2014
 11533                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
 11534                              <1> 	;
 11535                              <1> 	; INPUT -> 
 11536                              <1> 	;	EBX = Virtual (linear) address of source page
 11537                              <1> 	;	     (Page fault address)
 11538                              <1> 	; OUTPUT ->
 11539                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11540                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11541                              <1> 	;	EAX = 0 (CF = 1) 
 11542                              <1> 	;		if there is not a free page to be allocated
 11543                              <1> 	;	(page content of the source page will be copied
 11544                              <1> 	;	onto the target/new page) 	
 11545                              <1> 	;
 11546                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
 11547                              <1> 	;
 11548                              <1> 
 11549                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11550                              <1> 	; INPUT: 
 11551                              <1> 	;	EBX = Virtual (linear) address of source page
 11552                              <1> 	;	     (Page fault address)
 11553                              <1> 	; OUTPUT:
 11554                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11555                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11556                              <1> 	;	EAX = 0 (CF = 1) 
 11557                              <1> 	;		if there is not a free page to be allocated
 11558                              <1> 	;	(page content of the source page will be copied
 11559                              <1> 	;	onto the target/new page) 	
 11560                              <1> 	;
 11561                              <1> 	; Modified Registers -> ecx, ebx (except EAX) ; 16/04/2021
 11562                              <1> 	
 11563 00003285 56                  <1> 	push	esi ; *
 11564 00003286 57                  <1> 	push	edi ; **
 11565                              <1> 	; 16/04/2021
 11566                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11567                              <1> 	;push	ebx ; ***
 11568                              <1> 	;push	ecx ; ****
 11569 00003287 31F6                <1> 	xor 	esi, esi
 11570 00003289 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
 11571 0000328C 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
 11572 0000328E C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
 11573 00003291 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
 11574 00003294 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
 11575 00003296 031D[58700000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
 11576 0000329C 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
 11577 0000329E 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
 11578 000032A2 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
 11579 000032A4 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11580 000032AA 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
 11581 000032AE 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
 11582                              <1> 	; 07/09/2015
 11583 000032B0 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
 11584                              <1> 				     ; read only page as a child process?)	
 11585 000032B5 7509                <1> 	jnz	short cpp_0 ; yes
 11586 000032B7 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
 11587 000032B9 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
 11588 000032BE EB32                <1> 	jmp	short cpp_1
 11589                              <1> cpp_0:
 11590 000032C0 89FE                <1> 	mov	esi, edi
 11591 000032C2 0335[5C700000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
 11592 000032C8 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
 11593 000032CA 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11594 000032CE 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
 11595 000032D0 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11596 000032D6 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
 11597 000032DA 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
 11598 000032DC 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
 11599                              <1> 	; 21/09/2015
 11600 000032DE 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
 11601 000032E0 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
 11602                              <1> 	;
 11603 000032E4 F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
 11604 000032E7 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
 11605                              <1> 	;
 11606 000032E9 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
 11607 000032EE 39C8                <1> 	cmp	eax, ecx   ; Same page?	
 11608 000032F0 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
 11609                              <1> 			    ; Convert child's page to writable page
 11610                              <1> cpp_1:
 11611 000032F2 E832FCFFFF          <1> 	call	allocate_page
 11612 000032F7 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
 11613 000032F9 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
 11614 000032FB 7405                <1> 	jz	short cpp_2
 11615                              <1> 		; Convert read only page to writable page 
 11616                              <1> 		;(for the parent of the current process)
 11617                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
 11618                              <1> 	; 22/09/2015
 11619 000032FD 890E                <1> 	mov	[esi], ecx
 11620 000032FF 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
 11621                              <1> 				 ; 1+2+4 = 7
 11622                              <1> cpp_2:
 11623 00003302 89C7                <1> 	mov	edi, eax ; new page address of the child process
 11624                              <1> 	; 07/09/2015
 11625 00003304 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
 11626 00003306 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 11627 0000330B F3A5                <1> 	rep	movsd ; 31/08/2015
 11628                              <1> cpp_3:		
 11629 0000330D 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
 11630 0000330F 8903                <1> 	mov	[ebx], eax ; Update PTE
 11631 00003311 28C0                <1> 	sub	al, al ; clear attributes
 11632                              <1> cpp_4:
 11633                              <1> 	; 16/04/2021
 11634                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11635                              <1> 	;pop	ecx ; ****
 11636                              <1> 	;pop	ebx ; ***
 11637 00003313 5F                  <1> 	pop	edi ; **
 11638 00003314 5E                  <1> 	pop	esi ; *
 11639 00003315 C3                  <1> 	retn
 11640                              <1> 
 11641                              <1> ;; 28/04/2015
 11642                              <1> ;; 24/10/2014
 11643                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
 11644                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
 11645                              <1> ;;
 11646                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
 11647                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
 11648                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
 11649                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
 11650                              <1> ;;
 11651                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
 11652                              <1> ;;
 11653                              <1> ;; Method:
 11654                              <1> ;;	Swap page queue is a list of allocated pages with physical
 11655                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
 11656                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
 11657                              <1> ;;	When a new page is being allocated, swap queue is updated
 11658                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
 11659                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
 11660                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
 11661                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
 11662                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
 11663                              <1> ;;	offset value becomes it's previous offset value - 4.
 11664                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
 11665                              <1> ;;	the queue/list is not shifted.
 11666                              <1> ;;	After the queue/list shift, newly allocated page is added
 11667                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
 11668                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
 11669                              <1> ;;	will not be added to the tail of swap page queue.  		 
 11670                              <1> ;;	
 11671                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
 11672                              <1> ;;	the first non-accessed, writable page in the list, 
 11673                              <1> ;;	from the head to the tail. The list is shifted to left 
 11674                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
 11675                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
 11676                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
 11677                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
 11678                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
 11679                              <1> ;;	procedure will be failed)...
 11680                              <1> ;;
 11681                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
 11682                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
 11683                              <1> ;;	(PTE) will be added to the tail of the queue after
 11684                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
 11685                              <1> ;;	the queue will be rotated and the PTE in the head will be
 11686                              <1> ;;	added to the tail after resetting 'accessed' bit. 
 11687                              <1> ;;
 11688                              <1> ;;
 11689                              <1> ;;	
 11690                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
 11691                              <1> ;;
 11692                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
 11693                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
 11694                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
 11695                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
 11696                              <1> ;;
 11697                              <1> ;; [swpd_next] = the first free block address in swapped page records
 11698                              <1> ;;    		 for next free block search by 'swap_out' procedure.
 11699                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
 11700                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
 11701                              <1> ;; 		 (entire swap space must be accessed by using
 11702                              <1> ;;		 31 bit offset address) 
 11703                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
 11704                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
 11705                              <1> ;;		  0 for file, or beginning sector of the swap partition
 11706                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
 11707                              <1> ;;
 11708                              <1> ;; 					
 11709                              <1> ;; Method:
 11710                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
 11711                              <1> ;;	procedure swaps out a page from memory to the swap disk 
 11712                              <1> ;;	(partition) or swap file to get a new free page at the memory.
 11713                              <1> ;;	Swapping out is performed by using swap page queue.
 11714                              <1> ;;
 11715                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
 11716                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
 11717                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
 11718                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
 11719                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
 11720                              <1> ;;	Absolute physical (logical) address of the swapped page is 
 11721                              <1> ;;	calculated by adding offset value to the swap partition's 
 11722                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
 11723                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
 11724                              <1> ;;	and offset value is equal to absolute (physical or logical)
 11725                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
 11726                              <1> ;;	is in a partitioned virtual hard disk.) 
 11727                              <1> ;;
 11728                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
 11729                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
 11730                              <1> ;;
 11731                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
 11732                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
 11733                              <1> ;;
 11734                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
 11735                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
 11736                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
 11737                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
 11738                              <1> ;;	it means relevant (respective) block is in use, and, 
 11739                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
 11740                              <1> ;;      swap disk/file block is free.
 11741                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
 11742                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
 11743                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
 11744                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
 11745                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
 11746                              <1> ;;	------------------------------------------------------------
 11747                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
 11748                              <1> ;;	------------------------------------------------------------
 11749                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
 11750                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
 11751                              <1> ;;
 11752                              <1> ;;	..............................................................
 11753                              <1> ;;
 11754                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
 11755                              <1> ;;	then it searches Swap Allocation Table if free count is not
 11756                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
 11757                              <1> ;;	position with value of 1 on the table is converted to swap
 11758                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
 11759                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
 11760                              <1> ;;	number of physical swap disk or virtual swap disk)
 11761                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
 11762                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
 11763                              <1> ;;	(memory page). That will be a direct disk write procedure.
 11764                              <1> ;;	(for preventing late memory allocation, significant waiting). 
 11765                              <1> ;;	If disk write procedure returns with error or free count of 
 11766                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
 11767                              <1> ;;	'insufficient memory error' (cf=1). 
 11768                              <1> ;;
 11769                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
 11770                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
 11771                              <1> ;;	in other words, 'swap_out' will not check the table for other
 11772                              <1> ;;	free blocks after a disk write error. It will return to 
 11773                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
 11774                              <1> ;;
 11775                              <1> ;;	After writing the page on to swap disk/file address/sector,
 11776                              <1> ;;	'swap_out' procedure returns with that swap (offset) sector
 11777                              <1> ;;	address (cf=0). 
 11778                              <1> ;;
 11779                              <1> ;;	..............................................................
 11780                              <1> ;;
 11781                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
 11782                              <1> ;;	file sectors at specified memory page. Then page allocation
 11783                              <1> ;;	procedure updates relevant page table entry with 'present' 
 11784                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
 11785                              <1> ;;	to do, except to terminate the process which is the owner of
 11786                              <1> ;;	the swapped page.
 11787                              <1> ;;
 11788                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
 11789                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
 11790                              <1> ;;	updates [swpd_first] pointer if it is required.
 11791                              <1> ;;
 11792                              <1> ;;	..............................................................	 
 11793                              <1> ;;
 11794                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
 11795                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
 11796                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
 11797                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
 11798                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
 11799                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
 11800                              <1> ;;
 11801                              <1> 
 11802                              <1> ; 17/04/2021
 11803                              <1> ; ('swap_in' procedure call is disabled as temporary)
 11804                              <1> 
 11805                              <1> ; 30/11/2021 - temporary !
 11806                              <1> ;swap_in:
 11807                              <1> 	; 31/08/2015
 11808                              <1> 	; 20/07/2015
 11809                              <1> 	; 28/04/2015
 11810                              <1> 	; 18/04/2015
 11811                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 11812                              <1> 	;
 11813                              <1> 	; INPUT -> 
 11814                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
 11815                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
 11816                              <1> 	;	EAX = Offset Address for the swapped page on the
 11817                              <1> 	;	      swap disk or in the swap file.
 11818                              <1> 	;
 11819                              <1> 	; OUTPUT ->
 11820                              <1> 	;	EAX = 0 if loading at memory has been successful
 11821                              <1> 	;
 11822                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
 11823                              <1> 	;		  or sector not present or drive not ready
 11824                              <1> 	;	     EAX = Error code
 11825                              <1> 	;	     [u.error] = EAX 
 11826                              <1> 	;		       = The last error code for the process
 11827                              <1> 	;		         (will be reset after returning to user)	  
 11828                              <1> 	;
 11829                              <1> 	; Modified Registers -> EAX
 11830                              <1> 	;
 11831                              <1> 
 11832                              <1> ;       cmp     dword [swp_drv], 0
 11833                              <1> ;	jna	short swpin_dnp_err
 11834                              <1> ;
 11835                              <1> ;	cmp	eax, [swpd_size]
 11836                              <1> ;	jnb	short swpin_snp_err
 11837                              <1> ;
 11838                              <1> ;	push	esi
 11839                              <1> ;	push	ebx
 11840                              <1> ;	push	ecx
 11841                              <1> ;	mov	esi, [swp_drv]	
 11842                              <1> ;	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 11843                              <1> ;		; Note: Even if corresponding physical disk's sector 
 11844                              <1> ;		; size different than 512 bytes, logical disk sector
 11845                              <1> ;		; size is 512 bytes and disk reading procedure
 11846                              <1> ;		; will be performed for reading 4096 bytes
 11847                              <1> ;		; (2*2048, 8*512). 
 11848                              <1> ;	; ESI = Logical disk description table address
 11849                              <1> ;	; EBX = Memory page (buffer) address (physical!)
 11850                              <1> ;	; EAX = Sector adress (offset address, logical sector number)
 11851                              <1> ;	; ECX = Sector count ; 8 sectors
 11852                              <1> ;	push	eax
 11853                              <1> ;	call	logical_disk_read
 11854                              <1> ;	pop	eax
 11855                              <1> ;	jnc	short swpin_read_ok
 11856                              <1> ;	;
 11857                              <1> ;	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
 11858                              <1> ;	mov	[u.error], eax
 11859                              <1> ;	jmp	short swpin_retn
 11860                              <1> ;	;
 11861                              <1> ;swpin_read_ok:
 11862                              <1> ;	; EAX = Offset address (logical sector number)
 11863                              <1> ;	call	unlink_swap_block  ; Deallocate swap block	
 11864                              <1> ;	;
 11865                              <1> ;	; EBX = Memory page (buffer) address (physical!)
 11866                              <1> ;	; 20/07/2015
 11867                              <1> ;	mov	ebx, ebp ; virtual address (page fault address)
 11868                              <1> ;       and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 11869                              <1> ;	mov	bl, [u.uno] ; current process number
 11870                              <1> ;	; EBX = Virtual (Linear) address & process number combination
 11871                              <1> ;	call	swap_queue_shift
 11872                              <1> ;	; eax = 0 ; 10/06/2016 (if ebx input > 0, eax output = 0)
 11873                              <1> ;	;sub	eax, eax  ; 0 ; Error Code = 0  (no error)
 11874                              <1> ;	; zf = 1
 11875                              <1> ;swpin_retn:
 11876                              <1> ;	pop	ecx
 11877                              <1> ;	pop	ebx
 11878                              <1> ;	pop	esi
 11879                              <1> ;	retn
 11880                              <1> ;
 11881                              <1> ;swpin_dnp_err:
 11882                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR
 11883                              <1> ;swpin_err_retn:
 11884                              <1> ;	mov	[u.error], eax
 11885                              <1> ;	stc
 11886                              <1> ;	retn
 11887                              <1> ;
 11888                              <1> ;swpin_snp_err:
 11889                              <1> ;	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
 11890                              <1> ;	jmp	short swpin_err_retn
 11891                              <1> 
 11892                              <1> ; 17/04/2021
 11893                              <1> ; ('swap_out' procedure call is disabled as temporary)
 11894                              <1> 
 11895                              <1> ; 30/11/2021 - temporary !
 11896                              <1> ;swap_out:
 11897                              <1> 	; 10/06/2016
 11898                              <1> 	; 07/06/2016
 11899                              <1>         ; 23/05/2016
 11900                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
 11901                              <1> 	; 24/10/2014 - 31/08/2015 (Retro UNIX 386 v1)
 11902                              <1> 	;
 11903                              <1> 	; INPUT -> 
 11904                              <1> 	;	none
 11905                              <1> 	;
 11906                              <1> 	; OUTPUT ->
 11907                              <1> 	;	EAX = Physical page address (which is swapped out
 11908                              <1> 	;	      for allocating a new page)
 11909                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
 11910                              <1> 	;		  or sector not present or drive not ready
 11911                              <1> 	;	     EAX = Error code
 11912                              <1> 	;	     [u.error] = EAX 
 11913                              <1> 	;		       = The last error code for the process
 11914                              <1> 	;		         (will be reset after returning to user)	  
 11915                              <1> 	;
 11916                              <1> 	; Modified Registers -> none (except EAX)
 11917                              <1> 	;
 11918                              <1> 
 11919                              <1> ;	cmp 	word [swpq_count], 1
 11920                              <1> ;       jc      swpout_im_err ; 'insufficient memory'
 11921                              <1> ;
 11922                              <1> ;       ;cmp    dword [swp_drv], 1
 11923                              <1> ;	;jc	short swpout_dnp_err ; 'swap disk/file not present'
 11924                              <1> ;
 11925                              <1> ;       cmp     dword [swpd_free], 1
 11926                              <1> ;       jc      swpout_nfspc_err ; 'no free space on swap disk'
 11927                              <1> ;
 11928                              <1> ;	push	ebx ; *
 11929                              <1> ;swpout_1:
 11930                              <1> ;	; 10/06/2016
 11931                              <1> ;	xor	ebx, ebx ; shift the queue and return a PTE value
 11932                              <1> ;	call	swap_queue_shift
 11933                              <1> ;	and	eax, eax	; 0 = empty queue (improper entries)
 11934                              <1> ;       jz      swpout_npts_err        ; There is not any proper PTE
 11935                              <1> ;				       ; pointer in the swap queue
 11936                              <1> ;	; EAX = PTE value of the page
 11937                              <1> ;	; EBX = PTE address of the page
 11938                              <1> ;	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11939                              <1> ;	;
 11940                              <1> ;	; 07/06/2016
 11941                              <1> ;	; 19/05/2016
 11942                              <1> ;	; check this page is in timer events or not
 11943                              <1> ;	
 11944                              <1> ;swpout_timer_page_0:
 11945                              <1> ;	push	edx ; **
 11946                              <1> ;
 11947                              <1> ;	; 07/06/2016
 11948                              <1> ;	cmp	byte [timer_events], 0 
 11949                              <1> ;	jna	short swpout_2
 11950                              <1> ;	;
 11951                              <1> ;	mov	dl, [timer_events]
 11952                              <1> ;
 11953                              <1> ;	push	ecx ; ***
 11954                              <1> ;	push	ebx ; ****
 11955                              <1> ;	mov	ebx, timer_set ; beginning address of timer event
 11956                              <1> ;			       ; structures 
 11957                              <1> ;swpout_timer_page_1:
 11958                              <1> ;	mov	cl, [ebx]
 11959                              <1> ;	or	cl, cl ; 0 = free, >0 = process number
 11960                              <1> ;	jz	short swpout_timer_page_3
 11961                              <1> ;	mov	ecx, [ebx+12] ; response (signal return) address
 11962                              <1> ;	and	cx, PTE_A_CLEAR ; clear offset part (right 12 bits)
 11963                              <1> ;				; of the response byte address, to
 11964                              <1> ;				; get beginning of the page address)
 11965                              <1> ;	cmp	eax, ecx
 11966                              <1> ;	jne	short swpout_timer_page_2 ; not same page
 11967                              <1> ;	
 11968                              <1> ;	; !same page!
 11969                              <1> ;	;
 11970                              <1> ;	; NOTE: // 19/05/2016 // - TRDOS 386 feature only ! -
 11971                              <1> ;	; This page will be used by the kernel to put timer event
 11972                              <1> ;	; response (signal return) byte at the requested address;
 11973                              <1> ;	; in order to prevent a possible wrong write (while
 11974                              <1> ;	; this page is swapped out) on physical memory,
 11975                              <1> ;	; we must protect this page against to be swapped out!
 11976                              <1> ;	;
 11977                              <1> ;	pop	ebx ; ****
 11978                              <1> ;	pop	ecx ; ***
 11979                              <1> ;	pop	edx ; **
 11980                              <1> ;	jmp	short swpout_1	; do not swap out this page !
 11981                              <1> ; 
 11982                              <1> ;swpout_timer_page_2:
 11983                              <1> ;	; 07/06/2016
 11984                              <1> ;	dec	dl
 11985                              <1> ;	jz	short swpout_timer_page_4
 11986                              <1> ;swpout_timer_page_3:
 11987                              <1> ;	;cmp	ebx, timer_set + 240 ; last timer event (15*16) 
 11988                              <1> ;	;jnb	short swpout_timer_page_4
 11989                              <1> ;	add	ebx, 16
 11990                              <1> ;	jmp	short swpout_timer_page_1	
 11991                              <1> ;
 11992                              <1> ;swpout_timer_page_4:
 11993                              <1> ;	pop	ebx ; ****
 11994                              <1> ;	pop	ecx ; ***
 11995                              <1> ;swpout_2:
 11996                              <1> ;	mov	edx, ebx	       ; Page table entry address	
 11997                              <1> ;	mov	ebx, eax	       ; Buffer (Page) Address				
 11998                              <1> ;	;
 11999                              <1> ;	call	link_swap_block
 12000                              <1> ;	jnc	short swpout_3	       ; It may not be needed here	
 12001                              <1> ;				       ; because [swpd_free] value
 12002                              <1> ;				       ; was checked at the beginging. 	
 12003                              <1> ;	pop	edx ; **
 12004                              <1> ;	pop	ebx ; *
 12005                              <1> ;	jmp	short swpout_nfspc_err 
 12006                              <1> ;swpout_3:
 12007                              <1> ;	test	eax, 80000000h ; test bit 31 (this may not be needed!)
 12008                              <1> ;	jnz	short swpout_nfspc_err  ; 10/06/2016 (bit 31 = 1 !)
 12009                              <1> ;	;	
 12010                              <1> ;	push	esi ; **
 12011                              <1> ;	push	ecx ; ***
 12012                              <1> ;	push	eax ; sector address ; (31 bit !, bit 31 = 0)
 12013                              <1> ;	mov	esi, [swp_drv]	
 12014                              <1> ;	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 12015                              <1> ;		; Note: Even if corresponding physical disk's sector 
 12016                              <1> ;		; size different than 512 bytes, logical disk sector
 12017                              <1> ;		; size is 512 bytes and disk writing procedure
 12018                              <1> ;		; will be performed for writing 4096 bytes
 12019                              <1> ;		; (2*2048, 8*512). 
 12020                              <1> ;	; ESI = Logical disk description table address
 12021                              <1> ;	; EBX = Buffer (Page) address
 12022                              <1> ;	; EAX = Sector adress (offset address, logical sector number)
 12023                              <1> ;	; ECX = Sector count ; 8 sectors
 12024                              <1> ;	; edx = PTE address
 12025                              <1> ;	call	logical_disk_write
 12026                              <1> ;	; edx = PTE address
 12027                              <1> ;	pop	ecx ; sector address	
 12028                              <1> ;	jnc	short swpout_write_ok
 12029                              <1> ;	;
 12030                              <1> ;	;; call	unlink_swap_block ; this block must be left as 'in use'
 12031                              <1> ;swpout_dw_err:
 12032                              <1> ;	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
 12033                              <1> ;	mov	[u.error], eax
 12034                              <1> ;	jmp	short swpout_retn
 12035                              <1> ;	;
 12036                              <1> ;swpout_write_ok:
 12037                              <1> ;	; EBX = Buffer (page) address
 12038                              <1> ;	; EDX = Page Table Entry address
 12039                              <1> ;	; ECX = Swap disk sector (file block) address (31 bit)
 12040                              <1> ;	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
 12041                              <1> ;	mov 	[edx], ecx 
 12042                              <1> ;		; bit 0 = 0 (swapped page)
 12043                              <1> ;	mov	eax, ebx
 12044                              <1> ;swpout_retn:
 12045                              <1> ;	pop	ecx ; ***
 12046                              <1> ;	pop	esi ; **
 12047                              <1> ;	pop	ebx ; *
 12048                              <1> ;	retn
 12049                              <1> ;
 12050                              <1> ;;swpout_dnp_err:
 12051                              <1> ;;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
 12052                              <1> ;;	jmp	short swpout_err_retn
 12053                              <1> ;swpout_nfspc_err:
 12054                              <1> ;	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
 12055                              <1> ;swpout_err_retn:
 12056                              <1> ;	mov	[u.error], eax
 12057                              <1> ;	;stc
 12058                              <1> ;	retn
 12059                              <1> ;swpout_npts_err:
 12060                              <1> ;	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
 12061                              <1> ;	pop	ebx
 12062                              <1> ;	jmp	short swpout_err_retn
 12063                              <1> ;swpout_im_err:
 12064                              <1> ;	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
 12065                              <1> ;	jmp	short swpout_err_retn
 12066                              <1> 
 12067                              <1> ; 17/04/2021
 12068                              <1> ; ('swap_queue_shift' procedure call is disabled as temporary)
 12069                              <1> 
 12070                              <1> ; 30/11/2021 - temporary !
 12071                              <1> ;swap_queue_shift:
 12072                              <1> 	; 26/03/2017
 12073                              <1> 	; 10/06/2016
 12074                              <1> 	; 09/06/2016 - TRDOS 386 (TRDOS v2.0)
 12075                              <1> 	; 23/10/2014 - 20/07/2015 (Retro UNIX 386 v1)
 12076                              <1> 	;
 12077                              <1> 	; INPUT ->
 12078                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
 12079                              <1> 	;	      and process number combination (bit 0 to 11)
 12080                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
 12081                              <1> 	;	
 12082                              <1> 	; OUTPUT ->
 12083                              <1> 	;	If EBX input > 0 
 12084                              <1> 	;	   the queue will be shifted 4 bytes (dword),
 12085                              <1> 	; 	   from the tail to the head, up to entry offset
 12086                              <1> 	; 	   which points to EBX input value or nothing
 12087                              <1> 	;	   to do if EBX value is not found on the queue.
 12088                              <1> 	;	   (The entry -with EBX value- will be removed
 12089                              <1> 	;	   from the queue if it is found.)
 12090                              <1> 	;
 12091                              <1> 	;	   EAX = 0		
 12092                              <1> 	;
 12093                              <1> 	;	If EBX input = 0
 12094                              <1> 	;	   the queue will be shifted 4 bytes (dword),
 12095                              <1> 	; 	   from the tail to the head, if the PTE address
 12096                              <1> 	;	   which is pointed in head of the queue is marked
 12097                              <1> 	;	   as "accessed" or it is marked as "non present".
 12098                              <1> 	;	   (If "accessed" flag of the PTE -which is pointed
 12099                              <1> 	;	   in the head- is set -to 1-, it will be reset
 12100                              <1> 	;	   -to 0- and then, the queue will be rotated 
 12101                              <1> 	;	   -without dropping pointer of the PTE from 
 12102                              <1> 	;	   the queue- for 4 bytes on head to tail direction.
 12103                              <1> 	;	   Pointer in the head will be moved into the tail,
 12104                              <1> 	;	   other PTEs will be shifted on head direction.)
 12105                              <1> 	;
 12106                              <1> 	;	   Swap queue will be shifted up to the first
 12107                              <1> 	;	   'present' or 'non accessed' page will be found
 12108                              <1> 	;	   (as pointed) on the queue head (then it will be
 12109                              <1>         ;          removed/dropped from the queue).
 12110                              <1> 	;
 12111                              <1> 	;	   EAX (> 0) = PTE value of the page which is
 12112                              <1> 	;		 (it's pointer -virtual address-) dropped
 12113                              <1> 	;		 (removed) from swap queue.
 12114                              <1> 	;	   EBX = PTE address of the page (if EAX > 0)
 12115                              <1> 	;	         which is (it's pointer -virtual address-)
 12116                              <1> 	;		 dropped (removed) from swap queue.
 12117                              <1> 	;
 12118                              <1> 	;	   EAX = 0 -> empty swap queue ! 
 12119                              <1> 	;
 12120                              <1> 	; Modified Registers -> EAX, EBX
 12121                              <1> 	;
 12122                              <1> ;	movzx   eax, word [swpq_count]  ; Max. 1024
 12123                              <1> ;	and	ax, ax
 12124                              <1> ;	jz	short swpqs_retn
 12125                              <1> ;	push	edi
 12126                              <1> ;	push	esi
 12127                              <1> ;	push	ecx
 12128                              <1> ;	mov	esi, swap_queue
 12129                              <1> ;	mov	ecx, eax
 12130                              <1> ;	or	ebx, ebx
 12131                              <1> ;	jz	short swpqs_7
 12132                              <1> ;swpqs_1:
 12133                              <1> ;	lodsd
 12134                              <1> ;	cmp	eax, ebx
 12135                              <1> ;	je	short swpqs_2
 12136                              <1> ;	loop	swpqs_1
 12137                              <1> ;	; 10/06/2016
 12138                              <1> ;	sub	eax, eax 
 12139                              <1> ;	jmp	short swpqs_6
 12140                              <1> ;swpqs_2:
 12141                              <1> ;	mov	edi, esi
 12142                              <1> ;	sub 	edi, 4
 12143                              <1> ;swpqs_3:
 12144                              <1> ;	dec	word [swpq_count]
 12145                              <1> ;	jz	short swpqs_5
 12146                              <1> ;swpqs_4:
 12147                              <1> ;	dec 	ecx
 12148                              <1> ;	rep	movsd	; shift up (to the head)
 12149                              <1> ;swpqs_5:
 12150                              <1> ;	xor	eax, eax
 12151                              <1> ;	mov	[edi], eax
 12152                              <1> ;swpqs_6:
 12153                              <1> ;	pop	ecx
 12154                              <1> ;	pop	esi
 12155                              <1> ;	pop	edi
 12156                              <1> ;swpqs_retn:
 12157                              <1> ;	retn		
 12158                              <1> ;swpqs_7:
 12159                              <1> ;	mov	edi, esi ; head
 12160                              <1> ;	lodsd
 12161                              <1> ;	; 20/07/2015
 12162                              <1> ;	mov	ebx, eax
 12163                              <1> ;	and	ebx, ~PAGE_OFF ; ~0FFFh 
 12164                              <1> ;		      ; ebx = virtual address (at page boundary)	
 12165                              <1> ;	and	eax, PAGE_OFF ; 0FFFh
 12166                              <1> ;		      ; ax = process number (1 to 4095)
 12167                              <1> ;	cmp	al, [u.uno]
 12168                              <1> ;		; Max. 16 (nproc) processes for Retro UNIX 386 v1
 12169                              <1> ;	jne	short swpqs_8
 12170                              <1> ;	mov	eax, [u.pgdir]
 12171                              <1> ;	jmp	short swpqs_9
 12172                              <1> ;swpqs_8:
 12173                              <1> ;	; 09/06/2016
 12174                              <1> ;	cmp	byte [eax+p.stat-1], 0
 12175                              <1> ;	jna	short swpqs_3     ; free (or terminated) process
 12176                              <1> ;	cmp	byte [eax+p.stat-1], 2 ; waiting
 12177                              <1> ;	ja	short swpqs_3 	  ; zombie (3) or undefined ?	
 12178                              <1> ;
 12179                              <1> ;	;shl	ax, 2
 12180                              <1> ;	shl	al, 2
 12181                              <1> ;	mov 	eax, [eax+p.upage-4]
 12182                              <1> ;	or	eax, eax
 12183                              <1> ;	jz	short swpqs_3 ; invalid upage
 12184                              <1> ;	add	eax, u.pgdir - user
 12185                              <1> ;			 ; u.pgdir value for the process
 12186                              <1> ;			 ; is in [eax]
 12187                              <1> ;	mov	eax, [eax]
 12188                              <1> ;	and	eax, eax
 12189                              <1> ;	jz	short swpqs_3 ; invalid page directory
 12190                              <1> ;swpqs_9:
 12191                              <1> ;	push	edx
 12192                              <1> ;	; eax = page directory
 12193                              <1> ;	; ebx = virtual address
 12194                              <1> ;	call	get_pte
 12195                              <1> ;	mov	ebx, edx	; PTE address
 12196                              <1> ;	pop	edx
 12197                              <1> ;	; 10/06/2016
 12198                              <1> ;	jc	short swpqs_13 ; empty PDE
 12199                              <1> ;	; EAX = PTE value
 12200                              <1> ;	test	al, PTE_A_PRESENT ; bit 0 = 1
 12201                              <1> ;	jz	short swpqs_13  ; Drop non-present page
 12202                              <1> ;			        ; from the queue (head)
 12203                              <1> ;	test	al, PTE_A_WRITE	; bit 1 = 0 (read only)
 12204                              <1> ;	jz	short swpqs_13  ; Drop read only page
 12205                              <1> ;			        ; from the queue (head) 	
 12206                              <1> ;	;test	al, PTE_A_ACCESS ; bit 5 = 1 (Accessed)
 12207                              <1> ;	;jnz	short swpqs_11  ; present
 12208                              <1> ;			        ; accessed page
 12209                              <1> ;       btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
 12210                              <1> ;	jc	short swpqs_11  ; accessed page
 12211                              <1> ;
 12212                              <1> ;	dec	ecx
 12213                              <1> ;	mov	[swpq_count], cx
 12214                              <1> ;       jz      short swpqs_10
 12215                              <1> ;		; esi = head + 4
 12216                              <1> ;		; edi = head
 12217                              <1> ;	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 12218                              <1> ;swpqs_10:
 12219                              <1> ;	mov	[edi], ecx ; 0
 12220                              <1> ;	jmp	short swpqs_6 ; 26/03/2017
 12221                              <1> ;
 12222                              <1> ;swpqs_11:
 12223                              <1> ;	mov	[ebx], eax     ; save changed attribute
 12224                              <1> ;	; Rotation (head -> tail)
 12225                              <1> ;	dec	ecx     ; entry count -> last entry number		
 12226                              <1> ;	jz	short swpqs_10
 12227                              <1> ;		; esi = head + 4
 12228                              <1> ;		; edi = head
 12229                              <1> ;	mov	eax, [edi] ; 20/07/2015
 12230                              <1> ;	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 12231                              <1> ;	mov	[edi], eax ; head -> tail ; [k] = [1]
 12232                              <1> ;
 12233                              <1> ;	mov	cx, [swpq_count]
 12234                              <1> ;
 12235                              <1> ;swpqs_12:
 12236                              <1> ;	mov	esi, swap_queue ; head
 12237                              <1> ;       jmp     swpqs_7
 12238                              <1> ;
 12239                              <1> ;swpqs_13:
 12240                              <1> ;	dec	ecx
 12241                              <1> ;	mov	[swpq_count], cx
 12242                              <1> ;       jz      swpqs_5
 12243                              <1> ;	jmp	short swpqs_12
 12244                              <1> 
 12245                              <1> ; 17/04/2021
 12246                              <1> ; ('add_to_swp_queue' procedure call is disabled as temporary)
 12247                              <1> 
 12248                              <1> ; 30/11/2021 - temporary !
 12249                              <1> ;add_to_swap_queue:
 12250                              <1> 	; 20/02/2017
 12251                              <1> 	; 20/07/2015
 12252                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12253                              <1> 	;
 12254                              <1> 	; Adds new page to swap queue
 12255                              <1> 	; (page directories and page tables must not be added
 12256                              <1> 	; to swap queue)	
 12257                              <1> 	;
 12258                              <1> 	; INPUT ->
 12259                              <1> 	;	EBX = Linear (Virtual) addr for current process
 12260                              <1> 	;	[u.uno]
 12261                              <1> 	;	20/02/2017
 12262                              <1> 	;	(Linear address = CORE + user's virtual address)
 12263                              <1> 	;
 12264                              <1> 	; OUTPUT ->
 12265                              <1> 	;	EAX = [swpq_count]
 12266                              <1> 	;	      (after the PTE has been added)
 12267                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
 12268                              <1> 	;	      the PTE could not be added.
 12269                              <1> 	;
 12270                              <1> 	; Modified Registers -> EAX
 12271                              <1> 	;
 12272                              <1> ;	push	ebx
 12273                              <1> ;       and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 12274                              <1> ;	mov	bl, [u.uno] ; current process number
 12275                              <1> ;	call	swap_queue_shift ; drop from the queue if
 12276                              <1> ;				 ; it is already on the queue
 12277                              <1> ;		; then add it to the tail of the queue
 12278                              <1> ;	movzx	eax, word [swpq_count]
 12279                              <1> ;	cmp	ax, 1024
 12280                              <1> ;	jb	short atsq_1
 12281                              <1> ;	sub	ax, ax
 12282                              <1> ;	pop	ebx
 12283                              <1> ;	retn
 12284                              <1> ;atsq_1:
 12285                              <1> ;	push	esi
 12286                              <1> ;	mov	esi, swap_queue
 12287                              <1> ;	and	ax, ax
 12288                              <1> ;	jz	short atsq_2
 12289                              <1> ;	shl	ax, 2	; convert to offset
 12290                              <1> ;	add	esi, eax
 12291                              <1> ;	shr	ax, 2
 12292                              <1> ;atsq_2:
 12293                              <1> ;	inc	ax
 12294                              <1> ;	mov	[esi], ebx ; Virtual address + [u.uno] combination
 12295                              <1> ;	mov	[swpq_count], ax
 12296                              <1> ;	pop	esi
 12297                              <1> ;	pop	ebx
 12298                              <1> ;	retn
 12299                              <1> 
 12300                              <1> ; 17/04/2021
 12301                              <1> ; ('unlink_swap_block' procedure call is disabled as temporary)
 12302                              <1> 
 12303                              <1> ; 30/11/2021 - temporary !
 12304                              <1> ;unlink_swap_block:
 12305                              <1> 	; 15/09/2015
 12306                              <1> 	; 30/04/2015
 12307                              <1> 	; 18/04/2015
 12308                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12309                              <1> 	;
 12310                              <1> 	; INPUT -> 
 12311                              <1> 	;	EAX = swap disk/file offset address
 12312                              <1> 	;	      (bit 1 to bit 31)
 12313                              <1> 	; OUTPUT ->
 12314                              <1> 	;	[swpd_free] is increased
 12315                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
 12316                              <1> 	;
 12317                              <1> 	; Modified Registers -> EAX
 12318                              <1> 	;
 12319                              <1> ;	push	ebx
 12320                              <1> ;	push	edx
 12321                              <1> ;	;
 12322                              <1> ;	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
 12323                              <1> ;				     ; 3 bits right
 12324                              <1> ;				     ; to get swap block/page number
 12325                              <1> ;	mov	edx, eax
 12326                              <1> ;	; 15/09/2015
 12327                              <1> ;	shr	edx, 3		     ; to get offset to S.A.T.
 12328                              <1> ;				     ; (1 allocation bit = 1 page)
 12329                              <1> ;				     ; (1 allocation bytes = 8 pages)
 12330                              <1> ;	and	dl, 0FCh 	     ; clear lower 2 bits
 12331                              <1> ;				     ; (to get 32 bit position)			
 12332                              <1> ;	;
 12333                              <1> ;	mov	ebx, swap_alloc_table ; Swap Allocation Table address
 12334                              <1> ;	add	ebx, edx
 12335                              <1> ;	and	eax, 1Fh	     ; lower 5 bits only
 12336                              <1> ;				     ; (allocation bit position)	 
 12337                              <1> ;	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
 12338                              <1> ;				     ; than the address in 'swpd_next' ?
 12339                              <1> ;				     ; (next/first free block value)		
 12340                              <1> ;	jnb	short uswpbl_1	     ; no	
 12341                              <1> ;	mov	[swpd_next], eax     ; yes	
 12342                              <1> ;uswpbl_1:
 12343                              <1> ;	bts	[ebx], eax	     ; unlink/release/deallocate block
 12344                              <1> ;				     ; set relevant bit to 1.
 12345                              <1> ;				     ; set CF to the previous bit value	
 12346                              <1> ;	cmc			     ; complement carry flag	
 12347                              <1> ;	jc	short uswpbl_2	     ; do not increase swfd_free count
 12348                              <1> ;				     ; if the block is already deallocated
 12349                              <1> ;				     ; before.	
 12350                              <1> ;       inc     dword [swpd_free]
 12351                              <1> ;uswpbl_2:
 12352                              <1> ;	pop	edx
 12353                              <1> ;	pop	ebx
 12354                              <1> ;	retn
 12355                              <1> 
 12356                              <1> ; 17/04/2021
 12357                              <1> ; ('link_swap_block' procedure call is disabled as temporary)
 12358                              <1> 
 12359                              <1> ; 30/11/2021 - temporary !
 12360                              <1> ;link_swap_block:
 12361                              <1> 	; 01/07/2015
 12362                              <1> 	; 18/04/2015
 12363                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12364                              <1> 	;
 12365                              <1> 	; INPUT -> none
 12366                              <1> 	;
 12367                              <1> 	; OUTPUT ->
 12368                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
 12369                              <1> 	;	      in sectors (corresponding 
 12370                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
 12371                              <1> 	;
 12372                              <1> 	;	CF = 1 and EAX = 0 
 12373                              <1> 	; 		   if there is not a free block to be allocated	
 12374                              <1> 	;
 12375                              <1> 	; Modified Registers -> none (except EAX)
 12376                              <1> 	;
 12377                              <1> 
 12378                              <1> ;	;mov	eax, [swpd_free]
 12379                              <1> ;	;and	eax, eax
 12380                              <1> ;	;jz	short out_of_swpspc
 12381                              <1> ;	;
 12382                              <1> ;	push	ebx
 12383                              <1> ;	push	ecx
 12384                              <1> ;	;
 12385                              <1> ;	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
 12386                              <1> ;	mov	ecx, ebx
 12387                              <1> ;	add	ebx, [swpd_next] ; Free block searching starts from here
 12388                              <1> ;				 ; next_free_swap_block >> 5
 12389                              <1> ;	add	ecx, [swpd_last] ; Free block searching ends here
 12390                              <1> ;				 ; (total_swap_blocks - 1) >> 5
 12391                              <1> ;lswbl_scan:
 12392                              <1> ;	cmp	ebx, ecx
 12393                              <1> ;	ja	short lswbl_notfound
 12394                              <1> ;	;
 12395                              <1> ;	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 12396                              <1> ;			   ; Clears ZF if a bit is found set (1) and 
 12397                              <1> ;			   ; loads the destination with an index to
 12398                              <1> ;			   ; first set bit. (0 -> 31) 
 12399                              <1> ;			   ; Sets ZF to 1 if no bits are found set.
 12400                              <1> ;	; 01/07/2015
 12401                              <1> ;	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
 12402                              <1> ;			 ;
 12403                              <1> ;			 ; NOTE:  a Swap Disk Allocation Table bit 
 12404                              <1> ;			 ;	  with value of 1 means 
 12405                              <1> ;			 ;	  the corresponding page is free 
 12406                              <1> ;			 ;	  (Retro UNIX 386 v1 feaure only!)
 12407                              <1> ;	add	ebx, 4
 12408                              <1> ;			 ; We return back for searching next page block
 12409                              <1> ;			 ; NOTE: [swpd_free] is not ZERO; so, 
 12410                              <1> ;			 ;	 we always will find at least 1 free block here.
 12411                              <1> ;	jmp    	short lswbl_scan
 12412                              <1> ;	;
 12413                              <1> ;lswbl_notfound:	
 12414                              <1> ;	sub	ecx, swap_alloc_table
 12415                              <1> ;	mov	[swpd_next], ecx ; next/first free page = last page 
 12416                              <1> ;				 ; (unlink_swap_block procedure will change it)
 12417                              <1> ;	xor	eax, eax
 12418                              <1> ;	mov	[swpd_free], eax
 12419                              <1> ;	stc
 12420                              <1> ;lswbl_ok:
 12421                              <1> ;	pop	ecx
 12422                              <1> ;	pop	ebx
 12423                              <1> ;	retn
 12424                              <1> ;	;
 12425                              <1> ;;out_of_swpspc:
 12426                              <1> ;;	stc
 12427                              <1> ;;	retn
 12428                              <1> ;
 12429                              <1> ;lswbl_found:
 12430                              <1> ;	mov	ecx, ebx
 12431                              <1> ;	sub	ecx, swap_alloc_table
 12432                              <1> ;	mov	[swpd_next], ecx ; Set first free block searching start
 12433                              <1> ;				 ; address/offset (to the next)
 12434                              <1> ;       dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
 12435                              <1> ;	;
 12436                              <1> ;	btr	[ebx], eax	 ; The destination bit indexed by the source value
 12437                              <1> ;				 ; is copied into the Carry Flag and then cleared
 12438                              <1> ;				 ; in the destination.
 12439                              <1> ;				 ;
 12440                              <1> ;				 ; Reset the bit which is corresponding to the 
 12441                              <1> ;				 ; (just) allocated block.
 12442                              <1> ;	shl	ecx, 5		 ; (block offset * 32) + block index
 12443                              <1> ;	add	eax, ecx	 ; = block number
 12444                              <1> ;	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
 12445                              <1> ;				 ; 1 block =  8 sectors
 12446                              <1> ;	;
 12447                              <1> ;	; EAX = offset address of swap disk/file sector (beginning of the block)
 12448                              <1> ;	;
 12449                              <1> ;	; NOTE: The relevant page table entry will be updated
 12450                              <1> ;	;       according to this EAX value...
 12451                              <1> ;	;
 12452                              <1> ;	jmp	short lswbl_ok
 12453                              <1> 
 12454                              <1> ; 17/04/2021
 12455                              <1> ; ('logical_disk_read' procedure call is disabled as temporary)
 12456                              <1> 
 12457                              <1> ; 30/11/2021 - temporary !
 12458                              <1> ;logical_disk_read:
 12459                              <1> 	; 20/07/2015
 12460                              <1> 	; 09/03/2015 (temporary code here)
 12461                              <1> 	;
 12462                              <1> 	; INPUT ->
 12463                              <1> 	; 	ESI = Logical disk description table address
 12464                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12465                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12466                              <1> 	; 	ECX = Sector count
 12467                              <1> 	;
 12468                              <1> 	;
 12469                              <1> ;	retn
 12470                              <1> 
 12471                              <1> ; 17/04/2021
 12472                              <1> ; ('logical_disk_write' procedure call is disabled as temporary)
 12473                              <1> 
 12474                              <1> ; 30/11/2021 - temporary !
 12475                              <1> ;logical_disk_write:
 12476                              <1> 	; 20/07/2015
 12477                              <1> 	; 09/03/2015 (temporary code here)
 12478                              <1> 	;
 12479                              <1> 	; INPUT ->
 12480                              <1> 	; 	ESI = Logical disk description table address
 12481                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12482                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12483                              <1> 	; 	ECX = Sector count
 12484                              <1> 	;
 12485                              <1> ;	retn
 12486                              <1> 
 12487                              <1> get_physical_addr:
 12488                              <1> 	; 17/04/2021 - Rerto UNIX 386 v2
 12489                              <1> 	;	(temporary modifications)
 12490                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 12491                              <1> 	; 18/10/2015
 12492                              <1> 	; 29/07/2015
 12493                              <1> 	; 20/07/2015
 12494                              <1> 	; 04/06/2015
 12495                              <1> 	; 20/05/2015
 12496                              <1> 	; 28/04/2015
 12497                              <1> 	; 18/04/2015
 12498                              <1> 	; Get physical address
 12499                              <1> 	;     (allocates a new page for user if it is not present)
 12500                              <1> 	;	
 12501                              <1> 	; (This subroutine is needed for mapping user's virtual 
 12502                              <1> 	; (buffer) address to physical address (of the buffer).)
 12503                              <1> 	; ('sys write', 'sys read' system calls...)
 12504                              <1> 	;
 12505                              <1> 	; INPUT ->
 12506                              <1> 	;	EBX = virtual address
 12507                              <1> 	;	u.pgdir = page directory (physical) address
 12508                              <1> 	;
 12509                              <1> 	; OUTPUT ->
 12510                              <1> 	;	EAX = physical address 
 12511                              <1> 	;	EBX = linear address	
 12512                              <1> 	;	EDX = physical address of the page frame
 12513                              <1> 	;	      (with attribute bits)
 12514                              <1> 	;	ECX = byte count within the page frame
 12515                              <1> 	;
 12516                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
 12517                              <1> 	;
 12518                              <1> 
 12519                              <1> 	; 19/04/2020 - Retro UNIX386 v2
 12520 00003316 A1[58700000]        <1> 	mov	eax, [u.pgdir]
 12521                              <1> 
 12522                              <1> ifs_get_physical_addr: ; 19/04/2020 - Retro UNIX 386 v2
 12523                              <1> 	
 12524 0000331B 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
 12525                              <1> 	;
 12526                              <1> 	;mov	eax, [u.pgdir]
 12527 00003321 E815FDFFFF          <1> 	call	get_pte
 12528                              <1> 		; EDX = Page table entry address (if CF=0)
 12529                              <1> 	        ;       Page directory entry address (if CF=1)
 12530                              <1> 		;       (Bit 0 value is 0 if PT is not present)
 12531                              <1> 		; EAX = Page table entry value (page address)
 12532                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
 12533 00003326 731C                <1> 	jnc	short gpa_1
 12534                              <1> 	;
 12535 00003328 E8FCFBFFFF          <1> 	call	allocate_page
 12536 0000332D 724B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
 12537                              <1> gpa_0:
 12538 0000332F E866FCFFFF          <1> 	call 	clear_page
 12539                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 12540 00003334 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
 12541                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
 12542                              <1> 			   ; (user, writable, present page)	
 12543 00003336 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
 12544 00003338 A1[58700000]        <1> 	mov	eax, [u.pgdir]	
 12545 0000333D E8F9FCFFFF          <1> 	call	get_pte
 12546 00003342 7236                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12547                              <1> gpa_1:
 12548                              <1> 	; EAX = PTE value, EDX = PTE address
 12549 00003344 A801                <1> 	test 	al, PTE_A_PRESENT
 12550 00003346 750A                <1> 	jnz	short gpa_3
 12551 00003348 09C0                <1> 	or	eax, eax
 12552 0000334A 7420                <1> 	jz	short gpa_4  ; Allocate a new page
 12553                              <1> 
 12554                              <1> ; 17/04/2021
 12555                              <1> ; ('reload_page' procedure call is disabled as temporary)
 12556 0000334C EB2C                <1> 	jmp	short gpa_im_err  ; temporary !
 12557                              <1> 
 12558                              <1> 	; 20/07/2015
 12559                              <1> ;	push	ebp
 12560                              <1> ;	mov	ebp, ebx ; virtual (linear) address
 12561                              <1> ;	; reload swapped page
 12562                              <1> ;	call	reload_page ; 28/04/2015
 12563                              <1> ;	pop	ebp
 12564                              <1> ;	jc	short gpa_retn
 12565                              <1> gpa_2:
 12566                              <1> ; 17/04/2021
 12567                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)
 12568                              <1> 
 12569                              <1> 	; 20/07/2015
 12570                              <1> 	; 20/05/2015
 12571                              <1> 	; add this page to swap queue
 12572                              <1> ;	push	eax 
 12573                              <1> ;	; EBX = Linear (CORE+virtual) address ; 20/02/2017 
 12574                              <1> ;	call 	add_to_swap_queue
 12575                              <1> ;	pop	eax
 12576                              <1> 		; PTE address in EDX
 12577                              <1> 		; virtual address in EBX
 12578                              <1> 	; EAX = memory page address
 12579 0000334E 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
 12580                              <1> 				  ; present flag, bit 0 = 1
 12581                              <1> 				  ; user flag, bit 2 = 1	
 12582                              <1> 				  ; writable flag, bit 1 = 1
 12583 00003350 8902                <1> 	mov	[edx], eax  ; Update PTE value
 12584                              <1> gpa_3:
 12585                              <1> 	; 18/10/2015
 12586 00003352 89D9                <1> 	mov	ecx, ebx
 12587 00003354 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
 12588 0000335A 89C2                <1> 	mov 	edx, eax
 12589 0000335C 662500F0            <1> 	and	ax, PTE_A_CLEAR
 12590 00003360 01C8                <1> 	add	eax, ecx
 12591 00003362 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
 12592 00003364 81C100100000        <1> 	add	ecx, PAGE_SIZE
 12593 0000336A F8                  <1> 	clc
 12594                              <1> gpa_retn:
 12595 0000336B C3                  <1> 	retn	
 12596                              <1> gpa_4:	
 12597 0000336C E8B8FBFFFF          <1> 	call	allocate_page
 12598 00003371 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12599 00003373 E822FCFFFF          <1> 	call	clear_page
 12600 00003378 EBD4                <1> 	jmp	short gpa_2
 12601                              <1> 
 12602                              <1> gpa_im_err:	
 12603 0000337A B804000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12604                              <1> 				  ; Major error = 0 (No protection fault)	
 12605 0000337F C3                  <1> 	retn
 12606                              <1> 
 12607                              <1> ; 17/04/2021
 12608                              <1> ; ('reload_page' procedure call is disabled as temporary)
 12609                              <1> 
 12610                              <1> ; 30/11/2021 - temporary !
 12611                              <1> ;reload_page:
 12612                              <1> 	; 20/07/2015
 12613                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
 12614                              <1> 	;
 12615                              <1> 	; Reload (Restore) swapped page at memory
 12616                              <1> 	;
 12617                              <1> 	; INPUT -> 
 12618                              <1> 	;	EBP = Virtual (linear) memory address
 12619                              <1> 	;	EAX = PTE value (swap disk sector address)
 12620                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
 12621                              <1> 	; OUTPUT ->
 12622                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
 12623                              <1> 	;
 12624                              <1> 	;	CF = 1 and EAX = error code
 12625                              <1> 	;
 12626                              <1> 	; Modified Registers -> none (except EAX)
 12627                              <1> 	;
 12628                              <1> ;	shr	eax, 1   ; Convert PTE value to swap disk address 
 12629                              <1> ;	push	ebx      ;
 12630                              <1> ;	mov	ebx, eax ; Swap disk (offset) address	
 12631                              <1> ;	call	allocate_page
 12632                              <1> ;	jc	short rlp_im_err
 12633                              <1> ;	xchg 	eax, ebx	
 12634                              <1> ;	; EBX = Physical memory (page) address
 12635                              <1> ;	; EAX = Swap disk (offset) address
 12636                              <1> ;	; EBP = Virtual (linear) memory address
 12637                              <1> ;	call	swap_in
 12638                              <1> ;	jc	short rlp_swp_err  ; (swap disk/file read error)
 12639                              <1> ;	mov	eax, ebx	
 12640                              <1> ;rlp_retn:
 12641                              <1> ;	pop	ebx
 12642                              <1> ;	retn
 12643                              <1> ;	
 12644                              <1> ;rlp_im_err:	
 12645                              <1> ;	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12646                              <1> ;				  ; Major error = 0 (No protection fault)	
 12647                              <1> ;	jmp	short rlp_retn
 12648                              <1> ;
 12649                              <1> ;rlp_swp_err:
 12650                              <1> ;	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
 12651                              <1> ;	jmp	short rlp_retn
 12652                              <1> 
 12653                              <1> copy_page_dir:
 12654                              <1> 	; 17/04/2021 (temporary modifications)
 12655                              <1> 	; 19/09/2015
 12656                              <1> 	; temporary - 07/09/2015
 12657                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12658                              <1> 	;
 12659                              <1> 	; INPUT -> 
 12660                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 12661                              <1> 	;		    page directory.
 12662                              <1> 	; OUTPUT ->
 12663                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 12664                              <1> 	;	       page directory.
 12665                              <1> 	;	(New page directory with new page table entries.)
 12666                              <1> 	;	(New page tables with read only copies of the parent's
 12667                              <1> 	;	pages.)
 12668                              <1> 	;	EAX = 0 -> Error (CF = 1)
 12669                              <1> 	;
 12670                              <1> 	; Modified Registers -> none (except EAX)
 12671                              <1> 	;
 12672 00003380 E8A4FBFFFF          <1> 	call	allocate_page
 12673 00003385 723E                <1> 	jc	short cpd_err
 12674                              <1> 	;
 12675 00003387 55                  <1> 	push	ebp ; 20/07/2015
 12676 00003388 56                  <1> 	push	esi
 12677 00003389 57                  <1> 	push	edi
 12678 0000338A 53                  <1> 	push	ebx
 12679 0000338B 51                  <1> 	push	ecx
 12680 0000338C 8B35[58700000]      <1> 	mov	esi, [u.pgdir]
 12681 00003392 89C7                <1> 	mov	edi, eax
 12682 00003394 50                  <1> 	push	eax ; save child's page directory address
 12683                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 12684                              <1> 	; (use same system space for all user page tables) 
 12685 00003395 A5                  <1> 	movsd
 12686 00003396 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 12687 0000339B B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 12688                              <1> cpd_0:	
 12689 000033A0 AD                  <1> 	lodsd
 12690                              <1> 	;or	eax, eax
 12691                              <1>         ;jnz     short cpd_1
 12692 000033A1 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 12693 000033A3 7508                <1> 	jnz	short cpd_1
 12694                              <1>  	; (virtual address at the end of the page table)	
 12695 000033A5 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 12696 000033AB EB0F                <1> 	jmp	short cpd_2
 12697                              <1> cpd_1:	
 12698 000033AD 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 12699 000033B1 89C3                <1> 	mov	ebx, eax
 12700                              <1> 	; EBX = Parent's page table address
 12701 000033B3 E81F000000          <1> 	call	copy_page_table
 12702 000033B8 720C                <1> 	jc	short cpd_p_err
 12703                              <1> 	; EAX = Child's page table address
 12704 000033BA 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 12705                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 12706                              <1> 			 ; (present, writable, user)
 12707                              <1> cpd_2:
 12708 000033BC AB                  <1> 	stosd
 12709 000033BD E2E1                <1> 	loop	cpd_0
 12710                              <1> 	;
 12711 000033BF 58                  <1> 	pop	eax  ; restore child's page directory address
 12712                              <1> cpd_3:
 12713 000033C0 59                  <1> 	pop	ecx
 12714 000033C1 5B                  <1> 	pop	ebx
 12715 000033C2 5F                  <1> 	pop	edi
 12716 000033C3 5E                  <1> 	pop	esi
 12717 000033C4 5D                  <1> 	pop	ebp
 12718                              <1> cpd_err:
 12719 000033C5 C3                  <1> 	retn
 12720                              <1> cpd_p_err:
 12721                              <1> 	; release the allocated pages missing (recover free space)
 12722 000033C6 58                  <1> 	pop	eax  ; the new page directory address (physical)
 12723 000033C7 8B1D[58700000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 12724 000033CD E887FCFFFF          <1> 	call 	deallocate_page_dir
 12725 000033D2 29C0                <1> 	sub	eax, eax ; 0
 12726 000033D4 F9                  <1> 	stc
 12727 000033D5 EBE9                <1> 	jmp	short cpd_3	
 12728                              <1> 
 12729                              <1> copy_page_table:
 12730                              <1> 	; 17/04/2021 (temporary modifications)
 12731                              <1> 	; 19/09/2015
 12732                              <1> 	; temporary - 07/09/2015
 12733                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12734                              <1> 	;
 12735                              <1> 	; INPUT -> 
 12736                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 12737                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
 12738                              <1> 	; OUTPUT ->
 12739                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 12740                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 12741                              <1> 	;	CF = 1 -> error 
 12742                              <1> 	;
 12743                              <1> 	; Modified Registers -> EBP (except EAX)
 12744                              <1> 	;
 12745 000033D7 E84DFBFFFF          <1> 	call	allocate_page
 12746 000033DC 7244                <1> 	jc	short cpt_err
 12747                              <1> 	;
 12748 000033DE 50                  <1> 	push	eax ; *
 12749                              <1> 	;push 	ebx
 12750 000033DF 56                  <1> 	push	esi
 12751 000033E0 57                  <1> 	push	edi
 12752 000033E1 52                  <1> 	push	edx
 12753 000033E2 51                  <1> 	push	ecx
 12754                              <1> 	;
 12755 000033E3 89DE                <1> 	mov	esi, ebx
 12756 000033E5 89C7                <1> 	mov	edi, eax
 12757 000033E7 89C2                <1> 	mov	edx, eax
 12758 000033E9 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 12759                              <1> cpt_0:
 12760 000033EF AD                  <1> 	lodsd
 12761 000033F0 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 = 1
 12762                              <1> 	;jnz	short cpt_1 (*)
 12763                              <1> 	; 17/04/2021 (temporary (*)
 12764                              <1> 	;and	eax, eax (*)
 12765 000033F2 741E                <1> 	jz	short cpt_2  ; 17/04/2021
 12766                              <1> 	
 12767                              <1> ; 17/04/2021
 12768                              <1> ; ('reload_page' procedure call is disabled as temporary)
 12769                              <1> ;
 12770                              <1> ;	; ebp = virtual (linear) address of the memory page
 12771                              <1> ;	call	reload_page ; 28/04/2015
 12772                              <1> ;	jc	short cpt_p_err
 12773                              <1> cpt_1:
 12774 000033F4 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 12775 000033F8 89C1                <1> 	mov	ecx, eax
 12776                              <1> 	; Allocate a new page for the child process
 12777 000033FA E82AFBFFFF          <1> 	call	allocate_page
 12778 000033FF 721C                <1> 	jc	short cpt_p_err
 12779 00003401 57                  <1> 	push	edi
 12780 00003402 56                  <1> 	push	esi
 12781 00003403 89CE                <1> 	mov	esi, ecx
 12782 00003405 89C7                <1> 	mov	edi, eax
 12783 00003407 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 12784 0000340C F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 12785 0000340E 5E                  <1> 	pop	esi
 12786 0000340F 5F                  <1> 	pop	edi
 12787                              <1> 	; 
 12788                              <1> 
 12789                              <1> ; 17/04/2021
 12790                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)	
 12791                              <1> ;
 12792                              <1> ;	push	ebx
 12793                              <1> ;	push	eax
 12794                              <1> ;	mov	ebx, ebp
 12795                              <1> ;	; ebx = virtual address of the memory page
 12796                              <1> ;	call	add_to_swap_queue
 12797                              <1> ;	pop	eax
 12798                              <1> ;	pop	ebx
 12799                              <1> 	;
 12800                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 12801 00003410 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 12802                              <1> cpt_2:
 12803 00003412 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 12804                              <1> 	;
 12805 00003413 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 12806                              <1> 	;
 12807 00003419 39D7                <1> 	cmp	edi, edx
 12808 0000341B 72D2                <1> 	jb	short cpt_0
 12809                              <1> cpt_p_err:
 12810 0000341D 59                  <1> 	pop	ecx
 12811 0000341E 5A                  <1> 	pop	edx
 12812 0000341F 5F                  <1> 	pop	edi
 12813 00003420 5E                  <1> 	pop	esi
 12814                              <1> 	;pop	ebx
 12815 00003421 58                  <1> 	pop	eax ; *
 12816                              <1> cpt_err:
 12817 00003422 C3                  <1> 	retn
 12818                              <1> 
 12819                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
 12820                              <1> 
 12821                              <1> ;; Data:
 12822                              <1> 
 12823                              <1> ; 09/03/2015
 12824                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
 12825                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
 12826                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 12827                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 12828                              <1> ;swpd_next:  dd 0 ; next free page block
 12829                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
 12830                                  %include 'sysdefs.s' ; 09/03/2015
 12831                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 12832                              <1> ; (re-write kernel for test by using previous version without a major defect)
 12833                              <1> ; ****************************************************************************
 12834                              <1> ; Retro UNIX 386 v1 Kernel - SYSDEFS.INC
 12835                              <1> ; Last Modification: 28/11/2021
 12836                              <1> ;
 12837                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 12838                              <1> ; (Modified from 
 12839                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 12840                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 12841                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
 12842                              <1> ; ----------------------------------------------------------------------------
 12843                              <1> ;
 12844                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 12845                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 12846                              <1> ; <Bell Laboratories (17/3/1972)>
 12847                              <1> ; <Preliminary Release of UNIX Implementation Document>
 12848                              <1> ;
 12849                              <1> ; ****************************************************************************
 12850                              <1> 
 12851                              <1> nproc 	equ	16  ; number of processes
 12852                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
 12853                              <1> nbuf	equ	6   ; number of buffers (04/02/2016)
 12854                              <1> 
 12855                              <1> ; 22/11/2021
 12856                              <1> NFILES 	equ	50
 12857                              <1> OPENFILES equ	10  ; open files (for user) ; 28/03/2020
 12858                              <1> 
 12859                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
 12860                              <1> ;core	equ 	0  	    ; 19/04/2013	
 12861                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
 12862                              <1> 	; (if total size of argument list and arguments is 128 bytes)
 12863                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
 12864                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
 12865                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
 12866                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
 12867                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
 12868                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
 12869                              <1> 	; '/core' dump file size = 32768 bytes
 12870                              <1>  
 12871                              <1> ; 08/03/2014 
 12872                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)		 	 
 12873                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
 12874                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
 12875                              <1> 
 12876                              <1> ; 30/08/2013
 12877                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
 12878                              <1> 
 12879                              <1> ; 05/02/2014
 12880                              <1> ; process status
 12881                              <1> ;SFREE 	equ 0
 12882                              <1> ;SRUN	equ 1
 12883                              <1> ;SWAIT	equ 2
 12884                              <1> ;SZOMB	equ 3
 12885                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
 12886                              <1> 
 12887                              <1> ; 09/03/2015
 12888                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
 12889                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
 12890                              <1> swap_alloc_table equ 0D0000h  ;  swap allocation table address ; temporary
 12891                              <1> 
 12892                              <1> ; 17/09/2015
 12893                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
 12894                              <1> 
 12895                              <1> ; 21/09/2015 (36) 
 12896                              <1> ; 01/07/2015 (35)
 12897                              <1> ; 14/07/2013 (0-34)
 12898                              <1> ; UNIX v1 system calls
 12899                              <1> _rele 	equ 0
 12900                              <1> _exit 	equ 1
 12901                              <1> _fork 	equ 2
 12902                              <1> _read 	equ 3
 12903                              <1> _write	equ 4
 12904                              <1> _open	equ 5
 12905                              <1> _close 	equ 6
 12906                              <1> _wait 	equ 7
 12907                              <1> _creat 	equ 8
 12908                              <1> _link 	equ 9
 12909                              <1> _unlink	equ 10
 12910                              <1> _exec	equ 11
 12911                              <1> _chdir	equ 12
 12912                              <1> _time 	equ 13
 12913                              <1> _mkdir 	equ 14
 12914                              <1> _chmod	equ 15
 12915                              <1> _chown	equ 16
 12916                              <1> _break	equ 17
 12917                              <1> _stat	equ 18
 12918                              <1> _seek	equ 19
 12919                              <1> _tell 	equ 20
 12920                              <1> _mount	equ 21
 12921                              <1> _umount	equ 22
 12922                              <1> _setuid	equ 23
 12923                              <1> _getuid	equ 24
 12924                              <1> _stime	equ 25
 12925                              <1> _quit	equ 26	
 12926                              <1> _intr	equ 27
 12927                              <1> _fstat	equ 28
 12928                              <1> _emt 	equ 29
 12929                              <1> _mdate 	equ 30
 12930                              <1> _stty 	equ 31
 12931                              <1> _gtty	equ 32
 12932                              <1> _ilgins	equ 33
 12933                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
 12934                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
 12935                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
 12936                              <1> 
 12937                              <1> %macro sys 1-4
 12938                              <1>     ; 13/04/2015
 12939                              <1>     ; Retro UNIX 386 v1 system call.		
 12940                              <1>     mov eax, %1
 12941                              <1>     %if %0 >= 2   
 12942                              <1>         mov ebx, %2
 12943                              <1>         %if %0 >= 3    
 12944                              <1>             mov ecx, %3
 12945                              <1>             %if %0 = 4
 12946                              <1>                mov edx, %4   
 12947                              <1>             %endif
 12948                              <1>         %endif
 12949                              <1>     %endif
 12950                              <1>     int 30h	   
 12951                              <1> %endmacro
 12952                              <1> 
 12953                              <1> ; 13/05/2015 - ERROR CODES
 12954                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
 12955                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
 12956                              <1> ; 14/05/2015
 12957                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
 12958                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
 12959                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
 12960                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
 12961                              <1> ; 16/05/2015		
 12962                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
 12963                              <1> ; 18/05/2015
 12964                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
 12965                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
 12966                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
 12967                              <1> ; 07/06/2015
 12968                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
 12969                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
 12970                              <1> ; 09/06/2015
 12971                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
 12972                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
 12973                              <1> ; 16/06/2015
 12974                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
 12975                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
 12976                              <1> ; 22/06/2015
 12977                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
 12978                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
 12979                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
 12980                              <1> ; 23/06/2015
 12981                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
 12982                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
 12983                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
 12984                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
 12985                              <1> ; 27/06/2015
 12986                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
 12987                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
 12988                              <1> ; 29/06/2015
 12989                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
 12990                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error	
 12991                              <1> 
 12992                              <1> ; 26/08/2015
 12993                              <1> ; 24/07/2015
 12994                              <1> ; 24/06/2015
 12995                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
 12996                              <1> ; 01/07/2015
 12997                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
 12998                              <1> ;
 12999                              <1> ; 22/11/2021
 13000                              <1> ERR_READ_ONLY_FS   equ 30  ; 'read only file system !' error
 13001                              <1> ; 28/11/2021
 13002                              <1> ERR_INV_FILE	   equ 255 ; 'invalid file (inode) !' error 	
 13003                              <1> 
 13004                              <1> ; 26/11/2021 ('no free blocks on disk !' error)
 13005                              <1> ERR_ALLOC	   equ 33  ; 'disk allocation error !'	 					 		
 13006                                  %include 'u0.s'        ; 15/03/2015
 13007                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 13008                              <1> ; (re-write kernel for test by using previous version without a major defect)
 13009                              <1> ; ****************************************************************************
 13010                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
 13011                              <1> ; Last Modification: 28/11/2021
 13012                              <1> ; ----------------------------------------------------------------------------
 13013                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 13014                              <1> ; (v0.1 - Beginning: 11/07/2012)
 13015                              <1> ;
 13016                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 13017                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 13018                              <1> ; <Bell Laboratories (17/3/1972)>
 13019                              <1> ; <Preliminary Release of UNIX Implementation Document>
 13020                              <1> ;
 13021                              <1> ; Retro UNIX 8086 v1 - U0.ASM (28/07/2014) //// UNIX v1 -> u0.s
 13022                              <1> ;
 13023                              <1> ; ****************************************************************************
 13024                              <1> 
 13025                              <1> sys_init:
 13026                              <1> 	; 27/11/2021
 13027                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 (test) compatibility modification
 13028                              <1> 	; 18/10/2015
 13029                              <1> 	; 28/08/2015
 13030                              <1> 	; 24/08/2015
 13031                              <1> 	; 14/08/2015
 13032                              <1> 	; 24/07/2015 
 13033                              <1> 	; 02/07/2015
 13034                              <1> 	; 01/07/2015
 13035                              <1> 	; 23/06/2015
 13036                              <1> 	; 15/04/2015
 13037                              <1> 	; 13/04/2015
 13038                              <1> 	; 11/03/2015 (Retro UNIX 386 v1 - Beginning)
 13039                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13040                              <1> 	;
 13041                              <1> 	;call	ldrv_init ; Logical drive description tables initialization
 13042                              <1> 	;
 13043                              <1> 	;; 14/02/2014
 13044                              <1> 	;; 14/07/2013
 13045                              <1> 	;mov	ax, 41
 13046                              <1> 	;mov	[rootdir], ax
 13047                              <1> 	;mov	[u.cdir], ax
 13048                              <1> 	;and	al, 1 ; 15/04/2015
 13049                              <1> 	
 13050                              <1> 	; 27/11/2021
 13051                              <1> 	; 18/04/2021 - Retro UNIX 386 v2
 13052 00003423 31C0                <1> 	xor	eax, eax
 13053 00003425 FEC0                <1> 	inc	al	; eax = 1 (root directory inode) ; runix v2 fs
 13054 00003427 A3[DC6F0000]        <1> 	mov	[rootdir], eax ; = 1 ; 28/10/2021 (32 bit)
 13055 0000342C A3[F86F0000]        <1> 	mov	[u.cdir], eax ; 28/10/2021 (32 bit)
 13056                              <1> 
 13057 00003431 A2[49700000]        <1> 	mov	[u.uno], al ; = 1
 13058 00003436 66A3[DA6F0000]      <1> 	mov	[mpid], ax ; 1 
 13059 0000343C 66A3[D06C0000]      <1> 	mov	[p.pid], ax ; 1
 13060 00003442 A2[606D0000]        <1> 	mov	[p.stat], al ; SRUN, 05/02/2014
 13061                              <1> 	;
 13062 00003447 B004                <1> 	mov	al, time_count ; 30/08/2013
 13063 00003449 A2[40700000]        <1> 	mov	[u.quant], al ; 14/07/2013
 13064                              <1> 	; 02/07/2015
 13065 0000344E A1[F86E0000]        <1> 	mov	eax, [k_page_dir]
 13066                              <1> 	;sub	eax, eax
 13067 00003453 A3[58700000]        <1> 	mov	[u.pgdir], eax ; reset
 13068                              <1> 	; 18/10/2015
 13069                              <1> 	;mov	[u.ppgdir], eax ; 0
 13070                              <1>         ;
 13071 00003458 E851030000          <1>  	call	epoch
 13072 0000345D A3[7C810000]        <1> 	mov	[s.time], eax ; 13/03/2015
 13073                              <1> 	; 17/07/2013
 13074 00003462 E8AB060000          <1> 	call 	bf_init ; buffer initialization 
 13075                              <1> 	; 23/06/2015
 13076 00003467 E8BDFAFFFF          <1> 	call	allocate_page
 13077                              <1> 	;;jc	error
 13078 0000346C 0F8297000000        <1>         jc      panic   ; jc short panic (01/07/2015)
 13079 00003472 A3[54700000]        <1> 	mov	[u.upage], eax ; user structure page	
 13080 00003477 A3[706D0000]        <1> 	mov	[p.upage], eax
 13081                              <1> 	;
 13082 0000347C E819FBFFFF          <1> 	call	clear_page
 13083                              <1> 	;
 13084                              <1> 	; 14/08/2015
 13085 00003481 FA                  <1> 	cli
 13086                              <1> 	; 14/03/2015
 13087                              <1> 	; 17/01/2014
 13088 00003482 E8D9010000          <1> 	call	sp_init ; serial port initialization
 13089                              <1> 	; 14/08/2015
 13090 00003487 FB                  <1> 	sti
 13091                              <1> 	;
 13092                              <1> 	; 30/06/2015
 13093                              <1> 	;mov	esi, kernel_init_ok_msg
 13094                              <1> 	;call 	print_msg
 13095                              <1> 	;
 13096 00003488 30DB                <1> 	xor	bl, bl ; video page 0
 13097                              <1> vp_clr_nxt:  ; clear video pages (reset cursor positions)
 13098 0000348A E895300000          <1> 	call 	vp_clr  ; 17/07/2013
 13099 0000348F FEC3                <1> 	inc	bl
 13100 00003491 80FB08              <1> 	cmp	bl, 8
 13101 00003494 72F4                <1> 	jb	short vp_clr_nxt
 13102                              <1> 	;
 13103                              <1> 	; 24/07/2015
 13104                              <1> 	;push    KDATA
 13105                              <1>         ;push    esp
 13106                              <1> 	;mov	[tss.esp0], esp
 13107                              <1>         ;mov     word [tss.ss0], KDATA
 13108                              <1> 	;
 13109                              <1> 	; 24/08/2015
 13110                              <1> 	;; temporary (01/07/2015)
 13111 00003496 C605[40700000]04    <1> 	mov	byte [u.quant], time_count ; 4 
 13112                              <1> 			       ; it is not needed here !
 13113                              <1> 	;;inc	byte [u.kcall] ; 'the caller is kernel' sign
 13114 0000349D FE0D[E96F0000]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
 13115                              <1> 			      ; 0 = executing a system call
 13116                              <1> 	;;sys 	_msg, kernel_init_ok_msg, 255, 0
 13117                              <1> 	;
 13118                              <1> 	;;; 06/08/2015
 13119                              <1> 	;;;call	getch ; wait for a key stroke
 13120                              <1> 	;;mov 	ecx, 0FFFFFFFh	
 13121                              <1> ;;sys_init_msg_wait:
 13122                              <1> ;;	push 	ecx
 13123                              <1> ;;	mov	al, 1
 13124                              <1> ;;	mov 	ah, [ptty] ; active (current) video page
 13125                              <1> ;;	call	getc_n
 13126                              <1> ;;	pop	ecx
 13127                              <1> ;;	jnz	short sys_init_msg_ok
 13128                              <1> ;;	loop	sys_init_msg_wait
 13129                              <1> 	;
 13130                              <1> ;;sys_init_msg_ok:
 13131                              <1> 	; 28/08/2015 (initial settings for the 1st 'rswap')
 13132 000034A3 6A10                <1> 	push	KDATA ; ss
 13133 000034A5 54                  <1> 	push	esp
 13134 000034A6 9C                  <1> 	pushfd
 13135 000034A7 6A08                <1> 	push	KCODE ; cs
 13136 000034A9 68[DD340000]        <1> 	push	init_exec ; eip
 13137 000034AE 8925[EC6F0000]      <1> 	mov	[u.sp], esp
 13138 000034B4 1E                  <1> 	push	ds
 13139 000034B5 06                  <1> 	push	es
 13140 000034B6 0FA0                <1> 	push	fs
 13141 000034B8 0FA8                <1> 	push	gs	
 13142 000034BA 60                  <1> 	pushad
 13143 000034BB 8925[F06F0000]      <1> 	mov	[u.usp], esp
 13144 000034C1 E84F1B0000          <1> 	call	wswap ; save current user (u) structure, user registers
 13145                              <1> 		      ; and interrupt return components (for IRET)
 13146 000034C6 61                  <1> 	popad
 13147 000034C7 6658                <1> 	pop	ax ; gs
 13148 000034C9 6658                <1> 	pop	ax ; fs
 13149 000034CB 6658                <1> 	pop	ax ; es
 13150 000034CD 6658                <1> 	pop	ax ; ds	
 13151 000034CF 58                  <1> 	pop	eax ; eip (init_exec)
 13152 000034D0 6658                <1> 	pop	ax ; cs (KCODE)
 13153 000034D2 58                  <1> 	pop	eax ; E-FLAGS
 13154 000034D3 58                  <1> 	pop	eax ; esp
 13155 000034D4 6658                <1> 	pop	ax ; ss (KDATA)
 13156                              <1> 	;
 13157 000034D6 31C0                <1> 	xor	eax, eax ; 0
 13158 000034D8 A3[5C700000]        <1> 	mov	[u.ppgdir], eax ; reset (to zero) for '/etc/init'
 13159                              <1> 	;
 13160                              <1> 	; 02/07/2015
 13161                              <1> 	; [u.pgdir ] = [k_page_dir]
 13162                              <1> 	; [u.ppgdir] = 0 (page dir of the parent process)
 13163                              <1> 	;     (The caller is os kernel sign for 'sysexec')
 13164                              <1> init_exec:
 13165                              <1> 	; 13/03/2013
 13166                              <1> 	; 24/07/2013
 13167 000034DD BB[FF340000]        <1> 	mov	ebx, init_file
 13168 000034E2 B9[F7340000]        <1> 	mov	ecx, init_argp
 13169                              <1> 	; EBX contains 'etc/init' asciiz file name address  
 13170                              <1> 	; ECX contains address of argument list pointer
 13171                              <1> 	;
 13172                              <1> 	;dec 	byte [sysflg] ; FFh = ready for system call
 13173                              <1> 			      ; 0 = executing a system call
 13174                              <1> 	sys	_exec  ; execute file
 13175                              <2> 
 13176                              <2> 
 13177 000034E7 B80B000000          <2>  mov eax, %1
 13178                              <2>  %if %0 >= 2
 13179                              <2>  mov ebx, %2
 13180                              <2>  %if %0 >= 3
 13181                              <2>  mov ecx, %3
 13182                              <2>  %if %0 = 4
 13183                              <2>  mov edx, %4
 13184                              <2>  %endif
 13185                              <2>  %endif
 13186                              <2>  %endif
 13187 000034EC CD30                <2>  int 30h
 13188 000034EE 7319                <1> 	jnc	short panic
 13189                              <1> 	;
 13190 000034F0 BE[0C6C0000]        <1> 	mov	esi, etc_init_err_msg
 13191                              <1> 	; 22/11/2021
 13192                              <1> 	;call 	print_msg
 13193 000034F5 EB17                <1> 	jmp	short key_to_reboot
 13194                              <1> 
 13195                              <1> ;align 4
 13196                              <1> init_argp:
 13197 000034F7 [FF340000]00000000  <1> 	dd 	init_file, 0  ; 23/06/2015 (dw -> dd)
 13198                              <1> init_file:
 13199                              <1> 	; 24/08/2015
 13200 000034FF 2F6574632F696E6974- <1> 	db 	'/etc/init', 0
 13201 00003508 00                  <1>
 13202                              <1> panic:
 13203                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13204                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 13205 00003509 BE[F16B0000]        <1> 	mov 	esi, panic_msg
 13206                              <1> key_to_reboot: ; 22/11/2021
 13207 0000350E E819000000          <1> 	call 	print_msg
 13208                              <1> ;key_to_reboot:
 13209                              <1> 	; 15/11/2015
 13210 00003513 E84B2E0000          <1> 	call 	getch 
 13211                              <1> 		; wait for a character from the current tty
 13212                              <1> 	;
 13213 00003518 B00A                <1> 	mov	al, 0Ah
 13214 0000351A 8A1D[266F0000]      <1> 	mov	bl, [ptty] ; [active_page]
 13215 00003520 B407                <1> 	mov	ah, 07h ; Black background, 
 13216                              <1> 			; light gray forecolor
 13217 00003522 E8E6DEFFFF          <1> 	call 	write_tty
 13218 00003527 E966DBFFFF          <1> 	jmp	cpu_reset 
 13219                              <1> 
 13220                              <1> print_msg:
 13221                              <1> 	; 01/07/2015
 13222                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13223                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 13224                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
 13225                              <1> 	;
 13226                              <1> 	;
 13227 0000352C AC                  <1> 	lodsb
 13228                              <1> pmsg1:
 13229 0000352D 56                  <1> 	push 	esi
 13230 0000352E 0FB61D[266F0000]    <1> 	movzx	ebx, byte [ptty]
 13231 00003535 B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
 13232 00003537 E8D1DEFFFF          <1> 	call 	write_tty
 13233 0000353C 5E                  <1> 	pop	esi
 13234 0000353D AC                  <1> 	lodsb
 13235 0000353E 20C0                <1> 	and 	al, al
 13236 00003540 75EB                <1> 	jnz 	short pmsg1
 13237 00003542 C3                  <1> 	retn
 13238                              <1> 	
 13239                              <1> ctrlbrk:
 13240                              <1> 	; 12/11/2015
 13241                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13242                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
 13243                              <1> 	;
 13244                              <1> 	; INT 1Bh (control+break) handler		
 13245                              <1> 	;
 13246                              <1>       	; Retro Unix 8086 v1 feature only!
 13247                              <1>       	;
 13248 00003543 66833D[44700000]00  <1> 	cmp 	word [u.intr], 0
 13249 0000354B 7645                <1> 	jna 	short cbrk4
 13250                              <1> cbrk0:
 13251                              <1> 	; 12/11/2015
 13252                              <1> 	; 06/12/2013
 13253 0000354D 66833D[46700000]00  <1> 	cmp 	word [u.quit], 0
 13254 00003555 743B                <1> 	jz	short cbrk4
 13255                              <1> 	;
 13256                              <1> 	; 20/09/2013	
 13257 00003557 6650                <1> 	push 	ax
 13258 00003559 A0[266F0000]        <1> 	mov	al, [ptty]
 13259                              <1> 	;
 13260                              <1> 	; 12/11/2015
 13261                              <1> 	;
 13262                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
 13263                              <1> 	; or ctrl+break from console (pseudo) tty
 13264                              <1> 	; (!redirection!)
 13265                              <1> 	;
 13266 0000355E 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
 13267 00003560 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
 13268                              <1> 	;	
 13269                              <1> 	; Serial port interrupt handler sets [ptty]
 13270                              <1> 	; to the port's tty number (as temporary).
 13271                              <1> 	;
 13272                              <1> 	; If active process is using a stdin or 
 13273                              <1> 	; stdout redirection (by the shell),
 13274                              <1>         ; console tty keyboard must be available
 13275                              <1> 	; to terminate running process,
 13276                              <1> 	; in order to prevent a deadlock. 
 13277                              <1> 	;
 13278 00003562 52                  <1> 	push	edx
 13279 00003563 0FB615[49700000]    <1> 	movzx	edx, byte [u.uno]
 13280 0000356A 3A82[2F6D0000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
 13281 00003570 5A                  <1> 	pop	edx
 13282 00003571 7412                <1> 	je	short cbrk2
 13283                              <1> cbrk1:
 13284 00003573 FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
 13285                              <1> 	; 06/12/2013
 13286 00003575 3A05[2E700000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
 13287 0000357B 7408                <1> 	je	short cbrk2	
 13288 0000357D 3A05[2F700000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
 13289 00003583 750B                <1> 	jne	short cbrk3	
 13290                              <1> cbrk2:
 13291                              <1> 	;; 06/12/2013
 13292                              <1> 	;mov	ax, [u.quit]
 13293                              <1> 	;and	ax, ax
 13294                              <1> 	;jz	short cbrk3
 13295                              <1> 	;
 13296 00003585 6631C0              <1> 	xor	ax, ax ; 0
 13297 00003588 6648                <1> 	dec	ax
 13298                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
 13299 0000358A 66A3[46700000]      <1> 	mov	[u.quit], ax
 13300                              <1> cbrk3:
 13301 00003590 6658                <1> 	pop	ax
 13302                              <1> cbrk4:
 13303 00003592 C3                  <1> 	retn
 13304                              <1> 
 13305                              <1> com2_int:
 13306                              <1> 	; 07/11/2015 
 13307                              <1> 	; 24/10/2015
 13308                              <1> 	; 23/10/2015
 13309                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13310                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13311                              <1> 	; < serial port 2 interrupt handler >
 13312                              <1> 	;
 13313 00003593 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13314                              <1> 	;push	eax
 13315 00003596 66B80900            <1> 	mov	ax, 9
 13316 0000359A EB07                <1> 	jmp	short comm_int
 13317                              <1> com1_int:
 13318                              <1> 	; 07/11/2015
 13319                              <1> 	; 24/10/2015
 13320 0000359C 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13321                              <1> 	; 23/10/2015
 13322                              <1> 	;push	eax
 13323 0000359F 66B80800            <1> 	mov	ax, 8
 13324                              <1> comm_int:
 13325                              <1> 	; 20/11/2015
 13326                              <1> 	; 18/11/2015
 13327                              <1> 	; 17/11/2015
 13328                              <1> 	; 16/11/2015
 13329                              <1> 	; 09/11/2015
 13330                              <1> 	; 08/11/2015
 13331                              <1> 	; 07/11/2015
 13332                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
 13333                              <1> 	; 01/11/2015
 13334                              <1> 	; 26/10/2015
 13335                              <1> 	; 23/10/2015
 13336 000035A3 53                  <1> 	push	ebx
 13337 000035A4 56                  <1> 	push	esi
 13338 000035A5 57                  <1> 	push	edi
 13339 000035A6 1E                  <1> 	push 	ds
 13340 000035A7 06                  <1> 	push 	es
 13341                              <1> 	; 18/11/2015
 13342 000035A8 0F20DB              <1> 	mov	ebx, cr3
 13343 000035AB 53                  <1> 	push	ebx ; ****
 13344                              <1> 	;
 13345 000035AC 51                  <1> 	push	ecx ; ***
 13346 000035AD 52                  <1> 	push	edx ; **
 13347                              <1> 	;
 13348 000035AE BB10000000          <1> 	mov	ebx, KDATA
 13349 000035B3 8EDB                <1> 	mov	ds, bx
 13350 000035B5 8EC3                <1> 	mov	es, bx
 13351                              <1> 	;
 13352 000035B7 8B0D[F86E0000]      <1> 	mov	ecx, [k_page_dir]
 13353 000035BD 0F22D9              <1> 	mov	cr3, ecx
 13354                              <1> 	; 20/11/2015
 13355                              <1> 	; Interrupt identification register
 13356 000035C0 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
 13357                              <1> 	;
 13358 000035C4 3C08                <1> 	cmp 	al, 8 
 13359 000035C6 7702                <1> 	ja 	short com_i0
 13360                              <1> 	;
 13361                              <1> 	; 20/11/2015
 13362                              <1> 	; 17/11/2015
 13363                              <1> 	; 16/11/2015
 13364                              <1> 	; 15/11/2015
 13365                              <1> 	; 24/10/2015
 13366                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13367                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13368                              <1> 	; < serial port 1 interrupt handler >
 13369                              <1> 	;
 13370 000035C8 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
 13371                              <1> com_i0:
 13372                              <1> 	;push	eax ; *
 13373                              <1> 	; 07/11/2015
 13374 000035CA A2[666F0000]        <1> 	mov 	byte [ccomport], al
 13375                              <1> 	; 09/11/2015
 13376 000035CF 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
 13377                              <1> 	; 17/11/2015
 13378                              <1>  	; reset request for response status
 13379 000035D2 88A3[5C6F0000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
 13380                              <1> 	;
 13381                              <1> 	; 20/11/2015
 13382 000035D8 EC                  <1> 	in	al, dx		; read interrupt id. register
 13383 000035D9 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13384 000035DB 2404                <1> 	and	al, 4		; received data available?	
 13385 000035DD 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
 13386                              <1> 	;
 13387                              <1> 	; 20/11/2015
 13388 000035DF 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
 13389 000035E2 EC                  <1> 	in	al, dx     	; read character
 13390                              <1> 	;JMP	$+2	   	; I/O DELAY
 13391                              <1> 	; 08/11/2015
 13392                              <1> 	; 07/11/2015
 13393 000035E3 89DE                <1> 	mov	esi, ebx 
 13394 000035E5 89DF                <1> 	mov	edi, ebx
 13395 000035E7 81C6[606F0000]      <1> 	add 	esi, rchar - 8 ; points to last received char
 13396 000035ED 81C7[626F0000]      <1> 	add	edi, schar - 8 ; points to last sent char
 13397 000035F3 8806                <1> 	mov	[esi], al ; received char (current char)
 13398                              <1> 	; query
 13399 000035F5 20C0                <1> 	and	al, al
 13400 000035F7 7527                <1> 	jnz	short com_i2
 13401                              <1>    	; response
 13402                              <1> 	; 17/11/2015
 13403                              <1> 	; set request for response status
 13404 000035F9 FE83[5C6F0000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
 13405                              <1> 	;
 13406 000035FF 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
 13407 00003603 EC                  <1> 	in	al, dx	   	; read line status register 
 13408 00003604 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13409 00003606 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
 13410 00003608 7445                <1> 	jz	short com_eoi 	; no
 13411 0000360A B0FF                <1> 	mov 	al, 0FFh   	; response			
 13412 0000360C 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
 13413 00003610 EE                  <1> 	out	dx, al	   	; send on serial port
 13414                              <1> 	; 17/11/2015
 13415 00003611 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
 13416 00003614 7502                <1> 	jne 	short com_i1    ; no
 13417 00003616 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
 13418                              <1> com_i1:
 13419                              <1> 	; 17/11/2015
 13420                              <1> 	; reset request for response status (again)
 13421 00003618 FE8B[5C6F0000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
 13422 0000361E EB2F                <1> 	jmp	short com_eoi
 13423                              <1> com_i2:	
 13424                              <1> 	; 08/11/2015
 13425 00003620 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
 13426 00003622 7417                <1> 	je	short com_i3	; (check for response signal)
 13427                              <1> 	; 07/11/2015
 13428 00003624 3C04                <1> 	cmp	al, 04h	; EOT
 13429 00003626 751C                <1> 	jne	short com_i4	
 13430                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
 13431                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
 13432                              <1> 	; 08/11/2015
 13433                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
 13434 00003628 861D[266F0000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
 13435 0000362E E810FFFFFF          <1> 	call 	ctrlbrk
 13436 00003633 861D[266F0000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
 13437                              <1> 	;mov	al, 04h ; EOT
 13438                              <1> 	; 08/11/2015
 13439 00003639 EB09                <1> 	jmp	short com_i4	
 13440                              <1> com_i3:
 13441                              <1> 	; 08/11/2015
 13442                              <1> 	; If 0FFh has been received just after a query
 13443                              <1> 	; (schar, ZERO), it is a response signal.
 13444                              <1> 	; 17/11/2015
 13445 0000363B 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
 13446 0000363E 7704                <1> 	ja	short com_i4 ; no
 13447                              <1> 	; reset query status (schar)
 13448 00003640 8807                <1> 	mov	[edi], al ; 0FFh
 13449 00003642 FEC0                <1> 	inc	al ; 0
 13450                              <1> com_i4:
 13451                              <1> 	; 27/07/2014
 13452                              <1> 	; 09/07/2014
 13453 00003644 D0E3                <1> 	shl	bl, 1	
 13454 00003646 81C3[286F0000]      <1> 	add	ebx, ttychr
 13455                              <1> 	; 23/07/2014 (always overwrite)
 13456                              <1> 	;;cmp	word [ebx], 0
 13457                              <1> 	;;ja	short com_eoi
 13458                              <1> 	;
 13459 0000364C 668903              <1> 	mov	[ebx], ax   ; Save ascii code
 13460                              <1> 			    ; scan code = 0
 13461                              <1> com_eoi:
 13462                              <1> 	;mov	al, 20h
 13463                              <1> 	;out	20h, al	   ; end of interrupt
 13464                              <1> 	;
 13465                              <1> 	; 07/11/2015
 13466                              <1>       	;pop	eax ; *
 13467 0000364F A0[666F0000]        <1> 	mov	al, byte [ccomport] ; current COM port
 13468                              <1> 	 ; al = tty number (8 or 9)
 13469 00003654 E8971A0000          <1>         call	wakeup
 13470                              <1> com_iret:
 13471                              <1> 	; 23/10/2015
 13472 00003659 5A                  <1> 	pop	edx ; **
 13473 0000365A 59                  <1> 	pop	ecx ; ***
 13474                              <1> 	; 18/11/2015
 13475                              <1> 	;pop	eax ; ****
 13476                              <1> 	;mov	cr3, eax
 13477                              <1> 	;jmp	iiret
 13478 0000365B E944D3FFFF          <1> 	jmp	iiretp
 13479                              <1> 
 13480                              <1> ;iiretp: ; 01/09/2015
 13481                              <1> ;	; 28/08/2015
 13482                              <1> ;	pop	eax ; (*) page directory
 13483                              <1> ;	mov	cr3, eax
 13484                              <1> ;iiret:
 13485                              <1> ;	; 22/08/2014
 13486                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
 13487                              <1> ;	out	20h, al	; 8259 PORT
 13488                              <1> ;	;
 13489                              <1> ;	pop	es
 13490                              <1> ;	pop	ds
 13491                              <1> ;	pop	edi
 13492                              <1> ;	pop	esi
 13493                              <1> ;	pop	ebx ; 29/08/2014
 13494                              <1> ;	pop 	eax
 13495                              <1> ;	iretd
 13496                              <1> 
 13497                              <1> sp_init:
 13498                              <1> 	; 07/11/2015
 13499                              <1> 	; 29/10/2015
 13500                              <1> 	; 26/10/2015
 13501                              <1> 	; 23/10/2015
 13502                              <1> 	; 29/06/2015
 13503                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
 13504                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
 13505                              <1> 	; Initialization of Serial Port Communication Parameters
 13506                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13507                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13508                              <1> 	;
 13509                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13510                              <1> 	;
 13511                              <1> 	; INPUT:  (29/06/2015)
 13512                              <1> 	;	AL = 0 for COM1
 13513                              <1> 	;	     1 for COM2
 13514                              <1> 	;	AH = Communication parameters	
 13515                              <1> 	;
 13516                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13517                              <1> 	;	Bit	4	3	2	1	0
 13518                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13519                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13520                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13521                              <1> 	;		11 = even
 13522                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13523                              <1> 	;		Retro UNIX 386 v1 feature only !
 13524                              <1> 	;	Bit	7    6    5  | Baud rate
 13525                              <1> 	;		------------------------
 13526                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13527                              <1> 	;		0    0    1  | 9600 (12)
 13528                              <1> 	;		0    1    0  | 19200 (6) 
 13529                              <1> 	;		0    1	  1  | 38400 (3) 
 13530                              <1> 	;		1    0	  0  | 14400 (8)
 13531                              <1> 	;		1    0	  1  | 28800 (4)
 13532                              <1> 	;		1    1    0  | 57600 (2)
 13533                              <1> 	;		1    1    1  | 115200 (1) 	
 13534                              <1> 	
 13535                              <1> 	; References:	
 13536                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
 13537                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
 13538                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
 13539                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
 13540                              <1> 	;
 13541                              <1> 	; Set communication parameters for COM1 (= 03h)	
 13542                              <1> 	;
 13543 00003660 BB[626F0000]        <1> 	mov	ebx, com1p		; COM1 parameters  
 13544 00003665 66BAF803            <1> 	mov	dx, 3F8h		; COM1
 13545                              <1> 	 ; 29/10/2015
 13546 00003669 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13547 0000366D E86F000000          <1> 	call	sp_i3	; call A4	
 13548 00003672 A880                <1> 	test	al, 80h
 13549 00003674 7410                <1> 	jz	short sp_i0 ; OK..
 13550                              <1> 		; Error !
 13551                              <1> 	;mov	dx, 3F8h
 13552 00003676 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
 13553 00003679 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13554 0000367D E85F000000          <1> 	call	sp_i3	; call A4	
 13555 00003682 A880                <1> 	test	al, 80h
 13556 00003684 7508                <1> 	jnz	short sp_i1
 13557                              <1> sp_i0:
 13558                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
 13559                              <1>         ; (INT 14h initialization code disables interrupts.)
 13560                              <1> 	;
 13561 00003686 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13562 00003689 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
 13563                              <1> sp_i1:
 13564 0000368E 43                  <1> 	inc	ebx
 13565 0000368F 66BAF802            <1> 	mov	dx, 2F8h		; COM2
 13566                              <1> 	 ; 29/10/2015
 13567 00003693 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13568 00003697 E845000000          <1> 	call	sp_i3	; call A4	
 13569 0000369C A880                <1> 	test	al, 80h
 13570 0000369E 7410                <1> 	jz	short sp_i2 ; OK..
 13571                              <1> 		; Error !
 13572                              <1> 	;mov	dx, 2F8h
 13573 000036A0 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
 13574 000036A3 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13575 000036A7 E835000000          <1> 	call	sp_i3	; call A4	
 13576 000036AC A880                <1> 	test	al, 80h
 13577 000036AE 7530                <1> 	jnz	short sp_i7
 13578                              <1> sp_i2:
 13579 000036B0 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13580                              <1> sp_i6:
 13581                              <1> 	;; COM2 - enabling IRQ 3
 13582                              <1> 	; 07/11/2015
 13583                              <1> 	; 26/10/2015
 13584 000036B3 9C                  <1> 	pushf
 13585 000036B4 FA                  <1> 	cli
 13586                              <1> 	;
 13587 000036B5 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
 13588 000036B9 EC                  <1> 	in	al, dx 	   		; read register
 13589 000036BA EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13590 000036BC 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13591 000036BE EE                  <1> 	out	dx, al     		; write back to register
 13592 000036BF EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13593 000036C1 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
 13594 000036C5 EC                  <1> 	in	al, dx     		; read register
 13595 000036C6 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13596                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13597 000036C8 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13598 000036CA EE                  <1> 	out	dx, al 	   		; write back to register
 13599 000036CB EB00                <1> 	JMP	$+2        		; I/O DELAY
 13600 000036CD E421                <1> 	in	al, 21h    		; read interrupt mask register
 13601 000036CF EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13602 000036D1 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
 13603 000036D3 E621                <1> 	out	21h, al    		; write back to register
 13604                              <1> 	;
 13605                              <1> 	; 23/10/2015
 13606 000036D5 B8[93350000]        <1> 	mov 	eax, com2_int
 13607 000036DA A3[713B0000]        <1> 	mov	[com2_irq3], eax
 13608                              <1> 	; 26/10/2015
 13609 000036DF 9D                  <1> 	popf	
 13610                              <1> sp_i7:
 13611 000036E0 C3                  <1> 	retn
 13612                              <1> 
 13613                              <1> sp_i3:
 13614                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
 13615                              <1> 	; 28/10/2015
 13616 000036E1 FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
 13617 000036E3 B000                <1> 	mov	al, 0
 13618 000036E5 EE                  <1> 	out	dx, al			; disable serial port interrupt
 13619 000036E6 EB00                <1> 	JMP	$+2			; I/O DELAY
 13620 000036E8 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
 13621 000036EB B080                <1> 	mov	al, 80h			
 13622 000036ED EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
 13623                              <1> 	;-----	SET BAUD RATE DIVISOR
 13624                              <1> 	; 26/10/2015
 13625 000036EE 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
 13626                              <1> 					; of the divisor value
 13627 000036F1 88C8                <1> 	mov	al, cl	; 1
 13628 000036F3 EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
 13629                              <1> 					; 2 = 57600 baud
 13630                              <1> 					; 3 = 38400 baud
 13631                              <1> 					; 6 = 19200 baud
 13632                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
 13633 000036F4 EB00                <1> 	JMP	$+2			; I/O DELAY
 13634 000036F6 28C0                <1> 	sub	al, al
 13635 000036F8 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
 13636                              <1> 					; of the divisor value
 13637 000036FA EE                  <1> 	out	dx, al ; 0
 13638 000036FB EB00                <1> 	JMP	$+2			; I/O DELAY
 13639                              <1> 	;	
 13640 000036FD 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
 13641                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
 13642 000036FF 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
 13643 00003702 EE                  <1> 	out	dx, al			
 13644 00003703 EB00                <1> 	JMP	$+2			; I/O DELAY
 13645                              <1> 	; 29/10/2015
 13646 00003705 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
 13647 00003707 30C0                <1> 	xor	al, al			; 0
 13648 00003709 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
 13649 0000370A EB00                <1> 	JMP	$+2	
 13650                              <1> sp_i4:
 13651                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
 13652                              <1> 	; 29/06/2015 (line status after modem status)
 13653 0000370C 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
 13654                              <1> sp_i4s:
 13655 0000370F EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
 13656 00003710 EB00                <1> 	JMP	$+2			; I/O DELAY
 13657 00003712 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
 13658 00003714 FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
 13659                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
 13660 00003716 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
 13661                              <1> 	; AL = Line status, AH = Modem status
 13662 00003717 C3                  <1> 	retn
 13663                              <1> 
 13664                              <1> sp_status:
 13665                              <1> 	; 29/06/2015
 13666                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
 13667                              <1> 	; Get serial port status
 13668 00003718 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
 13669 0000371C 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
 13670                              <1> 					; dx = 2FEh for COM2
 13671 0000371E EBEF                <1> 	jmp	short sp_i4s
 13672                              <1> 
 13673                              <1> sp_setp: ; Set serial port communication parameters
 13674                              <1> 	; 07/11/2015
 13675                              <1> 	; 29/10/2015
 13676                              <1> 	; 29/06/2015
 13677                              <1> 	; Retro UNIX 386 v1 feature only !	
 13678                              <1> 	;
 13679                              <1> 	; INPUT:
 13680                              <1> 	;	AL = 0 for COM1
 13681                              <1> 	;	     1 for COM2
 13682                              <1> 	;	AH = Communication parameters (*)
 13683                              <1> 	; OUTPUT:
 13684                              <1> 	;	CL = Line status
 13685                              <1> 	;	CH = Modem status
 13686                              <1> 	;   If cf = 1 -> Error code in [u.error]
 13687                              <1> 	;		 'invalid parameter !' 
 13688                              <1> 	;		 	 or
 13689                              <1> 	;		 'device not ready !' error
 13690                              <1> 	;	
 13691                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13692                              <1> 	;	Bit	4	3	2	1	0
 13693                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13694                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13695                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13696                              <1> 	;		11 = even
 13697                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13698                              <1> 	;		Retro UNIX 386 v1 feature only !
 13699                              <1> 	;	Bit	7    6    5  | Baud rate
 13700                              <1> 	;		------------------------
 13701                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13702                              <1> 	;		0    0    1  | 9600 (12)
 13703                              <1> 	;		0    1    0  | 19200 (6) 
 13704                              <1> 	;		0    1	  1  | 38400 (3) 
 13705                              <1> 	;		1    0	  0  | 14400 (8)
 13706                              <1> 	;		1    0	  1  | 28800 (4)
 13707                              <1> 	;		1    1    0  | 57600 (2)
 13708                              <1> 	;		1    1    1  | 115200 (1) 
 13709                              <1> 	;
 13710                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13711                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13712                              <1> 	;
 13713                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13714                              <1> 	;
 13715 00003720 66BAF803            <1> 	mov	dx, 3F8h
 13716 00003724 BB[626F0000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
 13717 00003729 3C01                <1> 	cmp	al, 1
 13718 0000372B 776B                <1> 	ja 	short sp_invp_err
 13719 0000372D 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
 13720 0000372F FECE                <1> 	dec	dh ; 2F8h
 13721 00003731 43                  <1> 	inc	ebx ; COM2 control byte offset
 13722                              <1> sp_setp1:
 13723                              <1> 	; 29/10/2015
 13724 00003732 8823                <1> 	mov	[ebx], ah
 13725 00003734 0FB6CC              <1> 	movzx 	ecx, ah
 13726 00003737 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
 13727 0000373A 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
 13728 0000373D 8A81[A7370000]      <1> 	mov	al, [ecx+b_div_tbl]
 13729 00003743 6689C1              <1> 	mov	cx, ax
 13730 00003746 E896FFFFFF          <1> 	call	sp_i3
 13731 0000374B 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
 13732 0000374E A880                <1> 	test	al, 80h
 13733 00003750 740F                <1> 	jz	short sp_setp2
 13734 00003752 C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
 13735                              <1> stp_dnr_err:
 13736 00003755 C705[6A700000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
 13737 0000375D 0000                <1>
 13738                              <1> 	; CL = Line status, CH = Modem status
 13739 0000375F F9                  <1> 	stc
 13740 00003760 C3                  <1> 	retn
 13741                              <1> sp_setp2:
 13742 00003761 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
 13743 00003764 0F8649FFFFFF        <1>         jna     sp_i6 
 13744                              <1> 		      ; COM1 (3F?h)
 13745                              <1> sp_i5: 
 13746                              <1> 	; 07/11/2015
 13747                              <1> 	; 26/10/2015
 13748                              <1> 	; 29/06/2015
 13749                              <1> 	;
 13750                              <1> 	;; COM1 - enabling IRQ 4
 13751 0000376A 9C                  <1> 	pushf
 13752 0000376B FA                  <1> 	cli
 13753 0000376C 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
 13754 00003770 EC                  <1> 	in	al, dx 	   		; read register
 13755 00003771 EB00                <1> 	JMP	$+2			; I/O DELAY
 13756 00003773 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13757 00003775 EE                  <1> 	out	dx, al     		; write back to register
 13758 00003776 EB00                <1> 	JMP	$+2			; I/O DELAY
 13759 00003778 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
 13760 0000377C EC                  <1> 	in	al, dx     		; read register
 13761 0000377D EB00                <1> 	JMP	$+2			; I/O DELAY
 13762                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13763 0000377F 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13764 00003781 EE                  <1> 	out	dx, al 	   		; write back to register
 13765 00003782 EB00                <1> 	JMP	$+2        		; I/O DELAY
 13766 00003784 E421                <1> 	in	al, 21h    		; read interrupt mask register
 13767 00003786 EB00                <1> 	JMP	$+2			; I/O DELAY
 13768 00003788 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
 13769 0000378A E621                <1> 	out	21h, al    		; write back to register
 13770                              <1> 	;
 13771                              <1> 	; 23/10/2015
 13772 0000378C B8[9C350000]        <1> 	mov 	eax, com1_int
 13773 00003791 A3[6D3B0000]        <1> 	mov	[com1_irq4], eax
 13774                              <1> 	; 26/10/2015
 13775 00003796 9D                  <1> 	popf
 13776 00003797 C3                  <1> 	retn
 13777                              <1> 
 13778                              <1> sp_invp_err:
 13779 00003798 C705[6A700000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 13780 000037A0 0000                <1>
 13781 000037A2 31C9                <1> 	xor	ecx, ecx
 13782 000037A4 49                  <1> 	dec	ecx ; 0FFFFh
 13783 000037A5 F9                  <1> 	stc
 13784 000037A6 C3                  <1> 	retn
 13785                              <1> 
 13786                              <1> ; 29/10/2015
 13787                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
 13788 000037A7 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
 13789                              <1> 
 13790                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (01/09/2014) 
 13791                              <1> epoch:
 13792                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13793                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1 - UNIX.ASM)
 13794                              <1> 	; 'epoch' procedure prototype: 
 13795                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13796                              <1> 	; 14/11/2012
 13797                              <1> 	; unixboot.asm (boot file configuration)
 13798                              <1> 	; version of "epoch" procedure in "unixproc.asm"
 13799                              <1> 	; 21/7/2012
 13800                              <1> 	; 15/7/2012
 13801                              <1> 	; 14/7/2012		
 13802                              <1> 	; Erdogan Tan - RETRO UNIX v0.1
 13803                              <1> 	; compute current date and time as UNIX Epoch/Time
 13804                              <1> 	; UNIX Epoch: seconds since 1/1/1970 00:00:00
 13805                              <1> 	;
 13806                              <1>         ;  ((Modified registers: EAX, EDX, ECX, EBX))  
 13807                              <1> 	;
 13808 000037AE E81D010000          <1> 	call 	get_rtc_time		; Return Current Time
 13809 000037B3 86E9                <1>         xchg 	ch,cl
 13810 000037B5 66890D[666C0000]    <1>         mov 	[hour], cx
 13811 000037BC 86F2                <1>         xchg 	dh,dl
 13812 000037BE 668915[6A6C0000]    <1>         mov 	[second], dx
 13813                              <1> 	;
 13814 000037C5 E837010000          <1>         call 	get_rtc_date		; Return Current Date
 13815 000037CA 86E9                <1>         xchg 	ch,cl
 13816 000037CC 66890D[606C0000]    <1>         mov 	[year], cx
 13817 000037D3 86F2                <1>         xchg 	dh,dl
 13818 000037D5 668915[626C0000]    <1>         mov 	[month], dx
 13819                              <1> 	;
 13820 000037DC 66B93030            <1> 	mov 	cx, 3030h
 13821                              <1> 	;
 13822 000037E0 A0[666C0000]        <1> 	mov 	al, [hour] ; Hour
 13823                              <1>         	; AL <= BCD number)
 13824 000037E5 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13825                              <1> 					; AH = AL / 10h
 13826                              <1> 					; AL = AL MOD 10h
 13827 000037E7 D50A                <1>         aad 	; AX= AH*10+AL
 13828 000037E9 A2[666C0000]        <1> 	mov 	[hour], al
 13829 000037EE A0[676C0000]        <1> 	mov 	al, [hour+1] ; Minute
 13830                              <1>         	; AL <= BCD number)
 13831 000037F3 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13832                              <1> 					; AH = AL / 10h
 13833                              <1> 					; AL = AL MOD 10h
 13834 000037F5 D50A                <1>         aad 	; AX= AH*10+AL
 13835 000037F7 A2[686C0000]        <1> 	mov 	[minute], al
 13836 000037FC A0[6A6C0000]        <1> 	mov 	al, [second] ; Second
 13837                              <1>         	; AL <= BCD number)
 13838 00003801 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13839                              <1> 					; AH = AL / 10h
 13840                              <1> 					; AL = AL MOD 10h
 13841 00003803 D50A                <1>         aad 	; AX= AH*10+AL
 13842 00003805 A2[6A6C0000]        <1> 	mov 	[second], al
 13843 0000380A 66A1[606C0000]      <1> 	mov 	ax, [year] ; Year (century)
 13844 00003810 6650                <1>         push 	ax
 13845                              <1> 	   	; AL <= BCD number)
 13846 00003812 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13847                              <1> 					; AH = AL / 10h
 13848                              <1> 					; AL = AL MOD 10h
 13849 00003814 D50A                <1>         aad 	; AX= AH*10+AL
 13850 00003816 B464                <1> 	mov 	ah, 100
 13851 00003818 F6E4                <1> 	mul 	ah
 13852 0000381A 66A3[606C0000]      <1> 	mov 	[year], ax
 13853 00003820 6658                <1> 	pop	ax
 13854 00003822 88E0                <1> 	mov	al, ah
 13855                              <1>         	; AL <= BCD number)
 13856 00003824 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13857                              <1> 					; AH = AL / 10h
 13858                              <1> 					; AL = AL MOD 10h
 13859 00003826 D50A                <1>         aad 	; AX= AH*10+AL
 13860 00003828 660105[606C0000]    <1> 	add 	[year], ax
 13861 0000382F A0[626C0000]        <1> 	mov 	al, [month] ; Month
 13862                              <1>            	; AL <= BCD number)
 13863 00003834 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13864                              <1> 					; AH = AL / 10h
 13865                              <1> 					; AL = AL MOD 10h
 13866 00003836 D50A                <1>         aad 	; AX= AH*10+AL
 13867 00003838 A2[626C0000]        <1> 	mov 	[month], al	
 13868 0000383D A0[636C0000]        <1>         mov     al, [month+1]      	; Day
 13869                              <1>            	; AL <= BCD number)
 13870 00003842 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13871                              <1> 					; AH = AL / 10h
 13872                              <1> 					; AL = AL MOD 10h
 13873 00003844 D50A                <1>         aad 	; AX= AH*10+AL
 13874 00003846 A2[646C0000]        <1>         mov     [day], al
 13875                              <1> 	
 13876                              <1> convert_to_epoch:
 13877                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit modification)
 13878                              <1> 	; 09/04/2013 (retro UNIX 8086 v1)
 13879                              <1> 	;
 13880                              <1> 	; ((Modified registers: EAX, EDX, EBX)) 
 13881                              <1> 	;
 13882                              <1> 	; Derived from DALLAS Semiconductor
 13883                              <1> 	; Application Note 31 (DS1602/DS1603)
 13884                              <1> 	; 6 May 1998
 13885 0000384B 29C0                <1> 	sub 	eax, eax
 13886 0000384D 66A1[606C0000]      <1> 	mov 	ax, [year]
 13887 00003853 662DB207            <1> 	sub 	ax, 1970
 13888 00003857 BA6D010000          <1> 	mov 	edx, 365
 13889 0000385C F7E2                <1> 	mul 	edx
 13890 0000385E 31DB                <1> 	xor 	ebx, ebx
 13891 00003860 8A1D[626C0000]      <1> 	mov 	bl, [month]
 13892 00003866 FECB                <1> 	dec 	bl
 13893 00003868 D0E3                <1> 	shl 	bl, 1
 13894                              <1> 	;sub	edx, edx
 13895 0000386A 668B93[6C6C0000]    <1> 	mov 	dx, [EBX+DMonth]
 13896 00003871 8A1D[646C0000]      <1>         mov     bl, [day]
 13897 00003877 FECB                <1> 	dec 	bl
 13898 00003879 01D0                <1> 	add 	eax, edx
 13899 0000387B 01D8                <1> 	add 	eax, ebx
 13900                              <1> 			; EAX = days since 1/1/1970
 13901 0000387D 668B15[606C0000]    <1> 	mov 	dx, [year]
 13902 00003884 6681EAB107          <1> 	sub 	dx, 1969
 13903 00003889 66D1EA              <1> 	shr 	dx, 1
 13904 0000388C 66D1EA              <1> 	shr 	dx, 1		
 13905                              <1> 		; (year-1969)/4
 13906 0000388F 01D0                <1> 	add 	eax, edx
 13907                              <1> 			; + leap days since 1/1/1970
 13908 00003891 803D[626C0000]02    <1> 	cmp 	byte [month], 2	; if past february
 13909 00003898 7610                <1> 	jna 	short cte1
 13910 0000389A 668B15[606C0000]    <1> 	mov 	dx, [year]
 13911 000038A1 6683E203            <1> 	and 	dx, 3 ; year mod 4
 13912 000038A5 7503                <1> 	jnz 	short cte1		
 13913                              <1> 			; and if leap year
 13914 000038A7 83C001              <1> 	add 	eax, 1 	; add this year's leap day (february 29)
 13915                              <1> cte1: 			; compute seconds since 1/1/1970
 13916 000038AA BA18000000          <1> 	mov 	edx, 24
 13917 000038AF F7E2                <1> 	mul	edx
 13918 000038B1 8A15[666C0000]      <1> 	mov 	dl, [hour]
 13919 000038B7 01D0                <1> 	add 	eax, edx
 13920                              <1> 		; EAX = hours since 1/1/1970 00:00:00
 13921                              <1> 	;mov	ebx, 60
 13922 000038B9 B33C                <1> 	mov	bl, 60
 13923 000038BB F7E3                <1> 	mul	ebx
 13924 000038BD 8A15[686C0000]      <1> 	mov 	dl, [minute]
 13925 000038C3 01D0                <1> 	add 	eax, edx
 13926                              <1> 		; EAX = minutes since 1/1/1970 00:00:00
 13927                              <1> 	;mov 	ebx, 60
 13928 000038C5 F7E3                <1> 	mul	ebx
 13929 000038C7 8A15[6A6C0000]      <1> 	mov 	dl, [second]
 13930 000038CD 01D0                <1> 	add 	eax, edx
 13931                              <1>  		; EAX -> seconds since 1/1/1970 00:00:00
 13932 000038CF C3                  <1> 	retn
 13933                              <1> 
 13934                              <1> get_rtc_time:
 13935                              <1> 	; 15/03/2015
 13936                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13937                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13938                              <1> 	; INT 1Ah
 13939                              <1> 	; (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,	:
 13940                              <1> 	;       (CH) = HOURS IN BCD (00-23)			:
 13941                              <1> 	;       (CL) = MINUTES IN BCD (00-59)			:
 13942                              <1> 	;       (DH) = SECONDS IN BCD (00-59)			:
 13943                              <1> 	;       (DL) = DAYLIGHT SAVINGS ENABLE (00-01).		:
 13944                              <1> 	;								
 13945                              <1> RTC_20: 				; GET RTC TIME
 13946 000038D0 FA                  <1> 	cli
 13947 000038D1 E869D2FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13948 000038D6 7227                <1> 	JC	short RTC_29		; EXIT IF ERROR (CY= 1)
 13949                              <1> 
 13950 000038D8 B000                <1> 	MOV	AL,CMOS_SECONDS 	; SET ADDRESS OF SECONDS
 13951 000038DA E848D2FFFF          <1> 	CALL	CMOS_READ		; GET SECONDS
 13952 000038DF 88C6                <1> 	MOV	DH,AL			; SAVE
 13953 000038E1 B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
 13954 000038E3 E83FD2FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 13955 000038E8 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
 13956 000038EA 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
 13957 000038EC B002                <1> 	MOV	AL,CMOS_MINUTES 	; SET ADDRESS OF MINUTES
 13958 000038EE E834D2FFFF          <1> 	CALL	CMOS_READ		; GET MINUTES
 13959 000038F3 88C1                <1> 	MOV	CL,AL			; SAVE
 13960 000038F5 B004                <1> 	MOV	AL,CMOS_HOURS		; SET ADDRESS OF HOURS
 13961 000038F7 E82BD2FFFF          <1> 	CALL	CMOS_READ		; GET HOURS
 13962 000038FC 88C5                <1> 	MOV	CH,AL			; SAVE
 13963 000038FE F8                  <1> 	CLC				; SET CY= 0
 13964                              <1> RTC_29:
 13965 000038FF FB                  <1> 	sti
 13966 00003900 C3                  <1> 	RETn				; RETURN WITH RESULT IN CARRY FLAG
 13967                              <1> 
 13968                              <1> get_rtc_date:
 13969                              <1> 	; 15/03/2015
 13970                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13971                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13972                              <1> 	; INT 1Ah
 13973                              <1> 	; (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,:
 13974                              <1> 	;      (CH) = CENTURY IN BCD (19 OR 20) 		       :
 13975                              <1> 	;      (CL) = YEAR IN BCD (00-99)			       :
 13976                              <1> 	;      (DH) = MONTH IN BCD (01-12)			       :
 13977                              <1> 	;      (DL) = DAY IN BCD (01-31).		
 13978                              <1> 	;
 13979                              <1> RTC_40: 				; GET RTC DATE
 13980 00003901 FA                  <1> 	cli
 13981 00003902 E838D2FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13982 00003907 7225                <1> 	JC	short RTC_49		; EXIT IF ERROR (CY= 1)
 13983                              <1> 
 13984 00003909 B007                <1> 	MOV	AL,CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
 13985 0000390B E817D2FFFF          <1> 	CALL	CMOS_READ		; READ DAY OF MONTH
 13986 00003910 88C2                <1> 	MOV	DL,AL			; SAVE
 13987 00003912 B008                <1> 	MOV	AL,CMOS_MONTH		; ADDRESS MONTH
 13988 00003914 E80ED2FFFF          <1> 	CALL	CMOS_READ		; READ MONTH
 13989 00003919 88C6                <1> 	MOV	DH,AL			; SAVE
 13990 0000391B B009                <1> 	MOV	AL,CMOS_YEAR		; ADDRESS YEAR
 13991 0000391D E805D2FFFF          <1> 	CALL	CMOS_READ		; READ YEAR
 13992 00003922 88C1                <1> 	MOV	CL,AL			; SAVE
 13993 00003924 B032                <1> 	MOV	AL,CMOS_CENTURY 	; ADDRESS CENTURY LOCATION
 13994 00003926 E8FCD1FFFF          <1> 	CALL	CMOS_READ		; GET CENTURY BYTE
 13995 0000392B 88C5                <1> 	MOV	CH,AL			; SAVE
 13996 0000392D F8                  <1> 	CLC				; SET CY=0
 13997                              <1> RTC_49:
 13998 0000392E FB                  <1> 	sti
 13999 0000392F C3                  <1> 	RETn				; RETURN WITH RESULTS IN CARRY FLAG
 14000                              <1> 
 14001                              <1> set_date_time:
 14002                              <1> convert_from_epoch:
 14003                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 14004                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 14005                              <1> 	; 'convert_from_epoch' procedure prototype: 
 14006                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 14007                              <1> 	;
 14008                              <1> 	; ((Modified registers: EAX, EDX, ECX, EBX))	
 14009                              <1> 	;
 14010                              <1> 	; Derived from DALLAS Semiconductor
 14011                              <1> 	; Application Note 31 (DS1602/DS1603)
 14012                              <1> 	; 6 May 1998
 14013                              <1> 	;
 14014                              <1> 	; INPUT:
 14015                              <1> 	; EAX = Unix (Epoch) Time
 14016                              <1> 	;
 14017 00003930 31D2                <1> 	xor 	edx, edx
 14018 00003932 B93C000000          <1> 	mov 	ecx, 60
 14019 00003937 F7F1                <1> 	div	ecx
 14020                              <1> 	;mov 	[imin], eax   ; whole minutes
 14021                              <1> 			  ; since 1/1/1970
 14022 00003939 668915[6A6C0000]    <1> 	mov 	[second], dx  ; leftover seconds
 14023 00003940 29D2                <1> 	sub 	edx, edx
 14024 00003942 F7F1                <1> 	div	ecx
 14025                              <1> 	;mov 	[ihrs], eax   ; whole hours
 14026                              <1> 	;		      ; since 1/1/1970
 14027 00003944 668915[686C0000]    <1> 	mov 	[minute], dx  ; leftover minutes
 14028 0000394B 31D2                <1> 	xor	edx, edx
 14029                              <1> 	;mov 	cx, 24
 14030 0000394D B118                <1> 	mov 	cl, 24
 14031 0000394F F7F1                <1> 	div	ecx
 14032                              <1> 	;mov 	[iday], ax   ; whole days
 14033                              <1> 			     ; since 1/1/1970
 14034 00003951 668915[666C0000]    <1> 	mov 	[hour], dx   ; leftover hours
 14035 00003958 05DB020000          <1> 	add 	eax, 365+366 ; whole day since
 14036                              <1> 			     ; 1/1/1968 	
 14037                              <1> 	;mov 	[iday], ax
 14038 0000395D 50                  <1> 	push 	eax
 14039 0000395E 29D2                <1> 	sub	edx, edx
 14040 00003960 B9B5050000          <1> 	mov 	ecx, (4*365)+1 ; 4 years = 1461 days
 14041 00003965 F7F1                <1> 	div	ecx
 14042 00003967 59                  <1> 	pop 	ecx
 14043                              <1> 	;mov 	[lday], ax   ; count of quadyrs (4 years)
 14044 00003968 6652                <1> 	push 	dx
 14045                              <1> 	;mov 	[qday], dx   ; days since quadyr began
 14046 0000396A 6683FA3C            <1> 	cmp 	dx, 31 + 29  ; if past feb 29 then
 14047 0000396E F5                  <1> 	cmc		     ; add this quadyr's leap day
 14048 0000396F 83D000              <1> 	adc 	eax, 0	     ; to # of qadyrs (leap days)
 14049                              <1> 	;mov 	[lday], ax   ; since 1968			  
 14050                              <1> 	;mov 	cx, [iday]
 14051 00003972 91                  <1> 	xchg 	ecx, eax     ; ECX = lday, EAX = iday		  
 14052 00003973 29C8                <1> 	sub 	eax, ecx     ; iday - lday
 14053 00003975 B96D010000          <1> 	mov 	ecx, 365
 14054 0000397A 31D2                <1> 	xor	edx, edx
 14055                              <1> 	; EAX = iday-lday, EDX = 0
 14056 0000397C F7F1                <1> 	div	ecx
 14057                              <1> 	;mov 	[iyrs], ax   ; whole years since 1968
 14058                              <1> 	;jday = iday - (iyrs*365) - lday
 14059                              <1> 	;mov [jday], dx      ; days since 1/1 of current year
 14060                              <1> 	;add	eax, 1968
 14061 0000397E 6605B007            <1> 	add 	ax, 1968     ; compute year
 14062 00003982 66A3[606C0000]      <1> 	mov 	[year], ax
 14063 00003988 6689D1              <1> 	mov 	cx, dx
 14064                              <1> 	;mov 	dx, [qday]
 14065 0000398B 665A                <1> 	pop 	dx
 14066 0000398D 6681FA6D01          <1> 	cmp 	dx, 365	     ; if qday <= 365 and qday >= 60	
 14067 00003992 7709                <1> 	ja 	short cfe1   ; jday = jday +1
 14068 00003994 6683FA3C            <1> 	cmp 	dx, 60       ; if past 2/29 and leap year then
 14069 00003998 F5                  <1>         cmc		     ; add a leap day to the # of whole
 14070 00003999 6683D100            <1> 	adc 	cx, 0        ; days since 1/1 of current year
 14071                              <1> cfe1:			
 14072                              <1> 	;mov 	[jday], cx
 14073 0000399D 66BB0C00            <1> 	mov 	bx, 12       ; estimate month
 14074 000039A1 66BA6E01            <1> 	mov 	dx, 366      ; mday, max. days since 1/1 is 365
 14075 000039A5 6683E003            <1> 	and 	ax, 11b      ; year mod 4 (and dx, 3) 
 14076                              <1> cfe2:	; Month calculation  ; 0 to 11  (11 to 0)	
 14077 000039A9 6639D1              <1> 	cmp 	cx, dx       ; mday = # of days passed from 1/1
 14078 000039AC 731D                <1> 	jnb 	short cfe3
 14079 000039AE 664B                <1> 	dec 	bx           ; month = month - 1
 14080 000039B0 66D1E3              <1> 	shl 	bx, 1 
 14081 000039B3 668B93[6C6C0000]    <1> 	mov 	dx, [EBX+DMonth] ; # elapsed days at 1st of month
 14082 000039BA 66D1EB              <1> 	shr 	bx, 1        ; bx = month - 1 (0 to 11)
 14083 000039BD 6683FB01            <1> 	cmp	bx, 1        ; if month > 2 and year mod 4  = 0	
 14084 000039C1 76E6                <1> 	jna 	short cfe2   ; then mday = mday + 1
 14085 000039C3 08C0                <1> 	or 	al, al       ; if past 2/29 and leap year then
 14086 000039C5 75E2                <1> 	jnz 	short cfe2   ; add leap day (to mday)
 14087 000039C7 6642                <1> 	inc 	dx           ; mday = mday + 1
 14088 000039C9 EBDE                <1> 	jmp 	short cfe2
 14089                              <1> cfe3:
 14090 000039CB 6643                <1> 	inc 	bx	     ; -> bx = month, 1 to 12
 14091 000039CD 66891D[626C0000]    <1> 	mov 	[month], bx
 14092 000039D4 6629D1              <1> 	sub 	cx, dx	     ; day = jday - mday + 1	
 14093 000039D7 6641                <1> 	inc 	cx 			  
 14094 000039D9 66890D[646C0000]    <1> 	mov 	[day], cx
 14095                              <1> 	
 14096                              <1> 	; eax, ebx, ecx, edx is changed at return
 14097                              <1> 	; output ->
 14098                              <1> 	; [year], [month], [day], [hour], [minute], [second]
 14099                              <1> 	
 14100                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 14101                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 14102                              <1> set_date:
 14103 000039E0 A0[616C0000]        <1>         mov     al, [year+1]
 14104 000039E5 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14105 000039E7 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14106                              <1> 			     ; AL = AH * 10h + AL
 14107 000039E9 88C5                <1> 	mov 	ch, al ; century (BCD)
 14108 000039EB A0[606C0000]        <1> 	mov 	al, [year]
 14109 000039F0 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14110 000039F2 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14111                              <1> 			     ; AL = AH * 10h + AL
 14112 000039F4 88C1                <1> 	mov 	cl, al ; year (BCD)
 14113 000039F6 A0[626C0000]        <1>         mov 	al, [month]
 14114 000039FB D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14115 000039FD D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14116                              <1> 			     ; AL = AH * 10h + AL
 14117 000039FF 88C6                <1> 	mov 	dh, al ; month (BCD)
 14118 00003A01 A0[646C0000]        <1> 	mov 	al, [day]
 14119 00003A06 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14120 00003A08 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14121                              <1> 			     ; AL = AH * 10h + AL
 14122 00003A0A 88C6                <1> 	mov 	dh, al ; day (BCD)
 14123                              <1> 	; Set real-time clock date
 14124 00003A0C E879000000          <1> 	call	set_rtc_date
 14125                              <1> set_time:
 14126                              <1>         ; Read real-time clock time 
 14127                              <1> 	; (get day light saving time bit status)
 14128 00003A11 FA                  <1>  	cli
 14129 00003A12 E828D1FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14130                              <1> 	; cf = 1 -> al = 0
 14131 00003A17 7207                <1>         jc      short stime1
 14132 00003A19 B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
 14133 00003A1B E807D1FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 14134                              <1> stime1:
 14135 00003A20 FB                  <1> 	sti
 14136 00003A21 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
 14137 00003A23 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
 14138                              <1> 	; DL = 1 or 0 (day light saving time)
 14139                              <1> 	;	
 14140 00003A25 A0[666C0000]        <1> 	mov 	al, [hour]
 14141 00003A2A D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14142 00003A2C D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14143                              <1> 			     ; AL = AH * 10h + AL
 14144 00003A2E 88C5                <1> 	mov 	ch, al ; hour (BCD)
 14145 00003A30 A0[686C0000]        <1>         mov     al, [minute]
 14146 00003A35 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14147 00003A37 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14148                              <1> 			     ; AL = AH * 10h + AL
 14149 00003A39 88C1                <1> 	mov 	cl, al       ; minute (BCD)
 14150 00003A3B A0[6A6C0000]        <1>         mov     al, [second]
 14151 00003A40 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14152 00003A42 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14153                              <1> 			     ; AL = AH * 10h + AL
 14154 00003A44 88C6                <1> 	mov 	dh, al	     ; second (BCD)
 14155                              <1> 	; Set real-time clock time
 14156                              <1>  	; call	set_rtc_time
 14157                              <1> set_rtc_time:
 14158                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 14159                              <1> 	; 15/03/2015
 14160                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14161                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14162                              <1> 	; INT 1Ah
 14163                              <1> 	; (AH) = 03H  SET THE REAL TIME CLOCK USING,			:
 14164                              <1> 	;      (CH) = HOURS IN BCD (00-23)			       	:
 14165                              <1> 	;      (CL) = MINUTES IN BCD (00-59)			       	:
 14166                              <1> 	;      (DH) = SECONDS IN BCD (00-59)			       	:
 14167                              <1> 	;      (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.    :
 14168                              <1> 	;								:
 14169                              <1> 	;  NOTE: (DL)= 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED. :
 14170                              <1> 	;        (DL)= 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN  :
 14171                              <1> 	;         APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN :
 14172                              <1> 	;         OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.	  :
 14173                              <1> 	;
 14174                              <1> RTC_30: 				; SET RTC TIME
 14175 00003A46 FA                  <1> 	cli
 14176 00003A47 E8F3D0FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14177 00003A4C 7305                <1> 	JNC	short RTC_35		; GO AROUND IF CLOCK OPERATING
 14178 00003A4E E886000000          <1> 	CALL	RTC_STA 		; ELSE TRY INITIALIZING CLOCK
 14179                              <1> RTC_35:
 14180 00003A53 88F4                <1> 	MOV	AH,DH			; GET TIME BYTE - SECONDS
 14181 00003A55 B000                <1> 	MOV	AL,CMOS_SECONDS 	; ADDRESS SECONDS
 14182 00003A57 E89E000000          <1> 	CALL	CMOS_WRITE		; UPDATE SECONDS
 14183 00003A5C 88CC                <1> 	MOV	AH,CL			; GET TIME BYTE - MINUTES
 14184 00003A5E B002                <1> 	MOV	AL,CMOS_MINUTES 	; ADDRESS MINUTES
 14185 00003A60 E895000000          <1> 	CALL	CMOS_WRITE		; UPDATE MINUTES
 14186 00003A65 88EC                <1> 	MOV	AH,CH			; GET TIME BYTE - HOURS
 14187 00003A67 B004                <1> 	MOV	AL,CMOS_HOURS		; ADDRESS HOURS
 14188 00003A69 E88C000000          <1> 	CALL	CMOS_WRITE		; UPDATE ADDRESS
 14189                              <1> 	;MOV	AX,X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 14190 00003A6E 66B80B0B            <1> 	MOV	AX,257*CMOS_REG_B 	; 
 14191 00003A72 E8B0D0FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT TIME
 14192 00003A77 2462                <1> 	AND	AL,01100010B		; MASK FOR VALID BIT POSITIONS
 14193 00003A79 0C02                <1> 	OR	AL,00000010B		; TURN ON 24 HOUR MODE
 14194 00003A7B 80E201              <1> 	AND	DL,00000001B		; USE ONLY THE DSE BIT
 14195 00003A7E 08D0                <1> 	OR	AL,DL			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
 14196 00003A80 86E0                <1> 	XCHG	AH,AL			; PLACE IN WORK REGISTER AND GET ADDRESS
 14197 00003A82 E873000000          <1> 	CALL	CMOS_WRITE		; SET NEW ALARM BITS
 14198 00003A87 F8                  <1> 	CLC				; SET CY= 0
 14199 00003A88 FB                  <1> 	sti
 14200 00003A89 C3                  <1> 	RETn				; RETURN WITH CY= 0
 14201                              <1> 
 14202                              <1> set_rtc_date:
 14203                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 14204                              <1> 	; 15/03/2015
 14205                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14206                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14207                              <1> 	; INT 1Ah
 14208                              <1> 	; (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING, :
 14209                              <1> 	;     (CH) = CENTURY IN BCD (19 OR 20)			   :
 14210                              <1> 	;     (CL) = YEAR IN BCD (00-99)			   :
 14211                              <1> 	;     (DH) = MONTH IN BCD (01-12)			   :
 14212                              <1> 	;     (DL) = DAY IN BCD (01-31).
 14213                              <1> 	;
 14214                              <1> RTC_50: 				; SET RTC DATE
 14215 00003A8A FA                  <1> 	cli
 14216 00003A8B E8AFD0FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14217 00003A90 7305                <1> 	JNC	short RTC_55		; GO AROUND IF NO ERROR
 14218 00003A92 E842000000          <1> 	CALL	RTC_STA 		; ELSE INITIALIZE CLOCK
 14219                              <1> RTC_55:
 14220 00003A97 66B80600            <1> 	MOV	AX,CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
 14221 00003A9B E85A000000          <1> 	CALL	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
 14222 00003AA0 88D4                <1> 	MOV	AH,DL			; GET DAY OF MONTH BYTE
 14223 00003AA2 B007                <1> 	MOV	AL,CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
 14224 00003AA4 E851000000          <1> 	CALL	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
 14225 00003AA9 88F4                <1> 	MOV	AH,DH			; GET MONTH
 14226 00003AAB B008                <1> 	MOV	AL,CMOS_MONTH		; ADDRESS MONTH BYTE
 14227 00003AAD E848000000          <1> 	CALL	CMOS_WRITE		; WRITE MONTH REGISTER
 14228 00003AB2 88CC                <1> 	MOV	AH,CL			; GET YEAR BYTE
 14229 00003AB4 B009                <1> 	MOV	AL,CMOS_YEAR		; ADDRESS YEAR REGISTER
 14230 00003AB6 E83F000000          <1> 	CALL	CMOS_WRITE		; WRITE YEAR REGISTER
 14231 00003ABB 88EC                <1> 	MOV	AH,CH			; GET CENTURY BYTE
 14232 00003ABD B032                <1> 	MOV	AL,CMOS_CENTURY 	; ADDRESS CENTURY BYTE
 14233 00003ABF E836000000          <1> 	CALL	CMOS_WRITE		; WRITE CENTURY LOCATION
 14234                              <1> 	;MOV	AX,X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 14235 00003AC4 66B80B0B            <1> 	MOV	AX,257*CMOS_REG_B 	; 
 14236 00003AC8 E85AD0FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT SETTINGS
 14237 00003ACD 247F                <1> 	AND	AL,07FH 		; CLEAR 'SET BIT'
 14238 00003ACF 86E0                <1> 	XCHG	AH,AL			; MOVE TO WORK REGISTER
 14239 00003AD1 E824000000          <1> 	CALL	CMOS_WRITE		; AND START CLOCK UPDATING
 14240 00003AD6 F8                  <1> 	CLC				; SET CY= 0
 14241 00003AD7 FB                  <1> 	sti
 14242 00003AD8 C3                  <1> 	RETn				; RETURN CY=0
 14243                              <1> 
 14244                              <1> 	; 15/03/2015
 14245                              <1> RTC_STA:				; INITIALIZE REAL TIME CLOCK
 14246 00003AD9 B426                <1> 	mov	ah, 26h
 14247 00003ADB B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK
 14248 00003ADD E818000000          <1> 	CALL	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
 14249 00003AE2 B482                <1> 	mov	ah, 82h
 14250 00003AE4 B00B                <1> 	mov 	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION
 14251 00003AE6 E80F000000          <1> 	CALL	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
 14252 00003AEB B00C                <1> 	MOV	AL,CMOS_REG_C		; ADDRESS REGISTER C
 14253 00003AED E835D0FFFF          <1> 	CALL	CMOS_READ		; READ REGISTER C TO INITIALIZE
 14254 00003AF2 B00D                <1> 	MOV	AL,CMOS_REG_D		; ADDRESS REGISTER D
 14255 00003AF4 E82ED0FFFF          <1> 	CALL	CMOS_READ		; READ REGISTER D TO INITIALIZE
 14256 00003AF9 C3                  <1> 	RETn
 14257                              <1> 
 14258                              <1> 	; 15/03/2015
 14259                              <1> 	; IBM PC/XT Model 286 BIOS source code ----- 10/06/85 (test4.asm)
 14260                              <1> CMOS_WRITE:			; WRITE (AH) TO LOCATION (AL)
 14261 00003AFA 9C                  <1> 	pushf			; SAVE INTERRUPT ENABLE STATUS AND FLAGS
 14262                              <1> 	;push	ax		; SAVE WORK REGISTER VALUES
 14263 00003AFB D0C0                <1> 	rol	al, 1		; MOVE NMI BIT TO LOW POSITION
 14264 00003AFD F9                  <1> 	stc			; FORCE NMI BIT ON IN CARRY FLAG
 14265 00003AFE D0D8                <1> 	rcr	al, 1		; HIGH BIT ON TO DISABLE NMI - OLD IN CY
 14266 00003B00 FA                  <1> 	cli			; DISABLE INTERRUPTS
 14267 00003B01 E670                <1> 	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
 14268 00003B03 88E0                <1> 	mov	al, ah		; GET THE DATA BYTE TO WRITE
 14269 00003B05 E671                <1> 	out	CMOS_DATA, al	; PLACE IN REQUESTED CMOS LOCATION
 14270 00003B07 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
 14271 00003B09 D0D8                <1> 	rcr	al, 1		; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
 14272 00003B0B E670                <1> 	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
 14273 00003B0D 90                  <1> 	nop			; I/O DELAY
 14274 00003B0E E471                <1> 	in	al, CMOS_DATA	; OPEN STANDBY LATCH
 14275                              <1> 	;pop	ax		; RESTORE WORK REGISTERS
 14276 00003B10 9D                  <1> 	popf	
 14277 00003B11 C3                  <1> 	RETn
 14278                              <1> 
 14279                              <1> bf_init:
 14280                              <1> 	; 28/11/2021
 14281                              <1> 	; 14/08/2015
 14282                              <1> 	; 02/07/2015
 14283                              <1> 	; 01/07/2015
 14284                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 14285                              <1> 	; Buffer (pointer) initialization !
 14286                              <1> 	; 
 14287                              <1> 	; 17/07/2013 - 24/07/2013
 14288                              <1> 	; Retro UNIX 8086 v1 (U9.ASM)
 14289                              <1> 	; (Retro UNIX 8086 v1 feature only !)
 14290                              <1> 	;
 14291 00003B12 BF[B06F0000]        <1> 	mov	edi, bufp 
 14292 00003B17 B8[607D0000]        <1> 	mov	eax, buffer + (nbuf*520) 
 14293 00003B1C 29D2                <1> 	sub	edx, edx
 14294 00003B1E FECA                <1> 	dec	dl
 14295 00003B20 31C9                <1> 	xor	ecx, ecx
 14296 00003B22 49                  <1> 	dec	ecx
 14297                              <1> bi0:
 14298 00003B23 2D08020000          <1> 	sub	eax, 520 ; 8 header + 512 data
 14299 00003B28 AB                  <1> 	stosd
 14300 00003B29 89C6                <1> 	mov	esi, eax
 14301 00003B2B 8916                <1> 	mov	[esi], edx ; 000000FFh
 14302                              <1> 			    ; Not a valid device sign
 14303 00003B2D 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14304                              <1> 		      ; Not a valid block number sign 	 	
 14305 00003B30 3D[30710000]        <1> 	cmp	eax, buffer
 14306 00003B35 77EC                <1> 	ja	short bi0
 14307 00003B37 B8[607D0000]        <1> 	mov	eax, sb0
 14308 00003B3C AB                  <1> 	stosd
 14309 00003B3D B8[687F0000]        <1> 	mov	eax, sb1
 14310 00003B42 AB                  <1> 	stosd
 14311 00003B43 89C6                <1> 	mov	esi, eax ; offset sb1
 14312 00003B45 8916                <1> 	mov	[esi], edx ; 000000FFh
 14313                              <1> 			    ; Not a valid device sign
 14314 00003B47 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14315                              <1> 		      ; Not a valid block number sign 	 
 14316                              <1> 	; 14/08/2015
 14317                              <1> 	;call 	rdev_init
 14318                              <1> 	;retn
 14319                              <1> 
 14320                              <1> 	; 28/11/2021
 14321                              <1> rdev_init: ; root device, super block buffer initialization
 14322                              <1> 	; 14/08/2015
 14323                              <1> 	; Retro UNIX 386 v1 feature only !
 14324                              <1> 	;
 14325                              <1> 	; NOTE: Disk partitions (file systems), logical
 14326                              <1> 	; drive initialization, partition's start sector etc.
 14327                              <1> 	; will be coded here, later in 'ldrv_init'	
 14328                              <1> 
 14329 00003B4A 0FB605[EA690000]    <1> 	movzx	eax, byte [boot_drv]
 14330                              <1> rdi_0:
 14331 00003B51 3C80                <1> 	cmp	al, 80h
 14332 00003B53 7202                <1> 	jb	short rdi_1
 14333 00003B55 2C7E                <1> 	sub	al, 7Eh ; 80h = 2 (hd0), 81h = 3 (hd1)
 14334                              <1> rdi_1:
 14335 00003B57 A2[D66F0000]        <1> 	mov	[rdev], al
 14336 00003B5C BB[607D0000]        <1>         mov	ebx, sb0 ; super block buffer
 14337 00003B61 8903                <1> 	mov 	[ebx], eax
 14338 00003B63 B001                <1> 	mov	al, 1 ; eax = 1
 14339 00003B65 894304              <1> 	mov	[ebx+4], eax ; super block address on disk
 14340                              <1> 	;call 	diskio
 14341                              <1> 	;retn
 14342                              <1> 	; 28/11/2021
 14343 00003B68 E9B8260000          <1> 	jmp	diskio
 14344                              <1> 
 14345                              <1> ; 23/10/2015
 14346                              <1> com1_irq4:
 14347 00003B6D [753B0000]          <1> 	dd dummy_retn
 14348                              <1> com2_irq3:
 14349 00003B71 [753B0000]          <1> 	dd dummy_retn
 14350                              <1> 
 14351                              <1> dummy_retn:
 14352 00003B75 C3                  <1> 	retn
 14353                                  %include 'u1.s'        ; 10/05/2015
 14354                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 14355                              <1> ; (re-write kernel for test by using previous version without a major defect)
 14356                              <1> ; ****************************************************************************
 14357                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS1.INC
 14358                              <1> ; Last Modification: 30/11/2021
 14359                              <1> ; ----------------------------------------------------------------------------
 14360                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 14361                              <1> ; (v0.1 - Beginning: 11/07/2012)
 14362                              <1> ;
 14363                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 14364                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 14365                              <1> ; <Bell Laboratories (17/3/1972)>
 14366                              <1> ; <Preliminary Release of UNIX Implementation Document>
 14367                              <1> ;
 14368                              <1> ; Retro UNIX 8086 v1 - U1.ASM (12/07/2014) //// UNIX v1 -> u1.s
 14369                              <1> ;
 14370                              <1> ; ****************************************************************************
 14371                              <1> 
 14372                              <1> unkni: ; / used for all system calls
 14373                              <1> sysent: ; < enter to system call >
 14374                              <1> 	; 19/10/2015
 14375                              <1> 	; 21/09/2015
 14376                              <1> 	; 01/07/2015
 14377                              <1> 	; 19/05/2015
 14378                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14379                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 14380                              <1> 	;
 14381                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
 14382                              <1> 	; The trap type is determined and an indirect jump is made to 
 14383                              <1> 	; the appropriate system call handler. If there is a trap inside
 14384                              <1> 	; the system a jump to panic is made. All user registers are saved 
 14385                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
 14386                              <1> 	; instructor is decoded to get the the system code part (see
 14387                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
 14388                              <1> 	; the indirect jump address is calculated. If a bad system call is
 14389                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
 14390                              <1> 	; is called. If the call is legitimate control passes to the
 14391                              <1> 	; appropriate system routine.
 14392                              <1> 	;
 14393                              <1> 	; Calling sequence:
 14394                              <1> 	;	Through a trap caused by any sys call outside the system.
 14395                              <1> 	; Arguments:
 14396                              <1> 	;	Arguments of particular system call.	
 14397                              <1> 	; ...............................................................
 14398                              <1> 	;	
 14399                              <1> 	; Retro UNIX 8086 v1 modification: 
 14400                              <1> 	;       System call number is in EAX register.
 14401                              <1> 	;
 14402                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14403                              <1> 	;	registers depending of function details.
 14404                              <1>   	;
 14405                              <1> 	; 16/04/2015
 14406 00003B76 368925[EC6F0000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
 14407                              <1> 	; save user registers
 14408 00003B7D 1E                  <1> 	push	ds
 14409 00003B7E 06                  <1> 	push	es
 14410 00003B7F 0FA0                <1> 	push	fs
 14411 00003B81 0FA8                <1> 	push	gs
 14412 00003B83 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
 14413                              <1> 	;
 14414                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
 14415                              <1> 	; 	(ESPACE is size of space in kernel stack 
 14416                              <1> 	;	for saving/restoring user registers.)
 14417                              <1> 	;
 14418 00003B84 50                  <1> 	push	eax ; 01/07/2015
 14419 00003B85 66B81000            <1> 	mov     ax, KDATA
 14420 00003B89 8ED8                <1>         mov     ds, ax
 14421 00003B8B 8EC0                <1>         mov     es, ax
 14422 00003B8D 8EE0                <1>         mov     fs, ax
 14423 00003B8F 8EE8                <1>         mov     gs, ax
 14424 00003B91 A1[F86E0000]        <1> 	mov	eax, [k_page_dir]
 14425 00003B96 0F22D8              <1> 	mov	cr3, eax
 14426 00003B99 58                  <1> 	pop	eax ; 01/07/2015
 14427                              <1> 	; 19/10/2015
 14428 00003B9A FC                  <1> 	cld
 14429                              <1> 	;
 14430 00003B9B FE05[E96F0000]      <1> 	inc	byte [sysflg]
 14431                              <1> 		; incb sysflg / indicate a system routine is in progress
 14432 00003BA1 FB                  <1>         sti 	; 18/01/2014
 14433 00003BA2 0F8561F9FFFF        <1> 	jnz     panic ; 24/05/2013
 14434                              <1> 		; beq 1f
 14435                              <1> 		; jmp panic ; / called if trap inside system
 14436                              <1> ;1:
 14437                              <1> 	; 16/04/2015
 14438 00003BA8 A3[F46F0000]        <1> 	mov	[u.r0], eax
 14439 00003BAD 8925[F06F0000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
 14440                              <1> 	;
 14441                              <1> 		; mov $s.syst+2,clockp
 14442                              <1> 		; mov r0,-(sp) / save user registers 
 14443                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
 14444                              <1> 			   ; / in u.r0
 14445                              <1> 		; mov r1,-(sp)
 14446                              <1> 		; mov r2,-(sp)
 14447                              <1> 		; mov r3,-(sp)
 14448                              <1> 		; mov r4,-(sp)
 14449                              <1> 		; mov r5,-(sp)
 14450                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
 14451                              <1> 		             ; / arithmetic unit
 14452                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
 14453                              <1> 		             ; / extended arithmetic unit
 14454                              <1> 		; mov sc,-(sp) / "step count" register for the extended
 14455                              <1> 		             ; / arithmetic unit
 14456                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
 14457                              <1> 		; mov 18.(sp),r0 / store pc in r0
 14458                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
 14459                              <1> 		; sub $sys,r0 / get xxx code
 14460 00003BB3 C1E002              <1> 	shl	eax, 2
 14461                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
 14462 00003BB6 3D94000000          <1> 	cmp	eax, end_of_syscalls - syscalls
 14463                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
 14464                              <1> 	;jnb	short badsys
 14465                              <1> 		; bhis badsys / yes, bad system call
 14466 00003BBB F5                  <1> 	cmc
 14467 00003BBC 9C                  <1> 	pushf	
 14468 00003BBD 50                  <1> 	push	eax
 14469 00003BBE 8B2D[EC6F0000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
 14470 00003BC4 B0FE                <1> 	mov	al, 0FEh ; 11111110b
 14471 00003BC6 1400                <1> 	adc	al, 0 ; al = al + cf
 14472 00003BC8 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
 14473                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
 14474                              <1> 				 ; / and clear carry bit
 14475 00003BCB 5D                  <1> 	pop	ebp ; eax
 14476 00003BCC 9D                  <1> 	popf
 14477 00003BCD 0F8246010000        <1>         jc      badsys
 14478 00003BD3 A1[F46F0000]        <1> 	mov	eax, [u.r0]
 14479                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
 14480 00003BD8 FFA5[DE3B0000]      <1> 	jmp	dword [ebp+syscalls]
 14481                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
 14482                              <1> 		            ; / to proper system routine.
 14483                              <1> syscalls: ; 1:
 14484                              <1> 	; 21/09/2015
 14485                              <1> 	; 01/07/2015
 14486                              <1> 	; 16/04/2015 (32 bit address modification) 
 14487 00003BDE [E33C0000]          <1> 	dd sysrele	; / 0
 14488 00003BE2 [893D0000]          <1> 	dd sysexit 	; / 1
 14489 00003BE6 [AD3E0000]          <1> 	dd sysfork 	; / 2
 14490 00003BEA [C03F0000]          <1> 	dd sysread 	; / 3
 14491 00003BEE [DB3F0000]          <1> 	dd syswrite 	; / 4
 14492 00003BF2 [45400000]          <1> 	dd sysopen 	; / 5
 14493 00003BF6 [7F410000]          <1> 	dd sysclose 	; / 6
 14494 00003BFA [2F3E0000]          <1> 	dd syswait 	; / 7
 14495 00003BFE [F5400000]          <1> 	dd syscreat 	; / 8
 14496 00003C02 [A6440000]          <1> 	dd syslink 	; / 9
 14497 00003C06 [68450000]          <1> 	dd sysunlink 	; / 10
 14498 00003C0A [3B460000]          <1> 	dd sysexec 	; / 11
 14499 00003C0E [A44C0000]          <1> 	dd syschdir 	; / 12
 14500 00003C12 [884D0000]          <1> 	dd systime 	; / 13
 14501 00003C16 [36410000]          <1> 	dd sysmkdir 	; / 14
 14502 00003C1A [F64C0000]          <1> 	dd syschmod 	; / 15
 14503 00003C1E [584D0000]          <1> 	dd syschown 	; / 16
 14504 00003C22 [BB4D0000]          <1> 	dd sysbreak 	; / 17
 14505 00003C26 [184A0000]          <1> 	dd sysstat 	; / 18
 14506 00003C2A [804E0000]          <1> 	dd sysseek 	; / 19
 14507 00003C2E [924E0000]          <1> 	dd systell 	; / 20
 14508 00003C32 [0A5C0000]          <1> 	dd sysmount 	; / 21
 14509 00003C36 [BC5C0000]          <1> 	dd sysumount 	; / 22
 14510 00003C3A [104F0000]          <1> 	dd syssetuid 	; / 23
 14511 00003C3E [414F0000]          <1> 	dd sysgetuid 	; / 24
 14512 00003C42 [974D0000]          <1> 	dd sysstime 	; / 25
 14513 00003C46 [044F0000]          <1> 	dd sysquit 	; / 26
 14514 00003C4A [F84E0000]          <1> 	dd sysintr 	; / 27
 14515 00003C4E [F4490000]          <1> 	dd sysfstat 	; / 28
 14516 00003C52 [9B410000]          <1> 	dd sysemt 	; / 29
 14517 00003C56 [C9410000]          <1> 	dd sysmdate 	; / 30
 14518 00003C5A [14420000]          <1> 	dd sysstty 	; / 31
 14519 00003C5E [93430000]          <1> 	dd sysgtty 	; / 32
 14520 00003C62 [C4410000]          <1> 	dd sysilgins 	; / 33
 14521 00003C66 [0D650000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
 14522                              <1> 			     ; 11/06/2014
 14523 00003C6A [3C650000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
 14524                              <1> 			     ; 01/07/2015
 14525 00003C6E [13660000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
 14526                              <1> 			     ; 21/09/2015 - get last error number
 14527                              <1> end_of_syscalls:
 14528                              <1> 
 14529                              <1> error:
 14530                              <1> 	; 17/09/2015
 14531                              <1> 	; 03/09/2015
 14532                              <1> 	; 01/09/2015
 14533                              <1> 	; 09/06/2015
 14534                              <1> 	; 13/05/2015
 14535                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14536                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 14537                              <1> 	;
 14538                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
 14539                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
 14540                              <1> 	;
 14541                              <1> 	; INPUTS -> none
 14542                              <1> 	; OUTPUTS ->
 14543                              <1> 	;	processor status - carry (c) bit is set (means error)
 14544                              <1> 	;
 14545                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
 14546                              <1> 	; 	      Because, jumps to error procedure
 14547                              <1> 	;	      disrupts push-pop nesting balance)
 14548                              <1> 	;
 14549 00003C72 8B2D[EC6F0000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
 14550 00003C78 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
 14551                              <1> 				 ; (system call will return with cf = 1)
 14552                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
 14553                              <1> 		               ; / users stack
 14554                              <1> 	; 17/09/2015
 14555 00003C7C 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
 14556                              <1> 				 ; for saving/restoring user registers	
 14557                              <1> 	;cmp	ebp, [u.usp]
 14558                              <1> 	;je	short err0	
 14559 00003C7F 892D[F06F0000]      <1> 	mov	[u.usp], ebp
 14560                              <1> ;err0:
 14561                              <1> 	; 01/09/2015
 14562 00003C85 8B25[F06F0000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
 14563                              <1> 				    ; 10/04/2013
 14564                              <1> 				    ; (If an I/O error occurs during disk I/O,
 14565                              <1> 				    ; related procedures will jump to 'error'
 14566                              <1> 				    ; procedure directly without returning to 
 14567                              <1> 				    ; the caller procedure. So, stack pointer
 14568                              <1>                                     ; must be restored here.)
 14569                              <1> 	; 13/05/2015
 14570                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
 14571                              <1> 	;	'get last error' system call later. 	
 14572                              <1> 
 14573                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
 14574 00003C8B C605[68700000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
 14575                              <1> 
 14576                              <1> sysret: ; < return from system call>
 14577                              <1> 	; 30/11/2021
 14578                              <1> 	; 10/09/2015
 14579                              <1> 	; 29/07/2015
 14580                              <1> 	; 25/06/2015
 14581                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14582                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 14583                              <1> 	;
 14584                              <1> 	; 'sysret' first checks to see if process is about to be 
 14585                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
 14586                              <1> 	; If not, following happens:	 
 14587                              <1> 	; 	1) The user's stack pointer is restored.
 14588                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
 14589                              <1> 	;	   i-node has been modified. If it has, it is written out
 14590                              <1> 	;	   via 'ppoke'.
 14591                              <1> 	;	3) If the super block has been modified, it is written out
 14592                              <1> 	;	   via 'ppoke'.				
 14593                              <1> 	;	4) If the dismountable file system's super block has been
 14594                              <1> 	;	   modified, it is written out to the specified device
 14595                              <1> 	;	   via 'ppoke'.
 14596                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
 14597                              <1> 	;	   during his execution. If so, 'tswap' is called to give
 14598                              <1> 	;	   another user a chance to run.
 14599                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
 14600                              <1> 	;	    (See 'sysrele' for conclusion.)		
 14601                              <1> 	;
 14602                              <1> 	; Calling sequence:
 14603                              <1> 	;	jump table or 'br sysret'
 14604                              <1> 	; Arguments: 
 14605                              <1> 	;	-	
 14606                              <1> 	; ...............................................................
 14607                              <1> 	;	
 14608                              <1> 	; ((AX=r1 for 'iget' input))
 14609                              <1> 	;	
 14610                              <1> 	;xor	ax, ax ; 04/05/2013
 14611                              <1> 	; 30/11/2021
 14612 00003C92 31C0                <1> 	xor	eax, eax
 14613                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
 14614 00003C94 FEC0                <1> 	inc	al ; 04/05/2013
 14615 00003C96 3805[48700000]      <1> 	cmp	[u.bsys], al ; 1
 14616                              <1> 		; tstb u.bsys / is a process about to be terminated because
 14617 00003C9C 0F83E7000000        <1>         jnb     sysexit ; 04/05/2013
 14618                              <1> 		; bne sysexit / of an error? yes, go to sysexit
 14619                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
 14620                              <1> 		; mov u.sp,sp / no point stack to users stack
 14621 00003CA2 FEC8                <1> 	dec 	al ; mov ax, 0
 14622                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
 14623 00003CA4 E830180000          <1> 	call	iget
 14624                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
 14625                              <1> 		            ; / it is written out
 14626                              <1> 	;xor 	ax, ax ; 0
 14627                              <1> 	; 30/11/2021
 14628 00003CA9 31C0                <1> 	xor	eax, eax
 14629 00003CAB 3805[E76F0000]      <1> 	cmp	[smod], al ; 0
 14630                              <1> 		; tstb	smod / has the super block been modified
 14631 00003CB1 7614                <1> 	jna	short sysret1
 14632                              <1> 		; beq	1f / no, 1f
 14633 00003CB3 A2[E76F0000]        <1> 	mov	[smod], al ; 0
 14634                              <1> 		; clrb smod / yes, clear smod
 14635 00003CB8 BB[607D0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
 14636 00003CBD 66810B0002          <1>    	or	word [ebx], 200h ;;
 14637                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
 14638                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
 14639                              <1> 		      	      ; / output
 14640                              <1> 	; AX = 0
 14641 00003CC2 E83C240000          <1> 	call 	poke ; 07/08/2013
 14642                              <1> 	;call	ppoke
 14643                              <1> 	; AX = 0
 14644                              <1> 		; jsr r0,ppoke / write out modified super block to disk
 14645                              <1> sysret1: ;1:
 14646 00003CC7 3805[E86F0000]      <1> 	cmp	[mmod], al ; 0
 14647                              <1> 		; tstb	mmod / has the super block for the dismountable file
 14648                              <1> 		           ; / system
 14649 00003CCD 7614                <1> 	jna	short sysrel0
 14650                              <1> 		; beq 1f / been modified?  no, 1f
 14651 00003CCF A2[E86F0000]        <1> 	mov	[mmod], al ; 0	
 14652                              <1> 		; clrb	mmod / yes, clear mmod
 14653                              <1>         ;mov    ax, [mntd]
 14654                              <1>         ;;mov   al, [mdev] ; 26/04/2013
 14655 00003CD4 BB[687F0000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
 14656                              <1>         ;;mov	[ebx], al
 14657                              <1> 	;mov    [sb1], al
 14658                              <1> 		; movb	mntd,sb1 / set the I/O queue
 14659 00003CD9 66810B0002          <1> 	or	word [ebx], 200h
 14660                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
 14661                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
 14662 00003CDE E820240000          <1> 	call	poke ; 07/08/2013
 14663                              <1> 	;call	ppoke 
 14664                              <1> 		; jsr r0,ppoke / write it out to its device
 14665                              <1>         ;xor    al, al ; 26/04/2013       
 14666                              <1> ;1:
 14667                              <1> 		; tstb uquant / is the time quantum 0?
 14668                              <1> 		; bne 1f / no, don't swap it out
 14669                              <1> 
 14670                              <1> sysrele: ; < release >
 14671                              <1> 	; 14/10/2015
 14672                              <1> 	; 01/09/2015
 14673                              <1> 	; 24/07/2015
 14674                              <1> 	; 14/05/2015
 14675                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14676                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
 14677                              <1> 	;
 14678                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
 14679                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
 14680                              <1> 	; turns off the system flag. It then checked to see if there is
 14681                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
 14682                              <1> 	; the output gets flashed (see isintr) and interrupt action is
 14683                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
 14684                              <1> 	; the user, a rti is made.
 14685                              <1> 	;
 14686                              <1> 	; Calling sequence:
 14687                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
 14688                              <1> 	; Arguments:
 14689                              <1> 	;	-	
 14690                              <1> 	; ...............................................................
 14691                              <1> 	;	
 14692                              <1> 	; 23/02/2014 (swapret)
 14693                              <1> 	; 22/09/2013
 14694                              <1> sysrel0: ;1:
 14695 00003CE3 803D[40700000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
 14696                              <1> 		; tstb uquant / is the time quantum 0?
 14697 00003CEA 7705                <1>         ja      short swapret
 14698                              <1> 		; bne 1f / no, don't swap it out
 14699                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
 14700 00003CEC E8A2120000          <1> 	call	tswap
 14701                              <1> 		; jsr r0,tswap / yes, swap it out
 14702                              <1> ;
 14703                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
 14704                              <1> swapret: ;1:
 14705                              <1> 	; 10/09/2015
 14706                              <1> 	; 01/09/2015
 14707                              <1> 	; 14/05/2015
 14708                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
 14709                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
 14710                              <1> 	; cli
 14711                              <1> 	; 24/07/2015
 14712                              <1> 	;
 14713                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
 14714                              <1> 	;; mov	esp, [u.usp]
 14715                              <1> 
 14716                              <1> 	; 22/09/2013
 14717 00003CF1 E887140000          <1> 	call	isintr
 14718                              <1> 	; 20/10/2013
 14719 00003CF6 7405                <1> 	jz	short sysrel1
 14720 00003CF8 E875000000          <1> 	call	intract
 14721                              <1> 		; jsr r0,isintr / is there an interrupt from the user
 14722                              <1> 		;     br intract / yes, output gets flushed, take interrupt
 14723                              <1> 		               ; / action
 14724                              <1> sysrel1:
 14725 00003CFD FA                  <1> 	cli ; 14/10/2015
 14726 00003CFE FE0D[E96F0000]      <1> 	dec	byte [sysflg]
 14727                              <1> 		; decb sysflg / turn system flag off
 14728 00003D04 A1[58700000]        <1> 	mov     eax, [u.pgdir]
 14729 00003D09 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
 14730                              <1> 			  ; (others are different than kernel page tables) 
 14731                              <1> 	; 10/09/2015
 14732 00003D0C 61                  <1> 	popad ; edi, esi, ebp, temp (increment esp by 4), ebx, edx, ecx, eax
 14733                              <1> 		; mov (sp)+,sc / restore user registers
 14734                              <1> 		; mov (sp)+,mq
 14735                              <1> 		; mov (sp)+,ac
 14736                              <1> 		; mov (sp)+,r5
 14737                              <1> 		; mov (sp)+,r4
 14738                              <1> 		; mov (sp)+,r3
 14739                              <1> 		; mov (sp)+,r2
 14740                              <1> 	;
 14741 00003D0D A1[F46F0000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
 14742 00003D12 0FA9                <1> 	pop	gs
 14743 00003D14 0FA1                <1> 	pop	fs
 14744 00003D16 07                  <1> 	pop	es
 14745 00003D17 1F                  <1> 	pop	ds
 14746 00003D18 CF                  <1> 	iretd	
 14747                              <1> 		; rti / no, return from interrupt
 14748                              <1> 
 14749                              <1> badsys:
 14750                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14751                              <1> 	; (Major Modification: 'core' dumping procedure in
 14752                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
 14753                              <1> 	;	has been changed to print 'Invalid System Call !'
 14754                              <1> 	;	message on the user's console tty.)
 14755                              <1> 	; (EIP, EAX values will be shown on screen with error message)
 14756                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
 14757                              <1> 	; (EAX = Function number)  
 14758                              <1> 	;
 14759 00003D19 FE05[48700000]      <1> 	inc	byte [u.bsys]
 14760                              <1> 	;
 14761 00003D1F 8B1D[EC6F0000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
 14762 00003D25 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
 14763 00003D27 E8E4DAFFFF          <1> 	call	dwordtohex
 14764 00003D2C 8915[546C0000]      <1> 	mov	[bsys_msg_eip], edx
 14765 00003D32 A3[586C0000]        <1> 	mov	[bsys_msg_eip+4], eax
 14766 00003D37 A1[F46F0000]        <1> 	mov	eax, [u.r0]
 14767 00003D3C E8CFDAFFFF          <1> 	call	dwordtohex
 14768 00003D41 8915[446C0000]      <1> 	mov	[bsys_msg_eax], edx
 14769 00003D47 A3[486C0000]        <1> 	mov	[bsys_msg_eax+4], eax
 14770 00003D4C 31C0                <1> 	xor	eax, eax
 14771 00003D4E C705[1C700000]-     <1>         mov     dword [u.base], badsys_msg ; "Invalid System call !"
 14772 00003D54 [256C0000]          <1>
 14773 00003D58 8B1D[08700000]      <1> 	mov	ebx, [u.fofp]
 14774 00003D5E 8903                <1> 	mov	[ebx], eax
 14775                              <1> 	;mov	eax, 1 ; inode number of console tty (for user)	
 14776 00003D60 40                  <1> 	inc	eax
 14777 00003D61 C705[20700000]3B00- <1> 	mov	dword [u.count], BSYS_M_SIZE
 14778 00003D69 0000                <1>
 14779                              <1> 		; writei
 14780                              <1> 		; INPUTS ->
 14781                              <1> 		;    r1 - inode number
 14782                              <1> 		;    u.count - byte count to be written
 14783                              <1> 		;    u.base - points to user buffer
 14784                              <1> 		;    u.fofp - points to word with current file offset
 14785                              <1> 		; OUTPUTS ->
 14786                              <1> 		;    u.count - cleared
 14787                              <1> 		;    u.nread - accumulates total bytes passed back	
 14788                              <1> 		;
 14789                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
 14790 00003D6B E8D91B0000          <1> 	call	writei
 14791                              <1> 	;mov	eax, 1
 14792 00003D70 EB17                <1> 	jmp	sysexit
 14793                              <1> 
 14794                              <1> 		; incb u.bsys / turn on the user's bad-system flag
 14795                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
 14796                              <1> 		; jsr r0,namei / get the i-number for the core image file
 14797                              <1> 		; br 1f / error
 14798                              <1> 		; neg r1 / negate the i-number to open the core image file
 14799                              <1> 		       ; / for writing
 14800                              <1> 		; jsr r0,iopen / open the core image file
 14801                              <1> 		; jsr r0,itrunc / free all associated blocks
 14802                              <1> 		; br 2f
 14803                              <1> ;1:
 14804                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
 14805                              <1> 		; jsr r0,maknod / make an i-node
 14806                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
 14807                              <1> ;2:
 14808                              <1> 		; mov $core,u.base / move address core to u.base
 14809                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
 14810                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
 14811                              <1> 		; clr u.off / clear user offset
 14812                              <1> 		; jsr r0,writei / write out the core image to the user
 14813                              <1> 		; mov $user,u.base / pt. u.base to user
 14814                              <1> 		; mov $64.,u.count / u.count = 64
 14815                              <1> 		; jsr r0,writei / write out all the user parameters
 14816                              <1> 		; neg r1 / make i-number positive
 14817                              <1> 		; jsr r0,iclose / close the core image file
 14818                              <1> 		; br sysexit /
 14819                              <1> ;3:
 14820                              <1> 		; <core\0\0>
 14821                              <1> 
 14822                              <1> intract: ; / interrupt action
 14823                              <1> 	; 14/10/2015
 14824                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14825                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
 14826                              <1> 	;
 14827                              <1> 	; Retro UNIX 8086 v1 modification !
 14828                              <1> 	; (Process/task switching and quit routine by using
 14829                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 14830                              <1> 	;
 14831                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
 14832                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
 14833                              <1> 	;		'intract' will jump to 'sysexit'.
 14834                              <1> 	;	    Intract will return to the caller 
 14835                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
 14836                              <1> 	; 14/10/2015
 14837 00003D72 FB                  <1> 	sti
 14838                              <1> 	; 07/12/2013	
 14839 00003D73 66FF05[46700000]    <1> 	inc 	word [u.quit]
 14840 00003D7A 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
 14841 00003D7C 66FF0D[46700000]    <1> 	dec	word [u.quit]
 14842                              <1> 	; 16/04/2015
 14843 00003D83 C3                  <1> 	retn
 14844                              <1> intrct0:	
 14845 00003D84 58                  <1> 	pop	eax ; call intract -> retn
 14846                              <1> 	;
 14847 00003D85 31C0                <1> 	xor 	eax, eax
 14848 00003D87 FEC0                <1> 	inc	al  ; mov ax, 1
 14849                              <1> ;;;
 14850                              <1> 	; UNIX v1 original 'intract' routine... 
 14851                              <1> 	; / interrupt action
 14852                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
 14853                              <1> 		; bne 1f / no, 1f
 14854                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
 14855                              <1> 	; 1: / now in user area
 14856                              <1> 		; mov r1,-(sp) / save r1
 14857                              <1> 		; mov u.ttyp,r1 
 14858                              <1> 			; / pointer to tty buffer in control-to r1
 14859                              <1> 		; cmpb 6(r1),$177
 14860                              <1> 			; / is the interrupt char equal to "del"
 14861                              <1> 		; beq 1f / yes, 1f
 14862                              <1> 		; clrb 6(r1) 
 14863                              <1> 		        ; / no, clear the byte 
 14864                              <1> 			; / (must be a quit character)
 14865                              <1> 		; mov (sp)+,r1 / restore r1
 14866                              <1> 		; clr u.quit / clear quit flag
 14867                              <1> 		; bis $20,2(sp) 
 14868                              <1> 		    	; / set trace for quit (sets t bit of 
 14869                              <1> 			; / ps-trace trap)
 14870                              <1> 		; rti   ;  / return from interrupt
 14871                              <1> 	; 1: / interrupt char = del
 14872                              <1> 		; clrb 6(r1) / clear the interrupt byte 
 14873                              <1> 			   ; / in the buffer
 14874                              <1> 		; mov (sp)+,r1 / restore r1
 14875                              <1> 		; cmp u.intr,$core / should control be 
 14876                              <1> 				; / transferred to loc core?
 14877                              <1> 		; blo 1f
 14878                              <1> 		; jmp *u.intr / user to do rti yes, 
 14879                              <1> 				; / transfer to loc core
 14880                              <1> 	; 1:
 14881                              <1> 		; sys 1 / exit
 14882                              <1> 
 14883                              <1> sysexit: ; <terminate process>
 14884                              <1> 	; 30/11/2021 - etro UNIX 386 v1.2
 14885                              <1> 	; 01/09/2015
 14886                              <1> 	; 31/08/2015
 14887                              <1> 	; 14/05/2015
 14888                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14889                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 14890                              <1> 	;
 14891                              <1> 	; 'sysexit' terminates a process. First each file that
 14892                              <1> 	; the process has opened is closed by 'flose'. The process
 14893                              <1> 	; status is then set to unused. The 'p.pid' table is then
 14894                              <1> 	; searched to find children of the dying process. If any of
 14895                              <1> 	; children are zombies (died by not waited for), they are
 14896                              <1> 	; set free. The 'p.pid' table is then searched to find the
 14897                              <1> 	; dying process's parent. When the parent is found, it is
 14898                              <1> 	; checked to see if it is free or it is a zombie. If it is
 14899                              <1> 	; one of these, the dying process just dies. If it is waiting
 14900                              <1> 	; for a child process to die, it notified that it doesn't 
 14901                              <1> 	; have to wait anymore by setting it's status from 2 to 1
 14902                              <1> 	; (waiting to active). It is awakened and put on runq by
 14903                              <1> 	; 'putlu'. The dying process enters a zombie state in which
 14904                              <1> 	; it will never be run again but stays around until a 'wait'
 14905                              <1> 	; is completed by it's parent process. If the parent is not
 14906                              <1> 	; found, process just dies. This means 'swap' is called with
 14907                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
 14908                              <1> 	; to write out the process and 'rswap' reads the new process
 14909                              <1> 	; over the one that dies..i.e., the dying process is 
 14910                              <1> 	; overwritten and destroyed.	
 14911                              <1>  	;
 14912                              <1> 	; Calling sequence:
 14913                              <1> 	;	sysexit or conditional branch.
 14914                              <1> 	; Arguments:
 14915                              <1> 	;	-	
 14916                              <1> 	; ...............................................................
 14917                              <1> 	;	
 14918                              <1> 	; Retro UNIX 8086 v1 modification: 
 14919                              <1> 	;       System call number (=1) is in EAX register.
 14920                              <1> 	;
 14921                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14922                              <1> 	;       registers depending of function details.
 14923                              <1> 	;
 14924                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
 14925                              <1> 	;
 14926                              <1> ; / terminate process
 14927                              <1> 	; AX = 1
 14928                              <1> 	;dec 	ax ; 0
 14929                              <1> 	; 30/11/2021
 14930 00003D89 48                  <1> 	dec	eax ; 0
 14931 00003D8A 66A3[44700000]      <1> 	mov	[u.intr], ax ; 0
 14932                              <1> 		; clr u.intr / clear interrupt control word
 14933                              <1> 		; clr r1 / clear r1
 14934                              <1> 	; AX = 0
 14935                              <1> sysexit_1: ; 1:
 14936                              <1> 	; AX = File descriptor
 14937                              <1> 		; / r1 has file descriptor (index to u.fp list)
 14938                              <1> 		; / Search the whole list
 14939 00003D90 E8190D0000          <1> 	call	fclose
 14940                              <1> 		; jsr r0,fclose / close all files the process opened
 14941                              <1> 	;; ignore error return
 14942                              <1> 		; br .+2 / ignore error return
 14943                              <1> 	;inc	ax
 14944 00003D95 FEC0                <1> 	inc	al
 14945                              <1> 		; inc r1 / increment file descriptor
 14946                              <1> 	;cmp	ax, 10
 14947 00003D97 3C0A                <1> 	cmp	al, 10
 14948                              <1> 		; cmp r1,$10. / end of u.fp list?
 14949 00003D99 72F5                <1> 	jb	short sysexit_1
 14950                              <1> 		; blt 1b / no, go back
 14951 00003D9B 0FB61D[49700000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 14952                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
 14953 00003DA2 88A3[5F6D0000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 14954                              <1> 		; clrb p.stat-1(r1) / free the process
 14955                              <1> 	;shl	bx, 1
 14956 00003DA8 D0E3                <1> 	shl	bl, 1
 14957                              <1> 		; asl r1 / use r1 for index into the below tables
 14958 00003DAA 668B8B[CE6C0000]    <1> 	mov	cx, [ebx+p.pid-2]
 14959                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
 14960 00003DB1 668B93[EE6C0000]    <1> 	mov	dx, [ebx+p.ppid-2]
 14961                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
 14962                              <1> 	; xor 	bx, bx ; 0
 14963 00003DB8 30DB                <1> 	xor	bl, bl ; 0
 14964                              <1> 		; clr r2
 14965 00003DBA 31F6                <1> 	xor	esi, esi ; 0
 14966                              <1> 		; clr r5 / initialize reg
 14967                              <1> sysexit_2: ; 1:
 14968                              <1> 	        ; / find children of this dying process, 
 14969                              <1> 		; / if they are zombies, free them
 14970                              <1> 	;add	bx, 2
 14971 00003DBC 80C302              <1> 	add	bl, 2
 14972                              <1> 		; add $2,r2 / search parent process table 
 14973                              <1> 		          ; / for dying process's name
 14974 00003DBF 66398B[EE6C0000]    <1> 	cmp	[ebx+p.ppid-2], cx
 14975                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
 14976 00003DC6 7513                <1> 	jne	short sysexit_4
 14977                              <1> 		; bne 3f / no
 14978                              <1> 	;shr	bx, 1
 14979 00003DC8 D0EB                <1> 	shr	bl, 1
 14980                              <1> 		; asr r2 / yes, it is a parent
 14981 00003DCA 80BB[5F6D0000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
 14982                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
 14983                              <1> 				     ; / dying process a zombie
 14984 00003DD1 7506                <1> 	jne	short sysexit_3 
 14985                              <1> 		; bne 2f / no
 14986 00003DD3 88A3[5F6D0000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 14987                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
 14988                              <1> sysexit_3: ; 2:
 14989                              <1> 	;shr	bx, 1
 14990 00003DD9 D0E3                <1> 	shl	bl, 1
 14991                              <1> 		; asl r2
 14992                              <1> sysexit_4: ; 3:
 14993                              <1> 		; / search the process name table 
 14994                              <1> 		; / for the dying process's parent
 14995 00003DDB 663993[CE6C0000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
 14996                              <1> 		; cmp p.pid-2(r2),r4 / found it?
 14997 00003DE2 7502                <1> 	jne	short sysexit_5
 14998                              <1> 		; bne 3f / no
 14999 00003DE4 89DE                <1> 	mov	esi, ebx
 15000                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
 15001                              <1> 		          ; / process # x2) in r5
 15002                              <1> sysexit_5: ; 3:
 15003                              <1> 	;cmp	bx, nproc + nproc
 15004 00003DE6 80FB20              <1> 	cmp	bl, nproc + nproc
 15005                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
 15006 00003DE9 72D1                <1> 	jb	short sysexit_2
 15007                              <1> 		; blt 1b / no, go back
 15008                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
 15009 00003DEB 21F6                <1> 	and	esi, esi ; r5=r1
 15010 00003DED 7431                <1> 	jz	short sysexit_6
 15011                              <1> 		; beq 2f / no parent has been found. 
 15012                              <1> 		       ; / The process just dies
 15013 00003DEF 66D1EE              <1> 	shr	si, 1
 15014                              <1> 		; asr r1 / set up index to p.stat
 15015 00003DF2 8A86[5F6D0000]      <1> 	mov	al, [esi+p.stat-1]
 15016                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
 15017 00003DF8 20C0                <1> 	and	al, al
 15018 00003DFA 7424                <1> 	jz	short sysexit_6
 15019                              <1> 		; beq 2f / if its been freed, 2f
 15020 00003DFC 3C03                <1> 	cmp	al, 3
 15021                              <1> 		; cmp r2,$3 / is parent a zombie?
 15022 00003DFE 7420                <1> 	je	short sysexit_6
 15023                              <1> 		; beq 2f / yes, 2f
 15024                              <1> 	; BH = 0
 15025 00003E00 8A1D[49700000]      <1> 	mov	bl, [u.uno]
 15026                              <1> 		; movb u.uno,r3 / move dying process's number to r3
 15027 00003E06 C683[5F6D0000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
 15028                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
 15029                              <1> 	; 05/02/2014
 15030 00003E0D 3C01                <1> 	cmp	al, 1 ; SRUN
 15031 00003E0F 740F                <1> 	je	short sysexit_6
 15032                              <1> 	;cmp	al, 2
 15033                              <1> 		; cmp r2,$2 / is the parent waiting for 
 15034                              <1> 			  ; / this child to die
 15035                              <1> 	;jne	short sysexit_6	
 15036                              <1> 		; bne 2f / yes, notify parent not to wait any more
 15037                              <1> 	; 05/02/2014
 15038                              <1> 	; p.stat = 2 --> waiting
 15039                              <1> 	; p.stat = 4 --> sleeping
 15040 00003E11 C686[5F6D0000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
 15041                              <1> 	;dec	byte [esi+p.stat-1]
 15042                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
 15043 00003E18 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
 15044                              <1> 	; 
 15045                              <1> 	;mov	ebx, runq + 4
 15046                              <1> 		; mov $runq+4,r2 / on the runq
 15047 00003E1B E84B120000          <1> 	call	putlu
 15048                              <1> 		; jsr r0, putlu
 15049                              <1> sysexit_6: ; 2:
 15050                              <1> 	; 31/08/2015
 15051                              <1> 		; / the process dies
 15052 00003E20 C605[49700000]00    <1> 	mov	byte [u.uno], 0
 15053                              <1> 		; clrb u.uno / put zero as the process number, 
 15054                              <1> 	           ; / so "swap" will
 15055 00003E27 E871110000          <1> 	call	swap
 15056                              <1> 		; jsr r0,swap / overwrite process with another process
 15057                              <1> hlt_sys:
 15058                              <1> 	;sti ; 18/01/2014
 15059                              <1> hlts0:
 15060 00003E2C F4                  <1> 	hlt
 15061 00003E2D EBFD                <1> 	jmp	short hlts0
 15062                              <1> 		; 0 / and thereby kill it; halt?
 15063                              <1> 
 15064                              <1> 
 15065                              <1> syswait: ; < wait for a processs to die >
 15066                              <1> 	; 17/09/2015
 15067                              <1> 	; 02/09/2015
 15068                              <1> 	; 01/09/2015
 15069                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15070                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
 15071                              <1> 	;
 15072                              <1> 	; 'syswait' waits for a process die. 
 15073                              <1> 	; It works in following way:
 15074                              <1> 	;    1) From the parent process number, the parent's 
 15075                              <1> 	; 	process name is found. The p.ppid table of parent
 15076                              <1> 	;	names is then searched for this process name.
 15077                              <1> 	;	If a match occurs, r2 contains child's process
 15078                              <1> 	;	number. The child status is checked to see if it is
 15079                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
 15080                              <1> 	;	If it is, the child process is freed and it's name
 15081                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
 15082                              <1> 	;	If the child is not a zombie, nothing happens and
 15083                              <1> 	;	the search goes on through the p.ppid table until
 15084                              <1> 	;	all processes are checked or a zombie is found.
 15085                              <1> 	;    2) If no zombies are found, a check is made to see if
 15086                              <1> 	;	there are any children at all. If there are none,
 15087                              <1> 	;	an error return is made. If there are, the parent's
 15088                              <1> 	;	status is set to 2 (waiting for child to die),
 15089                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
 15090                              <1> 	;	is made to wait on the next process.
 15091                              <1> 	;
 15092                              <1> 	; Calling sequence:
 15093                              <1> 	;	?
 15094                              <1> 	; Arguments:
 15095                              <1> 	;	-
 15096                              <1> 	; Inputs: - 
 15097                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
 15098                              <1> 	; ...............................................................
 15099                              <1> 	;				
 15100                              <1> 	
 15101                              <1> ; / wait for a process to die
 15102                              <1> 
 15103                              <1> syswait_0:
 15104 00003E2F 0FB61D[49700000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 15105                              <1> 		; movb u.uno,r1 / put parents process number in r1
 15106 00003E36 D0E3                <1> 	shl	bl, 1
 15107                              <1> 	;shl	bx, 1
 15108                              <1> 		; asl r1 / x2 to get index into p.pid table
 15109 00003E38 668B83[CE6C0000]    <1> 	mov	ax, [ebx+p.pid-2]
 15110                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
 15111 00003E3F 31F6                <1> 	xor	esi, esi
 15112                              <1> 		; clr r2
 15113 00003E41 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
 15114                              <1> 	;xor 	cl, cl
 15115                              <1> 		; clr r3 / initialize reg 3
 15116                              <1> syswait_1: ; 1:
 15117 00003E43 6683C602            <1> 	add	si, 2
 15118                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
 15119                              <1> 			  ; / search table of parent processes 
 15120                              <1> 			  ; / for this process name
 15121 00003E47 663B86[EE6C0000]    <1> 	cmp	ax, [esi+p.ppid-2]
 15122                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
 15123                              <1> 			            ; / process number
 15124 00003E4E 7535                <1> 	jne	short syswait_3
 15125                              <1> 		;bne 3f / branch if no match of parent process name
 15126                              <1> 	;inc	cx
 15127 00003E50 FEC1                <1> 	inc	cl
 15128                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
 15129 00003E52 66D1EE              <1> 	shr	si, 1
 15130                              <1> 		; asr r2 / r2/2 to get index to p.stat table
 15131                              <1> 	; The possible states ('p.stat' values) of a process are:
 15132                              <1> 	;	0 = free or unused
 15133                              <1> 	;	1 = active
 15134                              <1> 	;	2 = waiting for a child process to die
 15135                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
 15136 00003E55 80BE[5F6D0000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
 15137                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
 15138 00003E5C 7524                <1> 	jne	short syswait_2
 15139                              <1> 		; bne 2f / no, skip it
 15140 00003E5E 88BE[5F6D0000]      <1> 	mov	[esi+p.stat-1], bh ; 0
 15141                              <1> 		; clrb p.stat-1(r2) / yes, free it
 15142 00003E64 66D1E6              <1> 	shl	si, 1
 15143                              <1> 		; asl r2 / r2x2 to get index into p.pid table
 15144 00003E67 0FB786[CE6C0000]    <1> 	movzx	eax, word [esi+p.pid-2]
 15145 00003E6E A3[F46F0000]        <1> 	mov	[u.r0], eax
 15146                              <1> 		; mov p.pid-2(r2),*u.r0 
 15147                              <1> 			      ; / put childs process name in (u.r0)
 15148                              <1> 	;
 15149                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
 15150                              <1> 	;
 15151                              <1> 	; Parent process ID -p.ppid- field (of the child process)
 15152                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
 15153                              <1> 	; system call loop from the application/program if it calls
 15154                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
 15155                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
 15156                              <1> 	;
 15157                              <1> 	; Note: syswait will return with error if there is not a
 15158                              <1> 	;       zombie or running process to wait.	
 15159                              <1> 	;
 15160 00003E73 6629C0              <1> 	sub	ax, ax
 15161 00003E76 668986[EE6C0000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
 15162 00003E7D E912FEFFFF          <1> 	jmp	sysret0 ; ax = 0
 15163                              <1> 	;
 15164                              <1> 	;jmp	sysret
 15165                              <1> 		; br sysret1 / return cause child is dead
 15166                              <1> syswait_2: ; 2:
 15167 00003E82 66D1E6              <1> 	shl	si, 1
 15168                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
 15169                              <1> syswait_3: ; 3:
 15170 00003E85 6683FE20            <1> 	cmp	si, nproc+nproc
 15171                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
 15172 00003E89 72B8                <1> 	jb	short syswait_1
 15173                              <1> 		; blt 1b / no, continue search
 15174                              <1> 	;and	cx, cx
 15175 00003E8B 20C9                <1> 	and	cl, cl
 15176                              <1> 		; tst r3 / one gets here if there are no children 
 15177                              <1> 		       ; / or children that are still active
 15178                              <1> 	; 30/10/2013
 15179 00003E8D 750B                <1> 	jnz	short syswait_4
 15180                              <1> 	;jz	error
 15181                              <1> 		; beq error1 / there are no children, error
 15182 00003E8F 890D[F46F0000]      <1> 	mov	[u.r0], ecx ; 0
 15183 00003E95 E9D8FDFFFF          <1> 	jmp	error
 15184                              <1> syswait_4:
 15185 00003E9A 8A1D[49700000]      <1> 	mov	bl, [u.uno]
 15186                              <1> 		; movb u.uno,r1 / there are children so put 
 15187                              <1> 			      ; / parent process number in r1
 15188 00003EA0 FE83[5F6D0000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
 15189                              <1> 		; incb p.stat-1(r1) / it is waiting for 
 15190                              <1> 				  ; / other children to die
 15191                              <1> 	; 04/11/2013
 15192 00003EA6 E8F2100000          <1> 	call	swap
 15193                              <1> 		; jsr r0,swap / swap it out, because it's waiting
 15194 00003EAB EB82                <1> 	jmp	syswait_0
 15195                              <1> 		; br syswait / wait on next process
 15196                              <1> 
 15197                              <1> sysfork: ; < create a new process >
 15198                              <1> 	; 18/09/2015
 15199                              <1> 	; 04/09/2015
 15200                              <1> 	; 02/09/2015
 15201                              <1> 	; 01/09/2015
 15202                              <1> 	; 28/08/2015
 15203                              <1> 	; 14/05/2015
 15204                              <1> 	; 10/05/2015
 15205                              <1> 	; 09/05/2015
 15206                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
 15207                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 15208                              <1> 	;
 15209                              <1> 	; 'sysfork' creates a new process. This process is referred
 15210                              <1> 	; to as the child process. This new process core image is
 15211                              <1> 	; a copy of that of the caller of 'sysfork'. The only
 15212                              <1> 	; distinction is the return location and the fact that (u.r0)
 15213                              <1> 	; in the old process (parent) contains the process id (p.pid)
 15214                              <1> 	; of the new process (child). This id is used by 'syswait'.
 15215                              <1> 	; 'sysfork' works in the following manner: 	
 15216                              <1> 	;    1) The process status table (p.stat) is searched to find
 15217                              <1> 	;	a process number that is unused. If none are found
 15218                              <1> 	;	an error occurs.
 15219                              <1> 	;    2) when one is found, it becomes the child process number
 15220                              <1> 	;	and it's status (p.stat) is set to active.
 15221                              <1> 	;    3) If the parent had a control tty, the interrupt 
 15222                              <1> 	;	character in that tty buffer is cleared.
 15223                              <1> 	;    4) The child process is put on the lowest priority run 
 15224                              <1> 	;	queue via 'putlu'.
 15225                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
 15226                              <1> 	;	it is a unique number) and is put in the child's unique
 15227                              <1> 	;	identifier; process id (p.pid).
 15228                              <1> 	;    6) The process name of the parent is then obtained and
 15229                              <1> 	;	placed in the unique identifier of the parent process
 15230                              <1> 	;	name is then put in 'u.r0'.	
 15231                              <1> 	;    7) The child process is then written out on disk by
 15232                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
 15233                              <1> 	;	and the child is born. (The child process is written 
 15234                              <1> 	;	out on disk/drum with 'u.uno' being the child process
 15235                              <1> 	;	number.)
 15236                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
 15237                              <1> 	;    9) The child process name is put in 'u.r0'.
 15238                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
 15239                              <1> 	;	create the return address for the parent process.
 15240                              <1> 	;   11) The 'u.fp' list as then searched to see what files
 15241                              <1> 	;	the parent has opened. For each file the parent has
 15242                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
 15243                              <1> 	;	to indicate that the child process also has opened
 15244                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
 15245                              <1> 	;
 15246                              <1> 	; Calling sequence:
 15247                              <1> 	;	from shell ?
 15248                              <1> 	; Arguments:
 15249                              <1> 	;	-
 15250                              <1> 	; Inputs: -
 15251                              <1> 	; Outputs: *u.r0 - child process name
 15252                              <1> 	; ...............................................................
 15253                              <1> 	;	
 15254                              <1> 	; Retro UNIX 8086 v1 modification: 
 15255                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
 15256                              <1> 	;	= process id of child a parent process returns
 15257                              <1> 	;	= process id of parent when a child process returns
 15258                              <1> 	;
 15259                              <1> 	;       In original UNIX v1, sysfork is called and returns as
 15260                              <1> 	;	in following manner: (with an example: c library, fork)
 15261                              <1> 	;	
 15262                              <1> 	;	1:
 15263                              <1> 	;		sys	fork
 15264                              <1> 	;			br 1f  / child process returns here
 15265                              <1> 	;		bes	2f     / parent process returns here
 15266                              <1> 	;		/ pid of new process in r0
 15267                              <1> 	;		rts	pc
 15268                              <1> 	;	2: / parent process condionally branches here
 15269                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
 15270                              <1> 	;		rts	pc
 15271                              <1> 	;
 15272                              <1> 	;	1: / child process brances here
 15273                              <1> 	;		clr	r0   / pid = 0 in child process
 15274                              <1> 	;		rts	pc
 15275                              <1> 	;
 15276                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
 15277                              <1> 	;		// pid = fork();
 15278                              <1> 	;		//
 15279                              <1> 	;		// pid == 0 in child process; 
 15280                              <1> 	;		// pid == -1 means error return
 15281                              <1> 	;		// in child, 
 15282                              <1> 	;		//	parents id is in par_uid if needed
 15283                              <1> 	;		
 15284                              <1> 	;		_fork:
 15285                              <1> 	;			mov	$.fork,eax
 15286                              <1> 	;			int	$0x30
 15287                              <1> 	;			jmp	1f
 15288                              <1> 	;			jnc	2f
 15289                              <1> 	;			jmp	cerror
 15290                              <1> 	;		1:
 15291                              <1> 	;			mov	eax,_par_uid
 15292                              <1> 	;			xor	eax,eax
 15293                              <1> 	;		2:
 15294                              <1> 	;			ret
 15295                              <1> 	;
 15296                              <1> 	;	In Retro UNIX 8086 v1,
 15297                              <1> 	;	'sysfork' returns in following manner:
 15298                              <1> 	;	
 15299                              <1> 	;		mov	ax, sys_fork
 15300                              <1> 	;		mov	bx, offset @f ; routine for child
 15301                              <1> 	;		int	20h
 15302                              <1> 	;		jc	error
 15303                              <1> 	;		
 15304                              <1> 	;	; Routine for parent process here (just after 'jc')
 15305                              <1> 	;		mov	word ptr [pid_of_child], ax
 15306                              <1> 	;		jmp	next_routine_for_parent	
 15307                              <1> 	;
 15308                              <1> 	;	@@: ; routine for child process here				
 15309                              <1> 	;		....	
 15310                              <1> 	;	NOTE: 'sysfork' returns to specified offset
 15311                              <1> 	;	       for child process by using BX input.
 15312                              <1> 	;	      (at first, parent process will return then 
 15313                              <1> 	;	      child process will return -after swapped in-
 15314                              <1> 	;	      'syswait' is needed in parent process
 15315                              <1> 	;	      if return from child process will be waited for.)
 15316                              <1> 	;	  				
 15317                              <1> 	
 15318                              <1> ; / create a new process
 15319                              <1> 	; EBX = return address for child process 
 15320                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
 15321 00003EAD 31F6                <1> 	xor 	esi, esi
 15322                              <1> 		; clr r1
 15323                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
 15324 00003EAF 46                  <1> 	inc	esi
 15325                              <1> 		; inc r1
 15326 00003EB0 80BE[5F6D0000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
 15327                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
 15328 00003EB7 760B                <1> 	jna	short sysfork_2	
 15329                              <1> 		; beq 1f / it's unused so branch
 15330 00003EB9 6683FE10            <1> 	cmp	si, nproc
 15331                              <1> 		; cmp r1,$nproc / all processes checked
 15332 00003EBD 72F0                <1> 	jb	short sysfork_1
 15333                              <1> 		; blt 1b / no, branch back
 15334                              <1> 	;
 15335                              <1> 	; Retro UNIX 8086 v1. modification:
 15336                              <1> 	;	Parent process returns from 'sysfork' to address 
 15337                              <1> 	;	which is just after 'sysfork' system call in parent
 15338                              <1> 	;	process. Child process returns to address which is put
 15339                              <1> 	;	in BX register by parent process for 'sysfork'. 
 15340                              <1> 	;
 15341                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
 15342                              <1> 		             ; / to old process return
 15343                              <1> 		; br error1 / no room for a new process
 15344 00003EBF E9AEFDFFFF          <1> 	jmp	error
 15345                              <1> sysfork_2: ; 1:
 15346 00003EC4 E860F0FFFF          <1> 	call	allocate_page
 15347 00003EC9 0F82A3FDFFFF        <1> 	jc	error
 15348 00003ECF 50                  <1> 	push	eax   ; UPAGE (user structure page) address
 15349                              <1> 	; Retro UNIX 386 v1 modification!
 15350 00003ED0 E84DF2FFFF          <1> 	call	duplicate_page_dir
 15351                              <1> 		; EAX = New page directory 
 15352 00003ED5 730B                <1> 	jnc	short sysfork_3
 15353 00003ED7 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15354 00003ED8 E814F2FFFF          <1> 	call 	deallocate_page
 15355 00003EDD E990FDFFFF          <1> 	jmp	error
 15356                              <1> sysfork_3:
 15357                              <1> 	; Retro UNIX 386 v1 modification !
 15358 00003EE2 56                  <1> 	push	esi
 15359 00003EE3 E82D110000          <1> 	call	wswap ; save current user (u) structure, user registers
 15360                              <1> 		      ; and interrupt return components (for IRET)
 15361 00003EE8 8705[58700000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
 15362 00003EEE A3[5C700000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
 15363 00003EF3 5E                  <1> 	pop	esi
 15364 00003EF4 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15365                              <1> 		; [u.usp] = esp
 15366 00003EF5 89F7                <1> 	mov	edi, esi
 15367 00003EF7 66C1E702            <1> 	shl	di, 2
 15368 00003EFB 8987[6C6D0000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
 15369 00003F01 A3[54700000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
 15370                              <1> 	; 28/08/2015
 15371 00003F06 0FB605[49700000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
 15372                              <1> 		; movb u.uno,-(sp) / save parent process number
 15373 00003F0D 89C7                <1> 	mov	edi, eax
 15374 00003F0F 50                  <1>         push	eax ; ** 
 15375 00003F10 8A87[2F6D0000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
 15376                              <1> 	; 18/09/2015
 15377                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
 15378                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
 15379 00003F16 668986[2F6D0000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
 15380                              <1> 				   ; ah - reset child's wait channel	
 15381 00003F1D 89F0                <1> 	mov	eax, esi
 15382 00003F1F A2[49700000]        <1> 	mov	[u.uno], al ; child process number
 15383                              <1> 		;movb r1,u.uno / set child process number to r1
 15384 00003F24 FE86[5F6D0000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
 15385                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
 15386                              <1> 				; / process to active status
 15387                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
 15388                              <1> 			      ; / control tty buffer in r2
 15389                              <1>                 ; beq 2f / branch, if no such tty assigned
 15390                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
 15391                              <1> 	; 2:
 15392 00003F2A 53                  <1> 	push	ebx  ; * return address for the child process
 15393                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15394                              <1> 	; (Retro UNIX 8086 v1 modification!)
 15395                              <1> 		; mov $runq+4,r2
 15396 00003F2B E83B110000          <1> 	call	putlu 
 15397                              <1>  		; jsr r0,putlu / put child process on lowest priority 
 15398                              <1> 			   ; / run queue
 15399 00003F30 66D1E6              <1> 	shl	si, 1
 15400                              <1> 		; asl r1 / multiply r1 by 2 to get index 
 15401                              <1> 		       ; / into p.pid table
 15402 00003F33 66FF05[DA6F0000]    <1> 	inc	word [mpid]
 15403                              <1> 		; inc mpid / increment m.pid; get a new process name
 15404 00003F3A 66A1[DA6F0000]      <1> 	mov	ax, [mpid]
 15405 00003F40 668986[CE6C0000]    <1> 	mov	[esi+p.pid-2], ax
 15406                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
 15407                              <1> 				    ; / in child process' name slot
 15408 00003F47 5A                  <1> 	pop	edx  ; * return address for the child process
 15409                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15410 00003F48 5B                  <1>   	pop	ebx  ; **
 15411                              <1> 	;mov	ebx, [esp] ; ** parent process number
 15412                              <1> 		; movb (sp),r2 / put parent process number in r2
 15413 00003F49 66D1E3              <1> 	shl 	bx, 1
 15414                              <1> 		;asl r2 / multiply by 2 to get index into below tables
 15415                              <1> 	;movzx eax, word [ebx+p.pid-2]
 15416 00003F4C 668B83[CE6C0000]    <1> 	mov	ax, [ebx+p.pid-2]
 15417                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
 15418                              <1> 				   ; / process
 15419 00003F53 668986[EE6C0000]    <1> 	mov	[esi+p.ppid-2], ax
 15420                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
 15421                              <1> 			  ; / in parent process slot for child
 15422 00003F5A A3[F46F0000]        <1> 	mov	[u.r0], eax	
 15423                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
 15424                              <1> 			     ; / at location where r0 was saved
 15425 00003F5F 8B2D[EC6F0000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
 15426 00003F65 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
 15427                              <1> 			   ; * return address for the child process
 15428                              <1> 		; mov $sysret1,-(sp) /
 15429                              <1> 		; mov sp,u.usp / contents of sp at the time when 
 15430                              <1> 			      ; / user is swapped out
 15431                              <1> 		; mov $sstack,sp / point sp to swapping stack space
 15432                              <1> 	; 04/09/2015 - 01/09/2015
 15433                              <1> 	; [u.usp] = esp
 15434 00003F68 68[923C0000]        <1> 	push	sysret ; ***
 15435 00003F6D 8925[F06F0000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
 15436                              <1> 			     ; (for child process)	
 15437 00003F73 31C0                <1> 	xor 	eax, eax
 15438 00003F75 66A3[2E700000]      <1> 	mov 	[u.ttyp], ax ; 0
 15439                              <1> 	;
 15440 00003F7B E895100000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
 15441                              <1> 		;jsr r0,wswap / put child process out on drum
 15442                              <1> 		;jsr r0,unpack / unpack user stack
 15443                              <1> 		;mov u.usp,sp / restore user stack pointer
 15444                              <1> 		; tst (sp)+ / bump stack pointer
 15445                              <1> 	; Retro UNIX 386 v1 modification !
 15446 00003F80 58                  <1> 	pop	eax ; ***
 15447 00003F81 66D1E3              <1> 	shl	bx, 1
 15448 00003F84 8B83[6C6D0000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
 15449 00003F8A E8AF100000          <1> 	call	rswap ; restore parent process 'u' structure, 
 15450                              <1> 		      ; registers and return address (for IRET)
 15451                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
 15452 00003F8F 0FB705[DA6F0000]    <1>         movzx   eax, word [mpid]
 15453 00003F96 A3[F46F0000]        <1> 	mov	[u.r0], eax
 15454                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
 15455                              <1> 			       ; / where r0 was saved
 15456                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
 15457                              <1> 			          ; / process return
 15458                              <1> 	;xor	ebx, ebx
 15459 00003F9B 31F6                <1> 	xor     esi, esi
 15460                              <1> 		;clr r1
 15461                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
 15462                              <1> 	      ; / opened by the parent process
 15463                              <1> 	; 01/09/2015
 15464                              <1> 	;xor	bh, bh
 15465                              <1> 	;mov 	bl, [esi+u.fp]
 15466 00003F9D 8A86[FE6F0000]      <1> 	mov 	al, [esi+u.fp]
 15467                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
 15468                              <1>         ;or      bl, bl
 15469 00003FA3 08C0                <1> 	or	al, al
 15470 00003FA5 740D                <1> 	jz	short sysfork_5	
 15471                              <1> 		; beq 2f / file has not been opened by parent, 
 15472                              <1> 		       ; / so branch
 15473 00003FA7 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
 15474 00003FA9 F6E4                <1> 	mul	ah
 15475                              <1> 	;movzx	ebx, ax
 15476 00003FAB 6689C3              <1> 	mov	bx, ax
 15477                              <1> 	;shl     bx, 3
 15478                              <1> 		; asl r2 / multiply by 8
 15479                              <1>        		; asl r2 / to get index into fsp table
 15480                              <1>        		; asl r2
 15481 00003FAE FE83[8E6C0000]      <1>   	inc     byte [ebx+fsp-2]
 15482                              <1> 		; incb fsp-2(r2) / increment number of processes
 15483                              <1> 			     ; / using file, because child will now be
 15484                              <1> 			     ; / using this file
 15485                              <1> sysfork_5: ; 2:
 15486 00003FB4 46                  <1>         inc     esi
 15487                              <1> 		; inc r1 / get next open file
 15488 00003FB5 6683FE0A            <1>         cmp     si, 10
 15489                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
 15490                              <1> 			  ; / can be opened
 15491 00003FB9 72E2                <1> 	jb	short sysfork_4	
 15492                              <1> 		; blt 1b / check next entry
 15493 00003FBB E9D2FCFFFF          <1> 	jmp	sysret
 15494                              <1> 		; br sysret1
 15495                              <1> 
 15496                              <1> sysread: ; < read from file >
 15497                              <1> 	; 13/05/2015
 15498                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15499                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15500                              <1> 	;
 15501                              <1> 	; 'sysread' is given a buffer to read into and the number of
 15502                              <1> 	; characters to be read. If finds the file from the file
 15503                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
 15504                              <1> 	; is returned from a successful open call (sysopen).
 15505                              <1> 	; The i-number of file is obtained via 'rw1' and the data
 15506                              <1> 	; is read into core via 'readi'.
 15507                              <1> 	;
 15508                              <1> 	; Calling sequence:
 15509                              <1> 	;	sysread; buffer; nchars
 15510                              <1> 	; Arguments:
 15511                              <1> 	;	buffer - location of contiguous bytes where 
 15512                              <1> 	;		 input will be placed.
 15513                              <1> 	;	nchars - number of bytes or characters to be read.
 15514                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15515                              <1> 	; Outputs: *u.r0 - number of bytes read.	
 15516                              <1> 	; ...............................................................
 15517                              <1> 	;				
 15518                              <1> 	; Retro UNIX 8086 v1 modification: 
 15519                              <1> 	;       'sysread' system call has three arguments; so,
 15520                              <1> 	;	* 1st argument, file descriptor is in BX register
 15521                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15522                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15523                              <1> 	;
 15524                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15525                              <1> 	;	to the user with number of bytes read. 
 15526                              <1> 	;
 15527 00003FC0 E83D000000          <1> 	call	rw1
 15528 00003FC5 0F82A7FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
 15529                              <1> 		; jsr r0,rw1 / get i-number of file to be read into r1
 15530 00003FCB F6C480              <1> 	test	ah, 80h
 15531                              <1> 		; tst r1 / negative i-number?
 15532 00003FCE 0F859EFCFFFF        <1> 	jnz	error
 15533                              <1> 		; ble error1 / yes, error 1 to read
 15534                              <1> 			   ; / it should be positive
 15535 00003FD4 E860170000          <1> 	call	readi
 15536                              <1> 		; jsr r0,readi / read data into core
 15537 00003FD9 EB18                <1> 	jmp	short rw0
 15538                              <1> 		; br 1f
 15539                              <1> syswrite: ; < write to file >
 15540                              <1> 	; 13/05/2015
 15541                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15542                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15543                              <1> 	;
 15544                              <1> 	; 'syswrite' is given a buffer to write onto an output file
 15545                              <1> 	; and the number of characters to write. If finds the file
 15546                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
 15547                              <1> 	; descriptor is returned from a successful open or create call
 15548                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
 15549                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
 15550                              <1> 	;
 15551                              <1> 	; Calling sequence:
 15552                              <1> 	;	syswrite; buffer; nchars
 15553                              <1> 	; Arguments:
 15554                              <1> 	;	buffer - location of contiguous bytes to be writtten.
 15555                              <1> 	;	nchars - number of characters to be written.
 15556                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15557                              <1> 	; Outputs: *u.r0 - number of bytes written.	
 15558                              <1> 	; ...............................................................
 15559                              <1> 	;				
 15560                              <1> 	; Retro UNIX 8086 v1 modification: 
 15561                              <1> 	;       'syswrite' system call has three arguments; so,
 15562                              <1> 	;	* 1st argument, file descriptor is in BX register
 15563                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15564                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15565                              <1> 	;
 15566                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15567                              <1> 	;	to the user with number of bytes written. 
 15568                              <1> 	;
 15569 00003FDB E822000000          <1> 	call	rw1
 15570 00003FE0 0F828CFCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
 15571                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
 15572 00003FE6 F6C480              <1>         test	ah, 80h
 15573                              <1> 		; tst r1 / positive i-number ?
 15574 00003FE9 744E                <1>         jz	short rw3 ; 13/05/2015
 15575                              <1> 	;jz	error
 15576                              <1> 		; bge error1 / yes, error 1 
 15577                              <1> 			   ; / negative i-number means write
 15578 00003FEB 66F7D8              <1>         neg	ax
 15579                              <1> 		; neg r1 / make it positive
 15580 00003FEE E856190000          <1> 	call	writei
 15581                              <1>         	; jsr r0,writei / write data
 15582                              <1> rw0: ; 1:
 15583 00003FF3 A1[24700000]        <1>         mov	eax, [u.nread]
 15584 00003FF8 A3[F46F0000]        <1> 	mov	[u.r0], eax
 15585                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
 15586                              <1> 				  ; / into (u.r0)
 15587 00003FFD E990FCFFFF          <1> 	jmp	sysret
 15588                              <1>         	; br sysret1
 15589                              <1> rw1:	
 15590                              <1> 	; 14/05/2015
 15591                              <1> 	; 13/05/2015
 15592                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15593                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
 15594                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
 15595                              <1> 	;
 15596                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
 15597                              <1> 				;(in the user's virtual memory space)
 15598                              <1> 	;mov	[u.count], edx 
 15599                              <1> 		; jsr r0,arg; u.base / get buffer pointer
 15600                              <1>         	; jsr r0,arg; u.count / get no. of characters
 15601                              <1> 	;;mov	eax, ebx ; file descriptor
 15602                              <1> 		; mov *u.r0,r1 / put file descriptor 
 15603                              <1> 		             ; / (index to u.fp table) in r1
 15604                              <1> 	; 13/05/2015
 15605 00004002 C705[F46F0000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
 15606 0000400A 0000                <1>
 15607                              <1> 	;
 15608                              <1> 	;; call	getf
 15609                              <1>         ; eBX = File descriptor
 15610 0000400C E8E80A0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
 15611                              <1> 		; jsr r0,getf / get i-number of the file in r1
 15612                              <1> 	; AX = I-number of the file ; negative i-number means write
 15613                              <1> 	; 13/05/2015
 15614 00004011 6683F801            <1> 	cmp 	ax, 1
 15615 00004015 7217                <1> 	jb	short rw2
 15616                              <1> 	;
 15617 00004017 890D[1C700000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
 15618                              <1> 				;(in the user's virtual memory space)
 15619 0000401D 8915[20700000]      <1> 	mov	[u.count], edx 
 15620                              <1> 	; 14/05/2015
 15621 00004023 C705[6A700000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
 15622 0000402B 0000                <1>
 15623 0000402D C3                  <1> 	retn
 15624                              <1>         	; rts r0
 15625                              <1> rw2:
 15626                              <1> 	; 13/05/2015
 15627 0000402E C705[6A700000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 15628 00004036 0000                <1>
 15629 00004038 C3                  <1> 	retn
 15630                              <1> rw3: 
 15631                              <1> 	; 13/05/2015
 15632 00004039 C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 15633 00004041 0000                <1>
 15634 00004043 F9                  <1> 	stc
 15635 00004044 C3                  <1> 	retn
 15636                              <1> 
 15637                              <1> sysopen: ;<open file>
 15638                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 15639                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15640                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
 15641                              <1> 	;
 15642                              <1> 	; 'sysopen' opens a file in following manner:
 15643                              <1> 	;    1) The second argument in a sysopen says whether to
 15644                              <1> 	;	open the file ro read (0) or write (>0).
 15645                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
 15646                              <1> 	;    3) The file is opened by 'iopen'.
 15647                              <1> 	;    4) Next housekeeping is performed on the fsp table
 15648                              <1> 	;	and the user's open file list - u.fp.
 15649                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
 15650                              <1> 	;	b) An entry for the file is created in the fsp table.
 15651                              <1> 	;	c) The number of this entry is put on u.fp list.
 15652                              <1> 	;	d) The file descriptor index to u.fp list is pointed
 15653                              <1> 	;	   to by u.r0.
 15654                              <1> 	;
 15655                              <1> 	; Calling sequence:
 15656                              <1> 	;	sysopen; name; mode
 15657                              <1> 	; Arguments:
 15658                              <1> 	;	name - file name or path name
 15659                              <1> 	;	mode - 0 to open for reading
 15660                              <1> 	;	       1 to open for writing
 15661                              <1> 	; Inputs: (arguments)
 15662                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
 15663                              <1> 	;		  is put into r0's location on the stack.	
 15664                              <1> 	; ...............................................................
 15665                              <1> 	;				
 15666                              <1> 	; Retro UNIX 8086 v1 modification: 
 15667                              <1> 	;       'sysopen' system call has two arguments; so,
 15668                              <1> 	;	* 1st argument, name is pointed to by BX register
 15669                              <1> 	;	* 2nd argument, mode is in CX register
 15670                              <1> 	;
 15671                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15672                              <1> 	;	to the user with the file descriptor/number 
 15673                              <1> 	;	(index to u.fp list).
 15674                              <1> 	;
 15675                              <1> 	;call	arg2
 15676                              <1> 	; * name - 'u.namep' points to address of file/path name
 15677                              <1> 	;          in the user's program segment ('u.segmnt')
 15678                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15679                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15680                              <1> 	;          which is on top of stack.
 15681                              <1> 	;
 15682                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
 15683                              <1> 	;
 15684                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
 15685                              <1> 
 15686 00004045 891D[10700000]      <1> 	mov	[u.namep], ebx
 15687 0000404B 6651                <1> 	push	cx
 15688 0000404D E8DE0A0000          <1> 	call	namei
 15689                              <1> 		; jsr r0,namei / i-number of file in r1
 15690                              <1>      	;and	ax, ax
 15691                              <1> 	;jz	error ; File not found
 15692 00004052 723B                <1> 	jc	short fnotfound ; 14/05/2015
 15693                              <1> 	;jc	error ; 27/05/2013
 15694                              <1> 		; br  error2 / file not found
 15695 00004054 665A                <1>    	pop	dx ; mode
 15696 00004056 6652                <1> 	push	dx
 15697                              <1> 	;or	dx, dx
 15698 00004058 08D2                <1> 	or	dl, dl
 15699                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
 15700                              <1> 		         ; / 0 means, open for read)
 15701 0000405A 7403                <1> 	jz	short sysopen_0
 15702                              <1> 		; beq 1f / yes, leave i-number positive
 15703                              <1> syscreat_0: ; 27/12/2015
 15704 0000405C 66F7D8              <1> 	neg	ax
 15705                              <1>         	; neg r1 / open for writing so make i-number negative
 15706                              <1> sysopen_0: ;1:
 15707 0000405F E8B31C0000          <1> 	call	iopen
 15708                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
 15709 00004064 665A                <1> 	pop	dx
 15710                              <1> 	;and	dx, dx
 15711 00004066 20D2                <1> 	and	dl, dl
 15712                              <1>         	; tst (sp)+ / pop the stack and test the mode
 15713 00004068 7403                <1> 	jz	short sysopen_2
 15714                              <1>         	; beq op1 / is open for read op1
 15715                              <1> sysopen_1: ;op0:
 15716 0000406A 66F7D8              <1> 	neg	ax
 15717                              <1>         	; neg r1 
 15718                              <1> 		     ;/ make i-number positive if open for writing [???]
 15719                              <1> 	;; NOTE: iopen always make i-number positive.
 15720                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
 15721                              <1> sysopen_2: ;op1:
 15722 0000406D 31F6                <1>         xor     esi, esi
 15723                              <1>         	; clr r2 / clear registers
 15724 0000406F 31DB                <1>         xor     ebx, ebx
 15725                              <1> 		; clr r3
 15726                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
 15727 00004071 389E[FE6F0000]      <1>         cmp     [esi+u.fp], bl ; 0
 15728                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
 15729 00004077 7625                <1>         jna      short sysopen_4
 15730                              <1> 		; beq 1f / if byte in list is 0 branch
 15731 00004079 46                  <1>         inc     esi
 15732                              <1> 		; inc r2 / bump r2 so next byte can be checked
 15733 0000407A 6683FE0A            <1>         cmp     si, 10
 15734                              <1> 		; cmp r2,$10. / reached end of list?
 15735 0000407E 72F1                <1> 	jb	short sysopen_3
 15736                              <1> 		; blt 1b / no, go back
 15737                              <1> toomanyf:
 15738                              <1> 	; 14/05/2015
 15739 00004080 C705[6A700000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
 15740 00004088 0000                <1>
 15741 0000408A E9E3FBFFFF          <1> 	jmp	error
 15742                              <1>         	; br error2 / yes, error (no files open)
 15743                              <1> fnotfound: 
 15744                              <1> 	; 14/05/2015
 15745 0000408F C705[6A700000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
 15746 00004097 0000                <1>
 15747 00004099 E9D4FBFFFF          <1> 	jmp	error
 15748                              <1> 
 15749                              <1> sysopen_4: ; 1:
 15750 0000409E 6683BB[906C0000]00  <1>         cmp     word [ebx+fsp], 0
 15751                              <1> 		; tst fsp(r3) / scan fsp entries
 15752 000040A6 7610                <1>         jna     short sysopen_5
 15753                              <1> 		; beq 1f / if 0 branch
 15754                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
 15755 000040A8 6683C30A            <1>         add     bx, 10 ; fsp structure size = 10 bytes/entry
 15756                              <1> 		; add $8.,r3 / add 8 to r3 
 15757                              <1> 			; / to bump it to next entry mfsp table
 15758                              <1> 	; 22/11/2021
 15759 000040AC 6681FB2003          <1> 	cmp	bx, NFILES*fp.size ; NFILES*16
 15760                              <1> 	;cmp	bx, nfiles*10
 15761                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
 15762 000040B1 72EB                <1> 	jb	short sysopen_4
 15763                              <1>        		; blt 1b / no, back
 15764 000040B3 E9BAFBFFFF          <1> 	jmp	error
 15765                              <1>         	; br error2 / yes, error
 15766                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
 15767 000040B8 668983[906C0000]    <1>         mov     [ebx+fsp], ax
 15768                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
 15769                              <1> 			; / into next available entry in fsp table,
 15770 000040BF 668B3D[D56F0000]    <1> 	mov	di, [cdev] ; word ? byte ?
 15771 000040C6 6689BB[926C0000]    <1>         mov     [ebx+fsp+2], di ; device number
 15772                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
 15773 000040CD 31FF                <1>         xor	edi, edi
 15774 000040CF 89BB[946C0000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
 15775                              <1> 		; clr fsp+4(r3)
 15776 000040D5 6689BB[986C0000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
 15777                              <1>        		; clr fsp+6(r3) / clear the next two words
 15778 000040DC 89D8                <1>   	mov	eax, ebx
 15779 000040DE B30A                <1> 	mov	bl, 10
 15780 000040E0 F6F3                <1> 	div	bl 
 15781                              <1> 		; asr r3
 15782                              <1> 		; asr r3 / divide by 8 
 15783                              <1> 		; asr r3 ; / to get number of the fsp entry-1
 15784 000040E2 FEC0                <1> 	inc	al
 15785                              <1>         	; inc r3 / add 1 to get fsp entry number
 15786 000040E4 8886[FE6F0000]      <1>         mov     [esi+u.fp], al
 15787                              <1> 		; movb r3,u.fp(r2) / move entry number into 
 15788                              <1> 			; / next available slot in u.fp list
 15789 000040EA 8935[F46F0000]      <1>         mov     [u.r0], esi
 15790                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
 15791                              <1> 			     ; / into r0 loc on stack
 15792 000040F0 E99DFBFFFF          <1>         jmp	sysret
 15793                              <1> 		; br sysret2
 15794                              <1> 
 15795                              <1> 	;
 15796                              <1> 	; 'fsp' table (10 bytes/entry)
 15797                              <1> 	; bit 15				   bit 0
 15798                              <1> 	; ---|-------------------------------------------
 15799                              <1> 	; r/w|		i-number of open file
 15800                              <1> 	; ---|-------------------------------------------
 15801                              <1> 	;		   device number
 15802                              <1> 	; -----------------------------------------------
 15803                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 15804                              <1> 	; -----------------------------------------------
 15805                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 15806                              <1> 	; ----------------------|------------------------
 15807                              <1> 	;  flag that says file 	| number of processes
 15808                              <1> 	;   has been deleted	| that have file open 
 15809                              <1> 	; ----------------------|------------------------
 15810                              <1> 	;
 15811                              <1> 
 15812                              <1> syscreat: ; < create file >
 15813                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
 15814                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15815                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
 15816                              <1> 	;
 15817                              <1> 	; 'syscreat' called with two arguments; name and mode.
 15818                              <1> 	; u.namep points to name of the file and mode is put
 15819                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
 15820                              <1> 	; If the file aready exists, it's mode and owner remain 
 15821                              <1> 	; unchanged, but it is truncated to zero length. If the file
 15822                              <1> 	; did not exist, an i-node is created with the new mode via
 15823                              <1> 	; 'maknod' whether or not the file already existed, it is
 15824                              <1> 	; open for writing. The fsp table is then searched for a free
 15825                              <1> 	; entry. When a free entry is found, proper data is placed
 15826                              <1> 	; in it and the number of this entry is put in the u.fp list.
 15827                              <1> 	; The index to the u.fp (also know as the file descriptor)
 15828                              <1> 	; is put in the user's r0. 			
 15829                              <1> 	;
 15830                              <1> 	; Calling sequence:
 15831                              <1> 	;	syscreate; name; mode
 15832                              <1> 	; Arguments:
 15833                              <1> 	;	name - name of the file to be created
 15834                              <1> 	;	mode - mode of the file to be created
 15835                              <1> 	; Inputs: (arguments)
 15836                              <1> 	; Outputs: *u.r0 - index to u.fp list 
 15837                              <1> 	;		   (the file descriptor of new file)
 15838                              <1> 	; ...............................................................
 15839                              <1> 	;				
 15840                              <1> 	; Retro UNIX 8086 v1 modification: 
 15841                              <1> 	;       'syscreate' system call has two arguments; so,
 15842                              <1> 	;	* 1st argument, name is pointed to by BX register
 15843                              <1> 	;	* 2nd argument, mode is in CX register
 15844                              <1> 	;
 15845                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15846                              <1> 	;	to the user with the file descriptor/number 
 15847                              <1> 	;	(index to u.fp list).
 15848                              <1> 	;
 15849                              <1> 	;call	arg2
 15850                              <1> 	; * name - 'u.namep' points to address of file/path name
 15851                              <1> 	;          in the user's program segment ('u.segmnt')
 15852                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15853                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15854                              <1> 	;          which is on top of stack.
 15855                              <1> 	;
 15856                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
 15857                              <1> 			    ; / on stack
 15858 000040F5 891D[10700000]      <1> 	mov	[u.namep], ebx ; file name address
 15859 000040FB 6651                <1> 	push	cx ; mode
 15860 000040FD E82E0A0000          <1> 	call 	namei        	
 15861                              <1> 		; jsr r0,namei / get the i-number
 15862                              <1>         ;and	ax, ax
 15863                              <1> 	;jz	short syscreat_1	       	
 15864 00004102 721E                <1> 	jc	short syscreat_1
 15865                              <1> 		; br  2f / if file doesn't exist 2f
 15866                              <1> 	; 27/12/2015
 15867 00004104 6683F829            <1> 	cmp	ax, 41 ; device inode ?
 15868 00004108 0F824EFFFFFF        <1>         jb      syscreat_0 ; yes
 15869                              <1> 	;
 15870 0000410E 66F7D8              <1> 	neg 	ax
 15871                              <1>         	; neg r1 / if file already exists make i-number 
 15872                              <1> 		       ; / negative (open for writing)
 15873 00004111 E8011C0000          <1> 	call	iopen
 15874                              <1>         	; jsr r0,iopen /
 15875 00004116 E873150000          <1> 	call	itrunc
 15876                              <1>         	; jsr r0,itrunc / truncate to 0 length
 15877 0000411B 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
 15878 0000411D E948FFFFFF          <1>         jmp     sysopen_1
 15879                              <1>         	; br op0
 15880                              <1> syscreat_1: ; 2: / file doesn't exist
 15881 00004122 6658                <1> 	pop	ax
 15882                              <1>         	; mov (sp)+,r1 / put the mode in r1
 15883 00004124 30E4                <1> 	xor	ah, ah	
 15884                              <1>         	; bic $!377,r1 / clear upper byte
 15885 00004126 E8D50C0000          <1> 	call 	maknod
 15886                              <1>         	; jsr r0,maknod / make an i-node for this file
 15887 0000412B 66A1[30700000]      <1> 	mov	ax, [u.dirbuf]
 15888                              <1>         	; mov u.dirbuf,r1 / put i-number 
 15889                              <1> 			        ; / for this new file in r1
 15890 00004131 E934FFFFFF          <1>         jmp     sysopen_1
 15891                              <1>         	; br op0 / open the file
 15892                              <1> 
 15893                              <1> sysmkdir: ; < make directory >
 15894                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15895                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 15896                              <1> 	;
 15897                              <1> 	; 'sysmkdir' creates an empty directory whose name is
 15898                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
 15899                              <1> 	; The special entries '.' and '..' are not present.
 15900                              <1> 	; Errors are indicated if the directory already exists or		
 15901                              <1> 	; user is not the super user. 
 15902                              <1> 	;
 15903                              <1> 	; Calling sequence:
 15904                              <1> 	;	sysmkdir; name; mode
 15905                              <1> 	; Arguments:
 15906                              <1> 	;	name - points to the name of the directory
 15907                              <1> 	;	mode - mode of the directory
 15908                              <1> 	; Inputs: (arguments)
 15909                              <1> 	; Outputs: -
 15910                              <1> 	;    (sets 'directory' flag to 1; 
 15911                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
 15912                              <1> 	; ...............................................................
 15913                              <1> 	;				
 15914                              <1> 	; Retro UNIX 8086 v1 modification: 
 15915                              <1> 	;       'sysmkdir' system call has two arguments; so,
 15916                              <1> 	;	* 1st argument, name is pointed to by BX register
 15917                              <1> 	;	* 2nd argument, mode is in CX register
 15918                              <1> 	;
 15919                              <1> 		
 15920                              <1> ; / make a directory
 15921                              <1> 
 15922                              <1> 	;call	arg2
 15923                              <1> 	; * name - 'u.namep' points to address of file/path name
 15924                              <1> 	;          in the user's program segment ('u.segmnt')
 15925                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15926                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15927                              <1> 	;          which is on top of stack.
 15928                              <1> 
 15929                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
 15930                              <1> 			    ; / on stack
 15931 00004136 891D[10700000]      <1> 	mov	[u.namep], ebx
 15932 0000413C 6651                <1> 	push	cx ; mode
 15933 0000413E E8ED090000          <1> 	call	namei
 15934                              <1>         	; jsr r0,namei / get the i-number
 15935                              <1>         	;     br .+4 / if file not found branch around error
 15936                              <1>         ;xor 	ax, ax
 15937                              <1> 	;jnz	error
 15938 00004143 731C                <1> 	jnc	short dir_exists ; 14/05/2015
 15939                              <1> 	;jnc	error	
 15940                              <1> 		; br  error2 / directory already exists (error)
 15941 00004145 803D[4A700000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 15942                              <1>         	;tstb u.uid / is user the super user
 15943 0000414C 7622                <1> 	jna	short dir_access_err ; 14/05/2015
 15944                              <1> 	;jna	error
 15945                              <1>         	;bne error2 / no, not allowed
 15946 0000414E 6658                <1> 	pop	ax
 15947                              <1>         	;mov (sp)+,r1 / put the mode in r1
 15948 00004150 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
 15949                              <1>         	;bic $!317,r1 / all but su and ex
 15950                              <1> 	;or	ax , 4000h ; 1011111111111111b
 15951 00004154 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
 15952                              <1>         	;bis $40000,r1 / directory flag
 15953 00004157 E8A40C0000          <1> 	call	maknod
 15954                              <1>         	;jsr r0,maknod / make the i-node for the directory
 15955 0000415C E931FBFFFF          <1> 	jmp	sysret
 15956                              <1>         	;br sysret2 /
 15957                              <1> dir_exists:
 15958                              <1> 	; 14/05/2015
 15959 00004161 C705[6A700000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
 15960 00004169 0000                <1>
 15961 0000416B E902FBFFFF          <1> 	jmp	error
 15962                              <1> dir_access_err:
 15963                              <1> 	; 14/05/2015
 15964 00004170 C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 15965 00004178 0000                <1>
 15966 0000417A E9F3FAFFFF          <1> 	jmp	error
 15967                              <1> 
 15968                              <1> sysclose: ;<close file>
 15969                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15970                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
 15971                              <1> 	;
 15972                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
 15973                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
 15974                              <1> 	; is put in r1 and 'fclose' is called.
 15975                              <1> 	;
 15976                              <1> 	; Calling sequence:
 15977                              <1> 	;	sysclose
 15978                              <1> 	; Arguments:
 15979                              <1> 	;	-  
 15980                              <1> 	; Inputs: *u.r0 - file descriptor
 15981                              <1> 	; Outputs: -
 15982                              <1> 	; ...............................................................
 15983                              <1> 	;				
 15984                              <1> 	; Retro UNIX 8086 v1 modification:
 15985                              <1> 	;	 The user/application program puts file descriptor
 15986                              <1> 	;        in BX register as 'sysclose' system call argument.
 15987                              <1> 	; 	 (argument transfer method 1)
 15988                              <1> 
 15989                              <1> 	; / close the file
 15990                              <1> 	
 15991 0000417F 89D8                <1> 	mov 	eax, ebx
 15992 00004181 E828090000          <1> 	call 	fclose
 15993                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
 15994                              <1> 		; jsr r0,fclose / close the file
 15995                              <1>                	; br error2 / unknown file descriptor
 15996                              <1> 		; br sysret2
 15997                              <1> 	; 14/05/2015
 15998 00004186 0F8306FBFFFF        <1> 	jnc	sysret
 15999 0000418C C705[6A700000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 16000 00004194 0000                <1>
 16001 00004196 E9D7FAFFFF          <1> 	jmp	error
 16002                              <1> 
 16003                              <1> sysemt:
 16004                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16005                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
 16006                              <1> 	;
 16007                              <1> 	; Retro UNIX 8086 v1 modification: 
 16008                              <1> 	;	'Enable Multi Tasking'  system call instead 
 16009                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
 16010                              <1> 	;
 16011                              <1> 	; Retro UNIX 8086 v1 feature only!
 16012                              <1> 	;	Using purpose: Kernel will start without time-out
 16013                              <1> 	;	(internal clock/timer) functionality.
 16014                              <1> 	;	Then etc/init will enable clock/timer for
 16015                              <1> 	;	multi tasking. (Then it will not be disabled again
 16016                              <1> 	;	except hardware reset/restart.)
 16017                              <1> 	;
 16018                              <1> 
 16019 0000419B 803D[4A700000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
 16020                              <1> 	;ja	error
 16021 000041A2 0F8771FBFFFF        <1> 	ja	badsys ; 14/05/2015
 16022                              <1> emt_0:
 16023 000041A8 FA                  <1> 	cli
 16024 000041A9 21DB                <1> 	and	ebx, ebx
 16025 000041AB 7410                <1> 	jz	short emt_2
 16026                              <1> 	; Enable multi tasking -time sharing-
 16027 000041AD B8[B4500000]        <1> 	mov	eax, clock
 16028                              <1> emt_1:
 16029 000041B2 A3[0B070000]        <1> 	mov	[x_timer], eax
 16030 000041B7 FB                  <1> 	sti
 16031 000041B8 E9D5FAFFFF          <1> 	jmp	sysret
 16032                              <1> emt_2:
 16033                              <1> 	; Disable multi tasking -time sharing-
 16034 000041BD B8[13070000]        <1> 	mov	eax, u_timer
 16035 000041C2 EBEE                <1> 	jmp	short emt_1
 16036                              <1> 
 16037                              <1> 	; Original UNIX v1 'sysemt' routine
 16038                              <1> ;sysemt:
 16039                              <1>         ;
 16040                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
 16041                              <1> 			 ; / in loc 30
 16042                              <1>         ;cmp    30,$core / was the argument a lower address 
 16043                              <1> 			; / than core
 16044                              <1>         ;blo    1f / yes, rtssym
 16045                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
 16046                              <1> 			; / and less than "ecore"
 16047                              <1>         ;blo    2f / yes, sysret2
 16048                              <1> ;1:
 16049                              <1>         ;mov    $rtssym,30
 16050                              <1> ;2:
 16051                              <1>         ;br     sysret2
 16052                              <1> 
 16053                              <1> sysilgins:
 16054                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16055                              <1> 	; 03/06/2013
 16056                              <1> 	; Retro UNIX 8086 v1 modification: 
 16057                              <1> 	;	not a valid system call ! (not in use)
 16058                              <1> 	;
 16059 000041C4 E950FBFFFF          <1> 	jmp	badsys
 16060                              <1> 	;jmp	error
 16061                              <1> 	;;jmp 	sysret
 16062                              <1> 
 16063                              <1> 	; Original UNIX v1 'sysemt' routine
 16064                              <1> ;sysilgins: / calculate proper illegal instruction trap address
 16065                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
 16066                              <1> 			  ;/ put it in loc 8.,
 16067                              <1>         ;cmp    10,$core / making it the illegal instruction 
 16068                              <1> 		       ; / trap address
 16069                              <1>         ;blo    1f / is the address a user core address?  
 16070                              <1> 		; / yes, go to 2f
 16071                              <1>         ;cmp    10,$ecore
 16072                              <1>         ;blo    2f
 16073                              <1> ;1:
 16074                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
 16075                              <1> 		    ; / instruction trap address for the system
 16076                              <1> ;2:
 16077                              <1>         ;br     sysret2 / return to the caller via 'sysret'
 16078                              <1> 
 16079                              <1> sysmdate: ; < change the modification time of a file >
 16080                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 16081                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16082                              <1> 	;
 16083                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
 16084                              <1> 	; file into core. The user is checked if he is the owner 
 16085                              <1> 	; or super user. If he is neither an error occurs.
 16086                              <1> 	; 'setimod' is then called to set the i-node modification
 16087                              <1> 	; byte and the modification time, but the modification time
 16088                              <1> 	; is overwritten by whatever get put on the stack during
 16089                              <1> 	; a 'systime' system call. This calls are restricted to
 16090                              <1> 	; the super user.		
 16091                              <1> 	;
 16092                              <1> 	; Calling sequence:
 16093                              <1> 	;	sysmdate; name
 16094                              <1> 	; Arguments:
 16095                              <1> 	;	name - points to the name of file
 16096                              <1> 	; Inputs: (arguments)
 16097                              <1> 	; Outputs: -
 16098                              <1> 	; ...............................................................
 16099                              <1> 	;				
 16100                              <1> 	; Retro UNIX 8086 v1 modification: 
 16101                              <1> 	;	 The user/application program puts address 
 16102                              <1> 	;	 of the file name in BX register 
 16103                              <1> 	;	 as 'sysmdate' system call argument.
 16104                              <1> 	;
 16105                              <1> ; / change the modification time of a file
 16106                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
 16107 000041C9 891D[10700000]      <1>         mov	[u.namep], ebx
 16108 000041CF E85C090000          <1> 	call	namei
 16109                              <1> 		; jsr r0,namei / get its i-number
 16110 000041D4 0F82B5FEFFFF        <1>         jc	fnotfound ; file not found !
 16111                              <1> 	;jc	error       
 16112                              <1> 		; br error2 / no, such file
 16113 000041DA E8FA120000          <1> 	call	iget
 16114                              <1> 		; jsr r0,iget / get i-node into core
 16115 000041DF A0[4A700000]        <1> 	mov	al, [u.uid]
 16116 000041E4 3A05[946C0000]      <1> 	cmp	al, [i.uid]
 16117                              <1>         	; cmpb u.uid,i.uid / is user same as owner
 16118 000041EA 7413                <1> 	je	short mdate_1
 16119                              <1>         	; beq 1f / yes
 16120 000041EC 20C0                <1> 	and	al, al
 16121                              <1> 		; tstb u.uid / no, is user the super user
 16122                              <1> 	;jnz	error
 16123                              <1> 		; bne error2 / no, error
 16124 000041EE 740F                <1> 	jz	short mdate_1
 16125 000041F0 C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 16126 000041F8 0000                <1>
 16127 000041FA E973FAFFFF          <1> 	jmp	error
 16128                              <1> mdate_1: ;1:
 16129 000041FF E868140000          <1> 	call	setimod
 16130                              <1>         	; jsr r0,setimod / fill in modification data,
 16131                              <1> 		               ; / time etc.
 16132 00004204 BE[406F0000]        <1> 	mov	esi, p_time
 16133 00004209 BF[C86C0000]        <1> 	mov	edi, i.mtim
 16134 0000420E A5                  <1> 	movsd
 16135                              <1> 		; mov 4(sp),i.mtim / move present time to
 16136                              <1>         	; mov 2(sp),i.mtim+2 / modification time
 16137 0000420F E97EFAFFFF          <1>         jmp	sysret
 16138                              <1> 		; br sysret2
 16139                              <1> 
 16140                              <1> sysstty: ; < set tty status and mode >
 16141                              <1> 	; 17/11/2015
 16142                              <1> 	; 12/11/2015
 16143                              <1> 	; 29/10/2015
 16144                              <1> 	; 17/10/2015
 16145                              <1> 	; 13/10/2015
 16146                              <1> 	; 29/06/2015
 16147                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
 16148                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 16149                              <1> 	;
 16150                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
 16151                              <1> 	; whose file descriptor is in (u.r0).
 16152                              <1> 	;
 16153                              <1> 	; Calling sequence:
 16154                              <1> 	;	sysstty; arg
 16155                              <1> 	; Arguments:
 16156                              <1> 	;	arg - address of 3 consequitive words that contain
 16157                              <1> 	;	      the source of status data	
 16158                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
 16159                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 16160                              <1> 	; ...............................................................
 16161                              <1> 	;	
 16162                              <1> 	; Retro UNIX 8086 v1 modification: 
 16163                              <1> 	;	'sysstty' system call will set the tty
 16164                              <1> 	;	(clear keyboard buffer and set cursor position)
 16165                              <1> 	;	 in following manner:
 16166                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
 16167                              <1> 	;
 16168                              <1> 	; Inputs:
 16169                              <1> 	;	BX = 0 --> means
 16170                              <1> 	;	   If CL = FFh
 16171                              <1> 	;	      set cursor position for console tty, only 
 16172                              <1> 	;	      CH will be ignored (char. will not be written)	
 16173                              <1> 	;	   If CH = 0 (CL < FFh)
 16174                              <1> 	;	      set console tty for (current) process
 16175                              <1> 	;	      CL = tty number (0 to 9)
 16176                              <1> 	;	      (If CH = 0, character will not be written)			
 16177                              <1> 	;          If CH > 0 (CL < FFh)	
 16178                              <1> 	;             CL = tty number (0 to 9)
 16179                              <1> 	;	      CH = character will be written
 16180                              <1> 	;	        at requested cursor position (in DX)	
 16181                              <1> 	;	   DX = cursor position for tty number 0 to 7.	
 16182                              <1>   	;		(only tty number 0 to 7) 
 16183                              <1> 	;          DL = communication parameters (for serial ports) 
 16184                              <1> 	;	        (only for COM1 and COM2 serial ports)
 16185                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
 16186                              <1> 	;			or set cursor position	
 16187                              <1> 	;	   DH = 0FFh -> DL is not valid
 16188                              <1> 	;		do not set serial port parameters 
 16189                              <1> 	;		or do not set cursor position
 16190                              <1> 	;
 16191                              <1> 	;	BX > 0 --> points to name of tty
 16192                              <1> 	;    	   CH > 0 -->
 16193                              <1> 	;		CH = character will be written in current 
 16194                              <1> 	;            	cursor position (for tty number from 0 to 7)
 16195                              <1> 	;	     	or character will be sent to serial port
 16196                              <1> 	;	     	(for tty number 8 or 9)
 16197                              <1> 	;		CL = color of the character if tty number < 8.
 16198                              <1> 	;    	   CH = 0 --> Do not write a character, 
 16199                              <1> 	;		set mode (tty 8 to 9) or 
 16200                              <1> 	;		set current cursor positions (tty 0 to 7) only. 
 16201                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
 16202                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
 16203                              <1> 	;		(DL is not valid)
 16204                              <1> 	;	   DL = communication parameters 
 16205                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
 16206                              <1> 	; Outputs:
 16207                              <1> 	;	cf = 0 -> OK
 16208                              <1> 	;	     AL = tty number (0 to 9)
 16209                              <1> 	;	     AH = line status if tty number is 8 or 9
 16210                              <1> 	;	     AH = process number (of the caller) 	
 16211                              <1> 	;	cf = 1 means error (requested tty is not ready)
 16212                              <1> 	;	     AH = FFh if the tty is locked 
 16213                              <1> 	;		  (owned by another process)
 16214                              <1> 	;	        = process number (of the caller) 
 16215                              <1> 	;		  (if < FFh and tty number < 8)
 16216                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 16217                              <1> 	;	     AH = line status if tty number is 8 or 9
 16218                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
 16219                              <1> 	;
 16220                              <1> 	; 27/06/2015 (32 bit modifications)
 16221                              <1> 	; 14/01/2014
 16222 00004214 31C0                <1> 	xor 	eax, eax
 16223 00004216 6648                <1> 	dec	ax ; 17/10/2015
 16224 00004218 A3[F46F0000]        <1> 	mov	[u.r0], eax ; 0FFFFh
 16225 0000421D 21DB                <1> 	and	ebx, ebx
 16226 0000421F 0F85CB000000        <1>         jnz     sysstty_6
 16227                              <1> ; set console tty
 16228                              <1> 	; 29/10/2015
 16229                              <1> 	; 17/01/2014 
 16230 00004225 80F909              <1> 	cmp	cl, 9
 16231 00004228 7613                <1> 	jna	short sysstty_0
 16232                              <1> 	; 17/11/2015
 16233 0000422A 80F9FF              <1> 	cmp	cl, 0FFh
 16234 0000422D 7202                <1> 	jb	short sysstty_13
 16235 0000422F 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
 16236                              <1> sysstty_13:
 16237 00004231 8A1D[49700000]      <1> 	mov	bl, [u.uno] ; process number
 16238 00004237 8A8B[2F6D0000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
 16239                              <1> sysstty_0:
 16240                              <1> 	; 29/06/2015
 16241 0000423D 6652                <1> 	push	dx
 16242 0000423F 6651                <1> 	push	cx
 16243 00004241 30D2                <1> 	xor 	dl, dl	; sysstty call sign
 16244 00004243 88C8                <1> 	mov	al, cl
 16245 00004245 A2[F46F0000]        <1> 	mov	[u.r0], al ; tyy number (0 to 9)
 16246 0000424A E8621B0000          <1> 	call	ottyp
 16247 0000424F 6659                <1> 	pop	cx
 16248 00004251 665A                <1> 	pop	dx
 16249                              <1> 	;
 16250 00004253 7257                <1> 	jc	short sysstty_pd_err
 16251                              <1> 	;
 16252 00004255 80F908              <1> 	cmp	cl, 8
 16253 00004258 7222                <1> 	jb	short sysstty_2
 16254                              <1> 	;
 16255 0000425A 80FEFF              <1> 	cmp	dh, 0FFh
 16256 0000425D 741D                <1> 	je	short sysstty_2
 16257                              <1> 		; set communication parameters for serial ports
 16258                              <1> 	; 29/10/2015
 16259 0000425F 88D4                <1> 	mov	ah, dl ; communication parameters
 16260                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
 16261                              <1> 		;			 THRE int + RDA int 
 16262                              <1> 		; ah = 23h = 00100011b = 9600 baud,
 16263                              <1> 		;			 THRE int + RDA int 
 16264 00004261 28C0                <1> 	sub	al, al ; 0
 16265                              <1> 	; 12/07/2014
 16266 00004263 80F909              <1> 	cmp	cl, 9
 16267 00004266 7202                <1> 	jb	short sysstty_1
 16268 00004268 FEC0                <1> 	inc	al
 16269                              <1> sysstty_1:
 16270 0000426A 6651                <1> 	push	cx
 16271                              <1> 	; 29/06/2015	
 16272 0000426C E8AFF4FFFF          <1> 	call 	sp_setp ; Set serial port communication parameters
 16273 00004271 66890D[F56F0000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
 16274                              <1> 			     ; Modem status (EAX bits 16 to 23)
 16275 00004278 6659                <1> 	pop	cx
 16276 0000427A 7265                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 16277                              <1> sysstty_2:
 16278                              <1> 	; 17/01/2014
 16279 0000427C 20ED                <1> 	and	ch, ch 	; set cursor position 
 16280                              <1> 			; or comm. parameters ONLY
 16281 0000427E 750D                <1> 	jnz	short sysstty_3
 16282 00004280 0FB61D[49700000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 16283 00004287 888B[2F6D0000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
 16284                              <1> sysstty_3:
 16285                              <1> 	; 16/01/2014
 16286 0000428D 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
 16287                              <1> 	; 17/11/2015
 16288 0000428F B507                <1> 	mov 	ch, 7  ; Default color (light gray)
 16289 00004291 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
 16290 00004293 0F86C5000000        <1>         jna     sysstty_9
 16291                              <1> sysstty_12:
 16292                              <1> 	;; BX = 0, CL = 8 or CL = 9
 16293                              <1> 	; (Set specified serial port as console tty port)
 16294                              <1> 	; CH = character to be written
 16295                              <1> 	; 15/04/2014
 16296                              <1> 	; CH = 0 --> initialization only
 16297                              <1> 	; AL = character
 16298                              <1> 	; 26/06/2014
 16299 00004299 880D[2D700000]      <1> 	mov	[u.ttyn], cl
 16300                              <1> 	; 12/07/2014
 16301 0000429F 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
 16302 000042A1 20C0                <1> 	and	al, al
 16303 000042A3 7416                <1> 	jz	short sysstty_4 ; al = ch = 0
 16304                              <1>  	; 04/07/2014
 16305 000042A5 E831210000          <1> 	call 	sndc
 16306                              <1> 	; 12/07/2014
 16307 000042AA EB1B                <1> 	jmp	short sysstty_5
 16308                              <1> sysstty_pd_err: ; 29/06/2015
 16309                              <1> 	; 'permission denied !' error
 16310 000042AC C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
 16311 000042B4 0000                <1>
 16312 000042B6 E9B7F9FFFF          <1> 	jmp	error
 16313                              <1> sysstty_4:
 16314                              <1> 	; 12/07/2014
 16315                              <1> 	;xchg 	ah, al	; al = 0 -> al = ah, ah = 0
 16316 000042BB 88E0                <1> 	mov	al, ah ; 29/06/2015
 16317 000042BD 2C08                <1> 	sub	al, 8
 16318                              <1> 	; 27/06/2015
 16319 000042BF E854F4FFFF          <1> 	call	sp_status ; get serial port status
 16320                              <1> 	; AL = Line status, AH = Modem status
 16321                              <1> 	; 12/11/2015
 16322 000042C4 3C80                <1> 	cmp	al, 80h
 16323 000042C6 F5                  <1> 	cmc
 16324                              <1> sysstty_5:
 16325 000042C7 66A3[F56F0000]      <1> 	mov	[u.r0+1], ax ; ah = line status
 16326                              <1> 		     ; EAX bits 16-23 = modem status	
 16327 000042CD 9C                  <1> 	pushf
 16328 000042CE 30D2                <1> 	xor	dl, dl ; sysstty call sign
 16329 000042D0 A0[2D700000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
 16330 000042D5 E8EA1B0000          <1> 	call	cttyp
 16331 000042DA 9D                  <1> 	popf
 16332 000042DB 0F83B1F9FFFF        <1> 	jnc	sysret	; time out error 
 16333                              <1> 
 16334                              <1> sysstty_tmout_err:
 16335 000042E1 C705[6A700000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
 16336 000042E9 0000                <1>
 16337 000042EB E982F9FFFF          <1> 	jmp	error
 16338                              <1> sysstty_6:
 16339 000042F0 6652                <1> 	push	dx
 16340 000042F2 6651                <1> 	push	cx
 16341 000042F4 891D[10700000]      <1> 	mov	[u.namep], ebx
 16342 000042FA E831080000          <1> 	call	namei
 16343 000042FF 6659                <1> 	pop	cx
 16344 00004301 665A                <1> 	pop	dx
 16345 00004303 720E                <1> 	jc	short sysstty_inv_dn
 16346                              <1> 	;
 16347 00004305 6683F813            <1> 	cmp	ax, 19  ; inode number of /dev/COM2
 16348 00004309 7708                <1> 	ja	short sysstty_inv_dn ; 27/06/2015
 16349                              <1> 	;
 16350 0000430B 3C0A                <1> 	cmp	al, 10 ; /dev/tty0 .. /dev/tty7
 16351                              <1> 		       ; /dev/COM1, /dev/COM2
 16352 0000430D 7213                <1> 	jb	short sysstty_7
 16353 0000430F 2C0A                <1> 	sub	al, 10
 16354 00004311 EB20                <1> 	jmp	short sysstty_8
 16355                              <1> sysstty_inv_dn: 
 16356                              <1> 	; 27/06/2015
 16357                              <1> 	; Invalid device name (not a tty) ! error
 16358                              <1> 	; (Device is not a tty or device name not found)
 16359 00004313 C705[6A700000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 16360 0000431B 0000                <1>
 16361 0000431D E950F9FFFF          <1> 	jmp	error 
 16362                              <1> sysstty_7:
 16363 00004322 3C01                <1> 	cmp	al, 1 ; /dev/tty
 16364 00004324 75ED                <1> 	jne	short sysstty_inv_dn ; 27/06/2015
 16365 00004326 0FB61D[49700000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 16366 0000432D 8A83[2F6D0000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
 16367                              <1> sysstty_8:	
 16368 00004333 A2[F46F0000]        <1> 	mov	[u.r0], al
 16369 00004338 6652                <1> 	push	dx
 16370 0000433A 6650                <1> 	push	ax
 16371 0000433C 6651                <1> 	push	cx	
 16372 0000433E E86E1A0000          <1> 	call	ottyp
 16373 00004343 6659                <1> 	pop	cx
 16374 00004345 6658                <1> 	pop	ax
 16375 00004347 665A                <1> 	pop	dx
 16376 00004349 0F825DFFFFFF        <1>         jc      sysstty_pd_err ; 'permission denied !'
 16377                              <1> 	; 29/10/2015
 16378 0000434F 86E9                <1> 	xchg 	ch, cl
 16379                              <1> 		; cl = character, ch = color code
 16380 00004351 86C1                <1> 	xchg	al, cl
 16381                              <1> 		; al = character, cl = tty number
 16382 00004353 80F907              <1> 	cmp	cl, 7
 16383 00004356 0F873DFFFFFF        <1>         ja      sysstty_12
 16384                              <1> 	;
 16385                              <1> 	; 16/01/2014
 16386 0000435C 30FF                <1> 	xor	bh, bh
 16387                              <1> 	;
 16388                              <1> sysstty_9: 	; tty 0 to tty 7
 16389                              <1> 	; al = character
 16390 0000435E 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
 16391 00004361 740F                <1> 	je	short sysstty_10
 16392 00004363 6651                <1> 	push	cx
 16393 00004365 6650                <1> 	push	ax	
 16394                              <1> 	; movzx, ebx, cl
 16395 00004367 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
 16396 00004369 E8C3D1FFFF          <1> 	call	set_cpos
 16397 0000436E 6658                <1> 	pop	ax
 16398 00004370 6659                <1> 	pop	cx
 16399                              <1> sysstty_10: 
 16400                              <1> 	; 29/10/2015
 16401 00004372 08C0                <1> 	or	al, al ; character
 16402 00004374 740F                <1> 	jz      short sysstty_11 ; al = 0
 16403                              <1> 	; 17/11/2015
 16404 00004376 3CFF                <1> 	cmp	al, 0FFh
 16405 00004378 730B                <1> 	jnb	short sysstty_11
 16406                              <1> 		; ch > 0 and ch < FFh
 16407                              <1> 	; write a character at current cursor position
 16408 0000437A 88EC                <1> 	mov	ah, ch ; color/attribute
 16409                              <1> 	; 12/07/2014
 16410 0000437C 6651                <1> 	push	cx
 16411 0000437E E8F7D2FFFF          <1> 	call	write_c_current
 16412 00004383 6659                <1> 	pop	cx
 16413                              <1> sysstty_11:
 16414                              <1> 	; 14/01/2014
 16415 00004385 30D2                <1> 	xor	dl, dl ; sysstty call sign
 16416                              <1> 	; 18/01/2014
 16417                              <1> 	;movzx	eax, cl ; 27/06/2015
 16418 00004387 88C8                <1> 	mov	al, cl
 16419 00004389 E8361B0000          <1> 	call	cttyp
 16420 0000438E E9FFF8FFFF          <1> 	jmp	sysret
 16421                              <1> 
 16422                              <1> ; Original UNIX v1 'sysstty' routine:
 16423                              <1> ; gtty:
 16424                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
 16425                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
 16426                              <1> 	; 		/ r2 has source
 16427                              <1>         ;mov    r2,-(sp)
 16428                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
 16429                              <1> ;1: / flush the clist wait till typewriter is quiescent
 16430                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
 16431                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
 16432                              <1>         ;mov    $240,*$ps / set processor priority to 5
 16433                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
 16434                              <1>         ;       br .+4 / list empty, skip branch
 16435                              <1>         ;br     1b / get another character until list is empty
 16436                              <1>         ;mov    0b,r1 / move cc offset to r1
 16437                              <1>         ;inc    r1 / bump it for output clist
 16438                              <1>         ;tstb   cc(r1) / is it 0
 16439                              <1>         ;beq    1f / yes, no characters to output
 16440                              <1>  	;mov    r1,0f / no, put offset in sleep arg
 16441                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
 16442                              <1>         ;br     1b / try to calm it down again
 16443                              <1> ;1:
 16444                              <1>         ;mov    (sp)+,r1
 16445                              <1>         ;mov    (sp)+,r2 / restore registers
 16446                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
 16447                              <1>         ;beq    1f / if 0, 1f
 16448                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
 16449                              <1>         ;                   / control status register
 16450                              <1> ;1:
 16451                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
 16452                              <1>         ;beq    1f / if 0 1f
 16453                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
 16454                              <1> 	;		    / control status reg
 16455                              <1> ;1:
 16456                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
 16457                              <1>         ;jmp     sysret2 / return to user
 16458                              <1> 
 16459                              <1> sysgtty: ; < get tty status >
 16460                              <1> 	; 23/11/2015
 16461                              <1> 	; 29/10/2015
 16462                              <1> 	; 17/10/2015
 16463                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
 16464                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 16465                              <1> 	;
 16466                              <1> 	; 'sysgtty' gets the status of tty in question. 
 16467                              <1> 	; It stores in the three words addressed by it's argument
 16468                              <1> 	; the status of the typewriter whose file descriptor
 16469                              <1> 	; in (u.r0).
 16470                              <1> 	;
 16471                              <1> 	; Calling sequence:
 16472                              <1> 	;	sysgtty; arg
 16473                              <1> 	; Arguments:
 16474                              <1> 	;	arg - address of 3 words destination of the status
 16475                              <1> 	; Inputs: ((*u.r0 - file descriptor))
 16476                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 16477                              <1> 	; ...............................................................
 16478                              <1> 	;	
 16479                              <1> 	; Retro UNIX 8086 v1 modification: 
 16480                              <1> 	;	'sysgtty' system call will return status of tty
 16481                              <1> 	;	(keyboard, serial port and video page status)
 16482                              <1> 	;	 in following manner:
 16483                              <1> 	;
 16484                              <1> 	; Inputs:
 16485                              <1> 	;	BX = 0 --> means 
 16486                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
 16487                              <1> 	;	                 for (current) process
 16488                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
 16489                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
 16490                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
 16491                              <1> 	;	     CH > 0 -->	tty number + 1
 16492                              <1> 	;
 16493                              <1> 	;	BX > 0 --> points to name of tty
 16494                              <1> 	;	     CL = 0 --> return keyboard status
 16495                              <1> 	;	     CL = 1 --> return video page status
 16496                              <1> 	;	     CH = undefined		 
 16497                              <1> 	;
 16498                              <1> 	; Outputs:
 16499                              <1> 	;	cf = 0 ->
 16500                              <1> 	;
 16501                              <1> 	;	     AL = tty number from 0 to 9
 16502                              <1> 	;		  (0 to 7 is also the video page of the tty)	
 16503                              <1> 	;	     AH = 0 if the tty is free/unused
 16504                              <1> 	;	     AH = the process number of the caller 
 16505                              <1>  	;	     AH = FFh if the tty is locked by another process
 16506                              <1> 	;
 16507                              <1> 	;	  (if calling is for serial port status)
 16508                              <1> 	;	     BX = serial port status if tty number is 8 or 9
 16509                              <1> 	;		  (BH = modem status, BL = Line status)
 16510                              <1> 	;	     CX = 0FFFFh (if data is ready)
 16511                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
 16512                              <1> 	;
 16513                              <1> 	;	  (if calling is for keyboard status)
 16514                              <1> 	;	     BX = current character in tty/keyboard buffer
 16515                              <1> 	;		  (BH = scan code, BL = ascii code)
 16516                              <1> 	;		  (BX=0 if there is not a waiting character)
 16517                              <1> 	;	     CX  is undefined
 16518                              <1> 	;
 16519                              <1> 	;	  (if calling is for video page status)	
 16520                              <1> 	;	     BX = cursor position on the video page
 16521                              <1> 	;		  if tty number < 8
 16522                              <1> 	;		  (BH = row, BL = column)
 16523                              <1> 	;	     CX = current character (in cursor position)
 16524                              <1> 	;		  on the video page of the tty 
 16525                              <1> 	;		  if tty number < 8
 16526                              <1> 	;		  (CH = color, CL = character)
 16527                              <1> 	;	
 16528                              <1> 	;	cf = 1 means error (requested tty is not ready)
 16529                              <1> 	;
 16530                              <1> 	;	     AH = FFh if the caller is not owner of
 16531                              <1> 	;		  specified tty or console tty
 16532                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 16533                              <1> 	;	     BX, CX are undefined if cf = 1
 16534                              <1> 	;
 16535                              <1> 	;	  (If tty number is 8 or 9)
 16536                              <1> 	;	     AL = tty number 
 16537                              <1> 	;	     AH = the process number of the caller 
 16538                              <1> 	;	     BX = serial port status
 16539                              <1> 	;  		 (BH = modem status, BL = Line status)
 16540                              <1> 	;	     CX = 0
 16541                              <1> 	;
 16542                              <1> 		
 16543                              <1> gtty:   ; get (requested) tty number
 16544                              <1> 	; 17/10/2015
 16545                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 16546                              <1> 	; 30/05/2013 - 12/07/2014
 16547                              <1> 	; Retro UNIX 8086 v1 modification ! 
 16548                              <1> 	;
 16549                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
 16550                              <1> 	;
 16551                              <1> 	; 28/06/2015 (32 bit modifications)
 16552                              <1> 	; 16/01/2014
 16553 00004393 31C0                <1> 	xor 	eax, eax
 16554 00004395 6648                <1> 	dec	ax ; 17/10/2015
 16555 00004397 A3[F46F0000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
 16556 0000439C 80F901              <1> 	cmp	cl, 1
 16557 0000439F 760F                <1> 	jna	short sysgtty_0
 16558                              <1> sysgtty_invp:
 16559                              <1> 	; 28/06/2015
 16560 000043A1 C705[6A700000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 16561 000043A9 0000                <1>
 16562 000043AB E9C2F8FFFF          <1> 	jmp	error
 16563                              <1> sysgtty_0:	
 16564 000043B0 21DB                <1> 	and	ebx, ebx
 16565 000043B2 7430                <1> 	jz	short sysgtty_1
 16566                              <1> 	;
 16567 000043B4 891D[10700000]      <1> 	mov	[u.namep], ebx
 16568 000043BA 6651                <1> 	push	cx ; 23/11/2015
 16569 000043BC E86F070000          <1> 	call	namei
 16570 000043C1 6659                <1> 	pop	cx ; 23/11/2015
 16571 000043C3 7210                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
 16572                              <1> 	;
 16573 000043C5 6683F801            <1> 	cmp	ax, 1
 16574 000043C9 7622                <1> 	jna	short sysgtty_2
 16575 000043CB 6683E80A            <1> 	sub	ax, 10
 16576 000043CF 6683F809            <1> 	cmp	ax, 9
 16577                              <1> 	;ja	short sysgtty_inv_dn
 16578                              <1> 	;mov	ch, al
 16579                              <1> 	;jmp	short sysgtty_4
 16580                              <1> 	; 23/11/2015
 16581 000043D3 7629                <1> 	jna	short sysgtty_4
 16582                              <1> sysgtty_inv_dn: 
 16583                              <1> 	; 28/06/2015
 16584                              <1> 	; Invalid device name (not a tty) ! error
 16585                              <1> 	; (Device is not a tty or device name not found)
 16586 000043D5 C705[6A700000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 16587 000043DD 0000                <1>
 16588 000043DF E98EF8FFFF          <1> 	jmp	error 
 16589                              <1> sysgtty_1:
 16590                              <1> 	; 16/01/2014
 16591 000043E4 80FD0A              <1> 	cmp	ch, 10
 16592 000043E7 77B8                <1> 	ja	short sysgtty_invp ; 28/06/2015
 16593 000043E9 FECD                <1> 	dec	ch ; 0 -> FFh (negative)
 16594 000043EB 790F                <1> 	jns	short sysgtty_3 ; not negative
 16595                              <1> 	;
 16596                              <1> sysgtty_2:
 16597                              <1> 	; get tty number of console tty
 16598 000043ED 8A25[49700000]      <1> 	mov	ah, [u.uno]
 16599                              <1>  	; 28/06/2015
 16600 000043F3 0FB6DC              <1> 	movzx 	ebx, ah
 16601 000043F6 8AAB[2F6D0000]      <1> 	mov	ch, [ebx+p.ttyc-1]
 16602                              <1> sysgtty_3:
 16603 000043FC 88E8                <1> 	mov	al, ch
 16604                              <1> sysgtty_4:
 16605 000043FE A2[F46F0000]        <1> 	mov	[u.r0], al
 16606                              <1>  	; 28/06/2015
 16607                              <1> 	;cmp	al, 9
 16608                              <1> 	;ja	short sysgtty_invp
 16609 00004403 8B2D[F06F0000]      <1> 	mov	ebp, [u.usp]
 16610                              <1> 	; 23/11/2015
 16611 00004409 20C9                <1> 	and	cl, cl
 16612 0000440B 7436                <1> 	jz	short sysgtty_6 ; keyboard status
 16613 0000440D 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
 16614 0000440F 7232                <1> 	jb	short sysgtty_6 ; video page status
 16615                              <1> 	; serial port status
 16616                              <1> 	; 12/07/2014
 16617                              <1> 	;mov	dx, 0
 16618                              <1> 	;je	short sysgtty_5
 16619                              <1> 	;inc	dl
 16620                              <1> ;sysgtty_5:
 16621                              <1> 	; 28/06/2015
 16622 00004411 2C08                <1> 	sub	al, 8
 16623 00004413 E800F3FFFF          <1> 	call	sp_status ; serial (COM) port (line) status
 16624                              <1> 	; AL = Line status, AH = Modem status
 16625 00004418 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
 16626 0000441C 8A25[49700000]      <1> 	mov	ah, [u.uno]
 16627 00004422 8825[F56F0000]      <1>         mov     [u.r0+1], ah
 16628 00004428 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)	
 16629                              <1> 				; (in ECX)
 16630 0000442E A880                <1> 	test	al, 80h
 16631 00004430 7565                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
 16632 00004432 A801                <1> 	test	al, 1
 16633 00004434 0F8458F8FFFF        <1> 	jz	sysret
 16634 0000443A 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)	
 16635 0000443E E94FF8FFFF          <1> 	jmp	sysret
 16636                              <1> sysgtty_6:
 16637 00004443 A2[2D700000]        <1> 	mov	[u.ttyn], al ; tty number
 16638                              <1> 	;movzx	ebx, al
 16639 00004448 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
 16640 0000444A D0E3                <1> 	shl 	bl, 1  ; aligned to word
 16641                              <1> 	; 22/04/2014 - 29/06/2015
 16642 0000444C 81C3[446F0000]      <1>         add     ebx, ttyl
 16643 00004452 8A23                <1>  	mov	ah, [ebx]
 16644 00004454 3A25[49700000]      <1> 	cmp	ah, [u.uno]
 16645 0000445A 7404                <1> 	je	short sysgtty_7
 16646 0000445C 20E4                <1> 	and	ah, ah
 16647                              <1> 	;jz	short sysgtty_7
 16648 0000445E 7506                <1> 	jnz	short sysgtty_8
 16649                              <1> 	;mov	ah, 0FFh
 16650                              <1> sysgtty_7:
 16651 00004460 8825[F56F0000]      <1>         mov     [u.r0+1], ah
 16652                              <1> sysgtty_8:
 16653 00004466 08C9                <1> 	or	cl, cl
 16654 00004468 7510                <1> 	jnz	short sysgtty_9
 16655 0000446A B001                <1> 	mov	al, 1  ; test a key is available
 16656 0000446C E8FC1E0000          <1> 	call	getc
 16657 00004471 66894510            <1> 	mov	[ebp+16], ax ; bx, character
 16658 00004475 E918F8FFFF          <1> 	jmp	sysret
 16659                              <1> sysgtty_9:
 16660 0000447A 8A1D[2D700000]      <1> 	mov	bl, [u.ttyn]
 16661                              <1> 	; bl = video page number
 16662 00004480 E868200000          <1> 	call 	get_cpos
 16663                              <1> 	; dx = cursor position
 16664 00004485 66895510            <1> 	mov	[ebp+16], dx ; bx
 16665                              <1> 	;mov	bl, [u.ttyn]
 16666                              <1> 	; bl = video page number
 16667 00004489 E870200000          <1> 	call	read_ac_current
 16668                              <1> 	; ax = character and attribute/color
 16669 0000448E 66894518            <1> 	mov	[ebp+24], ax ; cx
 16670 00004492 E9FBF7FFFF          <1> 	jmp	sysret
 16671                              <1> sysgtty_dnr_err:
 16672                              <1> 	; 'device not responding !' error	
 16673                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
 16674 00004497 C705[6A700000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ;  25				
 16675 0000449F 0000                <1>
 16676 000044A1 E9CCF7FFFF          <1> 	jmp	error	
 16677                              <1> 
 16678                              <1> ; Original UNIX v1 'sysgtty' routine:
 16679                              <1> ; sysgtty:
 16680                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
 16681                              <1> 	;	       / r2 has destination
 16682                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
 16683                              <1> 	;                     / in 1st word of dest
 16684                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
 16685                              <1> 	;                     / in 2nd word of dest
 16686                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
 16687                              <1>         ;jmp    sysret2 / return to user
 16688                              <1> 	
 16689                              <1> ; Original UNIX v1 'gtty' routine:
 16690                              <1> ; gtty:
 16691                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
 16692                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
 16693                              <1>         ;jsr    r0,getf / get the i-number of the file
 16694                              <1>         ;tst    r1 / is it open for reading
 16695                              <1>         ;bgt    1f / yes
 16696                              <1>         ;neg    r1 / no, i-number is negative, 
 16697                              <1> 	;          / so make it positive
 16698                              <1> ;1:
 16699                              <1>         ;sub    $14.,r1 / get i-number of tty0
 16700                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
 16701                              <1>         ;bhis   error9 / no, error
 16702                              <1>         ;asl    r1 / 0%2
 16703                              <1>         ;asl    r1 / 0%4 / yes
 16704                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
 16705                              <1> 	;	       ; / tty block
 16706                              <1>         ;mov    u.off,r2 / put argument in r2
 16707                              <1>         ;rts    r0 / return
 16708                                  %include 'u2.s'        ; 11/05/2015
 16709                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 16710                              <1> ; (re-write kernel for test by using previous version without a major defect)
 16711                              <1> ; ****************************************************************************
 16712                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS2.INC
 16713                              <1> ; Last Modification: 30/11/2021
 16714                              <1> ; ----------------------------------------------------------------------------
 16715                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 16716                              <1> ; (v0.1 - Beginning: 11/07/2012)
 16717                              <1> ;
 16718                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 16719                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 16720                              <1> ; <Bell Laboratories (17/3/1972)>
 16721                              <1> ; <Preliminary Release of UNIX Implementation Document>
 16722                              <1> ;
 16723                              <1> ; Retro UNIX 8086 v1 - U2.ASM (24/03/2014) //// UNIX v1 -> u2.s
 16724                              <1> ;
 16725                              <1> ; ****************************************************************************
 16726                              <1> 
 16727                              <1> syslink:
 16728                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 16729                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 16730                              <1> 	;
 16731                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
 16732                              <1> 	; name 1 is a file that already exists. name 2 is the name
 16733                              <1> 	; given to the entry that will go in the current directory.
 16734                              <1> 	; name2 will then be a link to the name 1 file. The i-number
 16735                              <1> 	; in the name 2 entry of current directory is the same
 16736                              <1> 	; i-number for the name 1 file.
 16737                              <1> 	;
 16738                              <1> 	; Calling sequence:
 16739                              <1> 	;	syslink; name 1; name 2
 16740                              <1> 	; Arguments:
 16741                              <1> 	;	name 1 - file name to which link will be created.
 16742                              <1> 	;	name 2 - name of entry in current directory that
 16743                              <1> 	;		 links to name 1.
 16744                              <1> 	; Inputs: -
 16745                              <1> 	; Outputs: -
 16746                              <1> 	; ...............................................................
 16747                              <1> 	;	
 16748                              <1> 	; Retro UNIX 8086 v1 modification: 
 16749                              <1> 	;       'syslink' system call has two arguments; so,
 16750                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
 16751                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
 16752                              <1> 	;
 16753                              <1> 		; / name1, name2
 16754                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
 16755 000044A6 891D[10700000]      <1> 	mov	[u.namep], ebx
 16756 000044AC 51                  <1> 	push	ecx
 16757 000044AD E87E060000          <1> 	call	namei
 16758                              <1> 		; jsr r0,namei / find the i-number associated with
 16759                              <1> 			     ; / the 1st path name
 16760                              <1>      	;;and	ax, ax
 16761                              <1> 	;;jz	error ; File not found
 16762                              <1> 	;jc	error 
 16763                              <1> 		; br error9 / cannot be found
 16764 000044B2 730F                <1> 	jnc	short syslink0
 16765                              <1> 	;pop 	ecx
 16766                              <1> 	; 'file not found !' error
 16767 000044B4 C705[6A700000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 16768 000044BC 0000                <1>
 16769 000044BE E9AFF7FFFF          <1> 	jmp	error
 16770                              <1> syslink0:
 16771 000044C3 E811100000          <1> 	call	iget
 16772                              <1> 		; jsr r0,iget / get the i-node into core
 16773 000044C8 8F05[10700000]      <1> 	pop	dword [u.namep] ; ecx
 16774                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
 16775 000044CE 6650                <1> 	push	ax
 16776                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
 16777                              <1> 			    ; / (a link to this file is to be created)
 16778 000044D0 66FF35[D56F0000]    <1> 	push	word [cdev]
 16779                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
 16780 000044D7 E855000000          <1> 	call	isdir
 16781                              <1> 		; jsr r0,isdir / is it a directory
 16782 000044DC E84F060000          <1> 	call	namei
 16783                              <1> 		; jsr r0,namei / no, get i-number of name2
 16784                              <1> 	;jnc	error
 16785                              <1> 		; br .+4   / not found 
 16786                              <1> 			 ; / so r1 = i-number of current directory
 16787                              <1> 			 ; / ii = i-number of current directory
 16788                              <1> 		; br error9 / file already exists., error
 16789 000044E1 720F                <1> 	jc	short syslink1
 16790                              <1> 	; pop ax
 16791                              <1> 	; pop ax
 16792                              <1> 	; 'file exists !' error
 16793 000044E3 C705[6A700000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
 16794 000044EB 0000                <1>
 16795 000044ED E980F7FFFF          <1> 	jmp	error
 16796                              <1> syslink1:
 16797 000044F2 6659                <1> 	pop	cx
 16798                              <1> 	;cmp	cx, [cdev]
 16799 000044F4 3A0D[D56F0000]      <1> 	cmp	cl, [cdev]
 16800                              <1> 	;jne	error
 16801                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
 16802                              <1> 			       ; / end of current directory
 16803                              <1> 	        ; bne error9
 16804 000044FA 740F                <1> 	je	short syslink2
 16805                              <1> 	; 'not same drive !' error
 16806 000044FC C705[6A700000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
 16807 00004504 0000                <1>
 16808 00004506 E967F7FFFF          <1> 	jmp	error
 16809                              <1> syslink2:
 16810 0000450B 6658                <1> 	pop	ax
 16811 0000450D 6650                <1> 	push	ax
 16812 0000450F 66A3[30700000]      <1> 	mov	[u.dirbuf], ax
 16813                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
 16814 00004515 E8A8000000          <1> 	call	mkdir
 16815                              <1> 		; jsr r0,mkdir / make directory entry for name2 
 16816                              <1> 		 	     ; / in current directory
 16817 0000451A 6658                <1> 	pop	ax
 16818                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
 16819 0000451C E8B80F0000          <1> 	call	iget
 16820                              <1> 		; jsr r0,iget / get i-node into core
 16821 00004521 FE05[926C0000]      <1> 	inc	byte [i.nlks]
 16822                              <1> 		; incb i.nlks / add 1 to its number of links
 16823 00004527 E840110000          <1> 	call	setimod
 16824                              <1> 		; jsr r0,setimod / set the i-node modified flag
 16825 0000452C E961F7FFFF          <1> 	jmp	sysret
 16826                              <1> 
 16827                              <1> isdir:
 16828                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 16829                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16830                              <1> 	;
 16831                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
 16832                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
 16833                              <1> 	;  called by syslink and sysunlink to make sure directories
 16834                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
 16835                              <1> 	; 'isdir' does not bother checking. The current i-node
 16836                              <1> 	;  is not disturbed.			
 16837                              <1> 	;		
 16838                              <1> 	; INPUTS ->
 16839                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
 16840                              <1> 	;    u.uid - user id
 16841                              <1> 	; OUTPUTS ->
 16842                              <1> 	;    r1 - contains current i-number upon exit
 16843                              <1> 	;    	 (current i-node back in core) 
 16844                              <1> 	;	
 16845                              <1> 	; ((AX = R1))
 16846                              <1> 	;
 16847                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 16848                              <1> 	;
 16849                              <1> 
 16850                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
 16851                              <1> 	; / there is an error unless super user made the call
 16852                              <1> 	
 16853 00004531 803D[4A700000]00    <1> 	cmp	byte [u.uid], 0 
 16854                              <1> 		; tstb u.uid / super user
 16855 00004538 762D                <1> 	jna	short isdir1
 16856                              <1> 		; beq 1f / yes, don't care
 16857 0000453A 66FF35[D06F0000]    <1> 	push	word [ii]
 16858                              <1> 		; mov ii,-(sp) / put current i-number on stack
 16859 00004541 E8930F0000          <1> 	call	iget
 16860                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
 16861 00004546 66F705[906C0000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
 16862 0000454E 40                  <1>
 16863                              <1> 		; bit $40000,i.flgs / is it a directory
 16864                              <1> 	;jnz	error
 16865                              <1> 		; bne error9 / yes, error
 16866 0000454F 740F                <1> 	jz	short isdir0
 16867 00004551 C705[6A700000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
 16868 00004559 0000                <1>
 16869                              <1> 				; 'permission denied !' error
 16870                              <1> 	; pop	ax
 16871 0000455B E912F7FFFF          <1> 	jmp	error	
 16872                              <1> isdir0:	
 16873 00004560 6658                <1> 	pop	ax
 16874                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
 16875 00004562 E8720F0000          <1> 	call	iget
 16876                              <1> 		; jsr r0,iget / get it back in
 16877                              <1> isdir1: ; 1:
 16878 00004567 C3                  <1> 	retn
 16879                              <1> 		; rts r0
 16880                              <1> 
 16881                              <1> sysunlink:
 16882                              <1> 	; 04/12/2015 (14 byte file names)
 16883                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 16884                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 16885                              <1> 	;
 16886                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
 16887                              <1> 	; name from its directory. If this entry was the last link
 16888                              <1> 	; to the file, the contents of the file are freed and the
 16889                              <1> 	; file is destroyed. If, however, the file was open in any
 16890                              <1> 	; process, the actual destruction is delayed until it is 
 16891                              <1> 	; closed, even though the directory entry has disappeared.
 16892                              <1> 	; 
 16893                              <1> 	; The error bit (e-bit) is set to indicate that the file	
 16894                              <1> 	; does not exist or that its directory can not be written.
 16895                              <1> 	; Write permission is not required on the file itself.
 16896                              <1> 	; It is also illegal to unlink a directory (except for
 16897                              <1> 	; the superuser).
 16898                              <1> 	;
 16899                              <1> 	; Calling sequence:
 16900                              <1> 	;	sysunlink; name
 16901                              <1> 	; Arguments:
 16902                              <1> 	;	name - name of directory entry to be removed 
 16903                              <1> 	; Inputs: -
 16904                              <1> 	; Outputs: -
 16905                              <1> 	; ...............................................................
 16906                              <1> 	;				
 16907                              <1> 	; Retro UNIX 8086 v1 modification:
 16908                              <1> 	;	 The user/application program puts address of the name
 16909                              <1> 	;        in BX register as 'sysunlink' system call argument.
 16910                              <1> 
 16911                              <1> 	; / name - remove link name
 16912 00004568 891D[10700000]      <1> 	mov	[u.namep], ebx
 16913                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
 16914 0000456E E8BD050000          <1> 	call	namei
 16915                              <1> 		; jsr r0,namei / find the i-number associated 
 16916                              <1> 			     ; / with the path name
 16917                              <1> 	;jc	error
 16918                              <1> 		; br error9 / not found
 16919 00004573 730F                <1> 	jnc	short sysunlink1
 16920                              <1> 	; 'file not found !' error
 16921 00004575 C705[6A700000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 16922 0000457D 0000                <1>
 16923 0000457F E9EEF6FFFF          <1> 	jmp	error
 16924                              <1> sysunlink1:
 16925 00004584 6650                <1> 	push	ax
 16926                              <1> 		; mov r1,-(sp) / put its i-number on the stack
 16927 00004586 E8A6FFFFFF          <1> 	call	isdir
 16928                              <1> 		; jsr r0,isdir / is it a directory
 16929 0000458B 6631C0              <1> 	xor 	ax, ax
 16930 0000458E 66A3[30700000]      <1> 	mov	[u.dirbuf], ax ; 0
 16931                              <1> 		; clr u.dirbuf / no, clear the location that will
 16932                              <1> 			   ; / get written into the i-number portion
 16933                              <1> 			 ; / of the entry
 16934 00004594 832D[14700000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
 16935                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
 16936 0000459B E86E000000          <1> 	call	wdir
 16937                              <1> 		; jsr r0,wdir / free the directory entry
 16938 000045A0 6658                <1> 	pop	ax
 16939                              <1> 		; mov (sp)+,r1 / get i-number back
 16940 000045A2 E8320F0000          <1> 	call	iget
 16941                              <1> 		; jsr r0,iget / get i-node
 16942 000045A7 E8C0100000          <1> 	call	setimod
 16943                              <1> 		; jsr r0,setimod / set modified flag
 16944 000045AC FE0D[926C0000]      <1> 	dec	byte [i.nlks]
 16945                              <1> 		; decb i.nlks / decrement the number of links
 16946 000045B2 0F85DAF6FFFF        <1> 	jnz	sysret
 16947                              <1> 		; bgt sysret9 / if this was not the last link
 16948                              <1> 			    ; / to file return
 16949                              <1> 	; AX = r1 = i-number
 16950 000045B8 E895090000          <1> 	call	anyi
 16951                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
 16952                              <1> 			 ; / Then free contents of file and destroy it.
 16953 000045BD E9D0F6FFFF          <1> 	jmp	sysret
 16954                              <1> 		; br sysret9
 16955                              <1> 
 16956                              <1> mkdir:
 16957                              <1> 	; 04/12/2015 (14 byte directory names)
 16958                              <1> 	; 12/10/2015
 16959                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
 16960                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 16961                              <1> 	;
 16962                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
 16963                              <1> 	; by u.namep into the current directory.
 16964                              <1> 	;
 16965                              <1> 	; INPUTS ->
 16966                              <1> 	;    u.namep - points to a file name 
 16967                              <1> 	;	           that is about to be a directory entry.
 16968                              <1> 	;    ii - current directory's i-number.	
 16969                              <1> 	; OUTPUTS ->
 16970                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
 16971                              <1> 	;    u.off - points to entry to be filled 
 16972                              <1> 	;	     in the current directory		
 16973                              <1> 	;    u.base - points to start of u.dirbuf.
 16974                              <1> 	;    r1 - contains i-number of current directory 
 16975                              <1> 	;	
 16976                              <1> 	; ((AX = R1)) output
 16977                              <1> 	;
 16978                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
 16979                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 16980                              <1> 	;
 16981                              <1> 
 16982                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 16983 000045C2 31C0                <1> 	xor 	eax, eax
 16984 000045C4 BF[32700000]        <1> 	mov     edi, u.dirbuf+2
 16985 000045C9 89FE                <1> 	mov	esi, edi
 16986 000045CB AB                  <1> 	stosd
 16987 000045CC AB                  <1> 	stosd
 16988                              <1> 	; 04/12/2015 (14 byte directory names)
 16989 000045CD AB                  <1> 	stosd
 16990 000045CE 66AB                <1> 	stosw
 16991                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
 16992 000045D0 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
 16993                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 16994                              <1> 	;mov 	ebp, [u.namep]
 16995 000045D2 E87E060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 16996                              <1> 		; esi = physical address (page start + offset)
 16997                              <1> 		; ecx = byte count in the page (1 - 4096)
 16998                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 16999                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
 17000                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
 17001                              <1> mkdir_1: ; 1: 
 17002 000045D7 45                  <1> 	inc	ebp ; 12/10/2015
 17003                              <1> 	;
 17004                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
 17005                              <1> 	 ; 01/08/2013
 17006 000045D8 AC                  <1> 	lodsb
 17007                              <1> 		; movb (r2)+,r1 / move character in name to r1
 17008 000045D9 20C0                <1> 	and 	al, al
 17009 000045DB 7427                <1> 	jz 	short mkdir_3 	  
 17010                              <1> 		; beq 1f / if null, done
 17011 000045DD 3C2F                <1> 	cmp	al, '/'
 17012                              <1> 		; cmp r1,$'/ / is it a "/"?
 17013 000045DF 7414                <1> 	je	short mkdir_err
 17014                              <1> 	;je	error
 17015                              <1> 		; beq error9 / yes, error
 17016                              <1> 	; 12/10/2015
 17017 000045E1 6649                <1> 	dec	cx
 17018 000045E3 7505                <1> 	jnz	short mkdir_2
 17019                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 17020 000045E5 E871060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 17021                              <1> 		; esi = physical address (page start + offset)
 17022                              <1> 		; ecx = byte count in the page
 17023                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 17024                              <1> mkdir_2:
 17025 000045EA 81FF[40700000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
 17026                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
 17027                              <1> 				     ; / a char?
 17028 000045F0 74E5                <1> 	je	short mkdir_1
 17029                              <1> 		; beq 1b / yes, go back
 17030 000045F2 AA                  <1> 	stosb
 17031                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
 17032 000045F3 EBE2                <1> 	jmp 	short mkdir_1
 17033                              <1> 		; br 1b / get next char
 17034                              <1> mkdir_err:
 17035                              <1> 	; 17/06/2015
 17036 000045F5 C705[6A700000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 17037 000045FD 0000                <1>
 17038 000045FF E96EF6FFFF          <1> 	jmp	error
 17039                              <1> 
 17040                              <1> mkdir_3: ; 1:
 17041 00004604 A1[0C700000]        <1> 	mov	eax, [u.dirp]
 17042 00004609 A3[14700000]        <1> 	mov	[u.off], eax
 17043                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
 17044                              <1> 				 ; / slot to u.off
 17045                              <1> wdir: ; 29/04/2013
 17046 0000460E C705[1C700000]-     <1>         mov     dword [u.base], u.dirbuf
 17047 00004614 [30700000]          <1>
 17048                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
 17049 00004618 C705[20700000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
 17050 00004620 0000                <1>
 17051                              <1> 		; mov $10.,u.count / u.count = 10
 17052 00004622 66A1[D06F0000]      <1> 	mov	ax, [ii] 
 17053                              <1> 		; mov ii,r1 / r1 has i-number of current directory
 17054 00004628 B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
 17055 0000462A E8910F0000          <1> 	call 	access
 17056                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
 17057                              <1> 				 ; / for writing
 17058                              <1> 	; AX = i-number of current directory
 17059                              <1> 	; 01/08/2013
 17060 0000462F FE05[68700000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
 17061 00004635 E80F130000          <1> 	call	writei
 17062                              <1> 		; jsr r0,writei / write into directory
 17063 0000463A C3                  <1> 	retn	
 17064                              <1> 		; rts r0
 17065                              <1> 
 17066                              <1> 	; 30/11/2021
 17067                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 17068                              <1> sysexec:
 17069                              <1> 	; 02/05/2021
 17070                              <1> 	; 27/03/2021
 17071                              <1> 	; 26/03/2021
 17072                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 17073                              <1> 	; 23/10/2015
 17074                              <1> 	; 10/10/2015, 18/10/2015, 19/10/2015
 17075                              <1> 	; 29/07/2015, 05/08/2015, 05/08/2015
 17076                              <1> 	; 21/07/2015, 24/07/2015, 25/07/2015
 17077                              <1> 	; 01/07/2015, 02/07/2015, 20/07,2015
 17078                              <1> 	; 24/06/2015, 25/06/2021
 17079                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17080                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 17081                              <1> 	;
 17082                              <1> 	; 'sysexec' initiates execution of a file whose path name if
 17083                              <1> 	; pointed to by 'name' in the sysexec call. 
 17084                              <1> 	; 'sysexec' performs the following operations:
 17085                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
 17086                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
 17087                              <1> 	;    3. sets trap vectors to system routines.
 17088                              <1> 	;    4. loads arguments to be passed to executing file into
 17089                              <1> 	;	highest locations of user's core
 17090                              <1> 	;    5. puts pointers to arguments in locations immediately
 17091                              <1> 	;	following arguments.
 17092                              <1> 	;    6.	saves number of arguments in next location.
 17093                              <1> 	;    7. intializes user's stack area so that all registers
 17094                              <1> 	;	will be zeroed and the PS is cleared and the PC set
 17095                              <1> 	;	to core when 'sysret' restores registers 
 17096                              <1> 	;	and does an rti.
 17097                              <1> 	;    8. inializes u.r0 and u.sp
 17098                              <1> 	;    9. zeros user's core down to u.r0
 17099                              <1> 	;   10.	reads executable file from storage device into core
 17100                              <1> 	;	starting at location 'core'.
 17101                              <1> 	;   11.	sets u.break to point to end of user's code with
 17102                              <1> 	;	data area appended.
 17103                              <1> 	;   12.	calls 'sysret' which returns control at location
 17104                              <1> 	;	'core' via 'rti' instruction.
 17105                              <1> 	;
 17106                              <1> 	; Calling sequence:
 17107                              <1> 	;	sysexec; namep; argp
 17108                              <1> 	; Arguments:
 17109                              <1> 	;	namep - points to pathname of file to be executed
 17110                              <1> 	;	argp  - address of table of argument pointers
 17111                              <1> 	;	argp1... argpn - table of argument pointers
 17112                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
 17113                              <1> 	; Inputs: (arguments)
 17114                              <1> 	; Outputs: -	
 17115                              <1> 	; ...............................................................
 17116                              <1> 	;
 17117                              <1> 	; Retro UNIX 386 v1 modification: 
 17118                              <1> 	;	User application runs in it's own virtual space 
 17119                              <1> 	;	which is izolated from kernel memory (and other
 17120                              <1> 	;	memory pages) via 80386	paging in ring 3 
 17121                              <1> 	;	privilige mode. Virtual start address is always 0.
 17122                              <1> 	;	User's core memory starts at linear address 400000h
 17123                              <1> 	;	(the end of the 1st 4MB).
 17124                              <1> 	;
 17125                              <1> 	; Retro UNIX 8086 v1 modification: 
 17126                              <1> 	;	user/application segment and system/kernel segment
 17127                              <1> 	;	are different and sysenter/sysret/sysrele routines
 17128                              <1> 	;	are different (user's registers are saved to 
 17129                              <1> 	;	and then restored from system's stack.)
 17130                              <1> 	;
 17131                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 17132                              <1> 	;	      arguments which were in these registers;
 17133                              <1> 	;	      but, it returns by putting the 1st argument
 17134                              <1> 	;	      in 'u.namep' and the 2nd argument
 17135                              <1> 	;	      on top of stack. (1st argument is offset of the
 17136                              <1> 	;	      file/path name in the user's program segment.)
 17137                              <1> 	
 17138                              <1> 	;call	arg2
 17139                              <1> 	; * name - 'u.namep' points to address of file/path name
 17140                              <1> 	;          in the user's program segment ('u.segmnt')
 17141                              <1> 	;          with offset in BX register (as sysopen argument 1).
 17142                              <1> 	; * argp - sysexec argument 2 is in CX register 
 17143                              <1> 	;          which is on top of stack.
 17144                              <1> 	;
 17145                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
 17146                              <1> 
 17147                              <1> 	; 23/06/2015 (32 bit modifications)
 17148                              <1> 
 17149 0000463B 891D[10700000]      <1> 	mov	[u.namep], ebx ; argument 1
 17150                              <1>         ; 18/10/2015
 17151 00004641 890D[28710000]      <1> 	mov     [argv], ecx  ; * ; argument 2
 17152 00004647 E8E4040000          <1> 	call	namei
 17153                              <1> 		; jsr r0,namei / namei returns i-number of file 
 17154                              <1> 			     ; / named in sysexec call in r1
 17155                              <1> 	;jc	error
 17156                              <1> 		; br error9
 17157 0000464C 730F                <1> 	jnc	short sysexec_0
 17158                              <1> 	;
 17159                              <1> 	; 'file not found !' error
 17160 0000464E C705[6A700000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
 17161 00004656 0000                <1>
 17162 00004658 E915F6FFFF          <1> 	jmp	error
 17163                              <1> 
 17164                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 17165                              <1> 	; (executable file flag is checked in 'access')
 17166                              <1> 	; (following error message is in 'access' subroutine)
 17167                              <1> ;sysexec_not_exf:
 17168                              <1> 	;; 'not executable file !' error
 17169                              <1> 	;mov	dword [u.error], ERR_NOT_EXECUTABLE
 17170                              <1> 	;jmp	error 
 17171                              <1> sysexec_0:
 17172                              <1> ; temporary - 28/11/2021
 17173 0000465D C70500800B00314E31- <1> mov	dword [0B8000h], 4E314E31h
 17174 00004666 4E                  <1>
 17175 00004667 B9FFFF0000          <1> mov	ecx, 0FFFFh
 17176                              <1> above1:
 17177 0000466C 4A                  <1> dec	edx
 17178 0000466D 42                  <1> inc	edx
 17179 0000466E E2FC                <1> loop	above1
 17180                              <1> 
 17181                              <1> 	; 26/03/2021 ('iget' will be called in 'access')
 17182                              <1> 	;call	iget
 17183                              <1> 	;	; jsr r0,iget / get i-node for file to be executed
 17184                              <1> 	;
 17185                              <1> 	;test    word [i.flgs], 10h
 17186                              <1> 	;	; bit $20,i.flgs / is file executable
 17187                              <1> 	;jz	short sysexec_not_exf
 17188                              <1> 	;;jz	error
 17189                              <1> 	;	; beq error9
 17190                              <1> 	; 26/03/2021
 17191 00004670 66BA4000            <1> 	mov	dx, 40h ; IEXEC - execute, owner
 17192 00004674 E8470F0000          <1> 	call	access
 17193                              <1> 	; ! we are here because there is execute permission !
 17194                              <1> 	; ('iopen' is not needed for regular files, from now on)
 17195                              <1> 
 17196                              <1> 	; 26/03/2021
 17197                              <1> 	;; 25/03/2021
 17198                              <1> 	;; (ref: Retro UNIX 386 v2, 'ux.s')
 17199                              <1> 	;mov	dx, 40h ; IEXEC - execute, owner
 17200                              <1> 	;;
 17201                              <1> 	;call	iopen
 17202                              <1> 	;	; jsr r0,iopen / gets i-node for file with i-number
 17203                              <1> 	;		     ; / given in r1 (opens file)
 17204                              <1> 	
 17205                              <1> 	; 26/03/2021
 17206                              <1> 	; AX = i-number of the file
 17207                              <1> 	;test	word [i.flgs], 20h
 17208                              <1> 	;	; bit $40,i.flgs / test user id on execution bit
 17209                              <1> 	;jz	short sysexec_1
 17210                              <1> 	;	; beq 1f
 17211                              <1> 	;cmp 	byte [u.uid], 0 ; 02/08/2013
 17212                              <1> 	;	; tstb u.uid / test user id
 17213                              <1> 	;jna	short sysexec_1
 17214                              <1> 	;	; beq 1f / super user
 17215                              <1> 
 17216                              <1> 	;mov	cl, [i.uid]
 17217                              <1> 	;mov	[u.uid], cl ; 02/08/2013
 17218                              <1> 	;	; movb i.uid,u.uid / put user id of owner of file
 17219                              <1> 				 ; / as process user id
 17220                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 17221 00004679 A0[916C0000]        <1> 	mov	al, [i.flgs+1]
 17222 0000467E 66833D[4A700000]00  <1> 	cmp	word [u.uid], 0	; super user (root) ?
 17223                              <1> 	;jna	short sysexec_19 ; yes, super user
 17224                              <1> 	;; 02/05/2021
 17225 00004686 7620                <1> 	jna	short sysexec_1	; don't set UID or GID
 17226                              <1> 
 17227                              <1> 	; test set user id on execution bit 
 17228 00004688 A808                <1> 	test	al, 08h ; ISUID flag (800h)
 17229                              <1> 	;jz	short sysexec_19
 17230                              <1> 	; 02/05/2021
 17231 0000468A 741C                <1> 	jz	short sysexec_1 ; do not set group ID
 17232                              <1> 				; (if user ID will not be set)
 17233                              <1> 				; (02/05/2021)	
 17234                              <1> 	; set user id on exec (800h)
 17235                              <1> 	; 26/03/2021
 17236                              <1> sysexec_setuid:
 17237                              <1> 	;; 27/03/2021
 17238                              <1> 	;cmp	word [u.uid], 0
 17239                              <1> 	;;jna	short sysexec_19 ; super user
 17240                              <1> 	;; 02/05/2021
 17241                              <1> 	;jna	short sysexec_1 ; do not set group ID
 17242                              <1> 	;			; (if user ID will not be set)
 17243                              <1> 	;			; (02/05/2021)
 17244 0000468C 668B0D[946C0000]    <1> 	mov	cx, [i.uid]
 17245 00004693 66890D[4A700000]    <1> 	mov	[u.uid], cx
 17246                              <1> sysexec_19:
 17247                              <1> 	; test set group id on execution bit 
 17248 0000469A A804                <1> 	test	al, 04h ; ISGID flag (400h)
 17249 0000469C 740A                <1> 	jz	short sysexec_1
 17250                              <1> sysexec_setgid:
 17251                              <1> 	; set group id on exec (400h)
 17252 0000469E A0[966C0000]        <1> 	mov	al, [i.gid]
 17253 000046A3 A2[4E700000]        <1> 	mov	[u.gid], al
 17254                              <1> 	;
 17255                              <1> sysexec_1:
 17256                              <1> 	; 18/10/2015
 17257                              <1> 	; 10/10/2015
 17258                              <1> 	; 24/07/2015
 17259                              <1> 	; 21/07/2015
 17260                              <1> 	; 25/06/2015
 17261                              <1> 	; 24/06/2015
 17262                              <1>         ; Moving arguments to the end of [u.upage]
 17263                              <1> 	; (by regarding page borders in user's memory space)
 17264                              <1> 	;
 17265                              <1> 	; 10/10/2015
 17266                              <1> 	; 21/07/2015
 17267 000046A8 89E5                <1> 	mov	ebp, esp ; (**)
 17268                              <1> 	; 18/10/2015
 17269 000046AA 89EF                <1> 	mov 	edi, ebp
 17270 000046AC B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
 17271                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
 17272 000046B1 29CF                <1> 	sub	edi, ecx
 17273 000046B3 89FC                <1> 	mov	esp, edi
 17274 000046B5 31C0                <1> 	xor	eax, eax
 17275 000046B7 A3[24700000]        <1> 	mov 	[u.nread], eax ; 0
 17276 000046BC 49                  <1> 	dec	ecx ; 256 - 1
 17277 000046BD 890D[20700000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
 17278                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
 17279                              <1> sysexec_2:
 17280 000046C3 8B35[28710000]      <1> 	mov	esi, [argv] ; 18/10/2015
 17281 000046C9 E871020000          <1> 	call	get_argp
 17282 000046CE B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
 17283                              <1> sysexec_3:
 17284 000046D3 21C0                <1> 	and	eax, eax
 17285 000046D5 7456                <1> 	jz	short sysexec_6
 17286                              <1> 	; 18/10/2015
 17287 000046D7 010D[28710000]      <1> 	add	[argv], ecx ; 4
 17288 000046DD 66FF05[26710000]    <1> 	inc	word [argc]
 17289                              <1> 	;
 17290 000046E4 A3[1C700000]        <1> 	mov	[u.base], eax
 17291                              <1>  	; 23/10/2015
 17292 000046E9 66C705[64700000]00- <1> 	mov	word [u.pcount], 0
 17293 000046F1 00                  <1>
 17294                              <1> sysexec_4:
 17295 000046F2 E810140000          <1> 	call	cpass ; get a character from user's core memory
 17296 000046F7 750B                <1>         jnz	short sysexec_5
 17297                              <1> 		; (max. 255 chars + null)
 17298                              <1> 	; 18/10/2015
 17299 000046F9 28C0                <1> 	sub 	al, al
 17300 000046FB AA                  <1> 	stosb
 17301 000046FC FF05[24700000]      <1> 	inc	dword [u.nread]
 17302 00004702 EB29                <1> 	jmp	short sysexec_6
 17303                              <1> sysexec_5:
 17304 00004704 AA                  <1> 	stosb
 17305 00004705 20C0                <1> 	and 	al, al
 17306 00004707 75E9                <1> 	jnz	short sysexec_4
 17307 00004709 B904000000          <1> 	mov	ecx, 4
 17308 0000470E 390D[24710000]      <1> 	cmp	[ncount], ecx ; 4
 17309 00004714 72AD                <1> 	jb	short sysexec_2
 17310 00004716 8B35[20710000]      <1> 	mov	esi, [nbase]
 17311 0000471C 010D[20710000]      <1> 	add	[nbase], ecx ; 4	
 17312 00004722 66290D[24710000]    <1> 	sub	[ncount], cx 
 17313 00004729 8B06                <1> 	mov	eax, [esi]
 17314 0000472B EBA6                <1> 	jmp	short sysexec_3
 17315                              <1> sysexec_6:
 17316                              <1> 	; 18/10/2015
 17317                              <1> 	; argument list transfer from user's core memory to
 17318                              <1> 	; kernel stack frame is OK here.
 17319                              <1> 	; [u.nread] = ; argument list length
 17320                              <1> 	;mov	[argv], esp ; start address of argument list
 17321                              <1> 	;
 17322                              <1> 	; 18/10/2015
 17323                              <1> 	; 24/07/2015
 17324                              <1>         ; 21/07/2015
 17325                              <1> 	; 02/07/2015
 17326                              <1> 	; 25/06/2015
 17327                              <1> 	; 24/06/2015
 17328                              <1> 	; 23/06/2015
 17329                              <1> 	;
 17330 0000472D 8B1D[5C700000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
 17331 00004733 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
 17332 00004735 740A                <1> 	jz	short sysexec_7
 17333 00004737 A1[58700000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
 17334 0000473C E818E9FFFF          <1> 	call	deallocate_page_dir
 17335                              <1> sysexec_7:
 17336 00004741 E848E8FFFF          <1> 	call	make_page_dir
 17337                              <1> 	;jc	short sysexec_14
 17338                              <1> 	;jc	panic  ; allocation error 
 17339                              <1> 	;	       ; after a deallocation would be nonsence !?
 17340                              <1> 	; 26/03/2021
 17341 00004746 7243                <1> 	jc	short sysexec_panic
 17342                              <1> 	
 17343                              <1> 	; 24/07/2015
 17344                              <1> 	; map kernel pages (1st 4MB) to PDE 0
 17345                              <1> 	;     of the user's page directory
 17346                              <1> 	;     (It is needed for interrupts!)
 17347                              <1> 	; 18/10/2015
 17348 00004748 8B15[F86E0000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
 17349 0000474E 8B02                <1> 	mov	eax, [edx] ; physical address of
 17350                              <1> 			   ; kernel's first page table (1st 4 MB)
 17351                              <1> 			   ; (PDE 0 of kernel's page directory)
 17352 00004750 8B15[58700000]      <1> 	mov 	edx, [u.pgdir]
 17353 00004756 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
 17354                              <1> 	;
 17355                              <1> 	; 20/07/2015
 17356 00004758 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
 17357                              <1> 	; 18/10/2015
 17358 0000475D BE[18710000]        <1> 	mov	esi, pcore ; physical start address
 17359                              <1> sysexec_8:	
 17360 00004762 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
 17361 00004767 E840E8FFFF          <1> 	call	make_page_table
 17362                              <1> 	;jc	panic
 17363                              <1> 	; 26/03/2021
 17364 0000476C 721D                <1> 	jc	short sysexec_panic
 17365                              <1> 	;
 17366                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
 17367 0000476E E847E8FFFF          <1> 	call	make_page ; make new page, clear and set the pte
 17368                              <1> 	;jc	panic
 17369                              <1> 	; 26/03/2021
 17370 00004773 7216                <1> 	jc	short sysexec_panic
 17371                              <1> 	;
 17372 00004775 8906                <1> 	mov	[esi], eax ; 24/06/2015
 17373                              <1> 	; ebx = virtual address (24/07/2015)
 17374                              <1> 	; 30/11/2021
 17375                              <1> 	;call 	add_to_swap_queue
 17376                              <1> 	; 18/10/2015
 17377 00004777 81FE[1C710000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
 17378 0000477D 7411                <1> 	je	short sysexec_9 ; yes
 17379 0000477F BE[1C710000]        <1> 	mov	esi, ecore  ; physical address of the last page
 17380                              <1> 	; 20/07/2015
 17381 00004784 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
 17382                              <1> 	; ebx = virtual end address + segment base address - 4K
 17383 00004789 EBD7                <1>         jmp     short sysexec_8
 17384                              <1> sysexec_panic:
 17385                              <1> 	; 26/03/2021
 17386 0000478B E979EDFFFF          <1> 	jmp	panic
 17387                              <1> 
 17388                              <1> sysexec_9:
 17389                              <1> 	; 18/10/2015
 17390                              <1> 	; 26/08/2015
 17391                              <1> 	; 25/06/2015
 17392                              <1> 	; move arguments from kernel stack to [ecore]
 17393                              <1> 	; (argument list/line will be copied from kernel stack
 17394                              <1> 	; frame to the last (stack) page of user's core memory)
 17395                              <1> 	; 18/10/2015
 17396 00004790 8B3D[1C710000]      <1> 	mov	edi, [ecore]
 17397 00004796 81C700100000        <1> 	add	edi, PAGE_SIZE
 17398 0000479C 0FB705[26710000]    <1> 	movzx	eax, word [argc]
 17399 000047A3 09C0                <1> 	or	eax, eax
 17400 000047A5 7509                <1> 	jnz	short sysexec_10
 17401 000047A7 89FB                <1> 	mov 	ebx, edi
 17402 000047A9 83EB04              <1> 	sub	ebx, 4 
 17403 000047AC 8903                <1> 	mov	[ebx], eax ; 0
 17404 000047AE EB40                <1> 	jmp 	short sysexec_13
 17405                              <1> sysexec_10:
 17406 000047B0 8B0D[24700000]      <1> 	mov	ecx, [u.nread]
 17407                              <1> 	;mov 	esi, [argv]
 17408 000047B6 89E6                <1> 	mov	esi, esp ; start address of argument list
 17409 000047B8 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
 17410 000047BA 89C2                <1> 	mov	edx, eax
 17411 000047BC FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
 17412 000047BE C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
 17413 000047C1 89FB                <1> 	mov	ebx, edi
 17414 000047C3 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
 17415 000047C6 29D3                <1> 	sub 	ebx, edx
 17416 000047C8 89FA                <1> 	mov	edx, edi
 17417 000047CA F3A4                <1> 	rep	movsb
 17418 000047CC 89D6                <1> 	mov 	esi, edx
 17419 000047CE 89DF                <1> 	mov 	edi, ebx
 17420 000047D0 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
 17421 000047D5 2B15[1C710000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
 17422 000047DB AB                  <1> 	stosd	; eax = argument count
 17423                              <1> sysexec_11:
 17424 000047DC 89F0                <1> 	mov	eax, esi
 17425 000047DE 01D0                <1> 	add	eax, edx
 17426 000047E0 AB                  <1> 	stosd  ; eax = virtual address
 17427 000047E1 FE0D[26710000]      <1> 	dec	byte [argc]
 17428 000047E7 7407                <1> 	jz	short sysexec_13
 17429                              <1> sysexec_12:
 17430 000047E9 AC                  <1> 	lodsb
 17431 000047EA 20C0                <1> 	and	al, al
 17432 000047EC 75FB                <1> 	jnz	short sysexec_12
 17433 000047EE EBEC                <1> 	jmp	short sysexec_11
 17434                              <1> 	;
 17435                              <1> 	; 1:
 17436                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
 17437                              <1> 			     ; / pointers to arguments to be passed
 17438                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
 17439                              <1> 			      ; / u.quit = 1 take quit
 17440                              <1> 		; mov $1,u.intr / u.intr determines handling of 
 17441                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
 17442                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
 17443                              <1> 			       ; / system routine
 17444                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector
 17445                              <1> 			       ; / set to take system routine
 17446                              <1> 		; mov $sstack,sp / stack space used during swapping
 17447                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
 17448                              <1> 		; mov $ecore,r5 / r5 has end of core
 17449                              <1> 		; mov $core,r4 / r4 has start of users core
 17450                              <1> 		; mov r4,u.base / u.base has start of users core
 17451                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
 17452                              <1> 	; 1:
 17453                              <1> 		; tst (r2)+ / argument char = "nul"
 17454                              <1> 		; bne 1b
 17455                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of
 17456                              <1> 			  ; / end of argument pointer list
 17457                              <1> 	; 1:
 17458                              <1> 	     ; / move arguments to bottom of users core
 17459                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 17460                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
 17461                              <1> 			    ; / ptr list
 17462                              <1> 		; blo 1f / branch to 1f when all arguments
 17463                              <1> 		       ; / are moved
 17464                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 17465                              <1> 	; 2:
 17466                              <1> 		; tstb (r3)+
 17467                              <1> 		; bne 2b / scan argument for \0 (nul)
 17468                              <1> 
 17469                              <1> 	; 2:
 17470                              <1> 		; movb -(r3),-(r5) / move argument char 
 17471                              <1> 				 ; / by char starting at "ecore"
 17472                              <1> 		; cmp r3,(r2) / moved all characters in 
 17473                              <1> 			    ; / this argument
 17474                              <1> 		; bhi 2b / branch 2b if not
 17475                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
 17476                              <1> 			     ; / r5 has pointer to nth arg
 17477                              <1> 		; br 1b / string
 17478                              <1> 	; 1:
 17479                              <1> 		; clrb -(r5)
 17480                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
 17481                              <1> 			; / last word of argument strings
 17482                              <1> 		; mov $core,r2
 17483                              <1> 	
 17484                              <1> 	; 1: / move argument pointers into core following 
 17485                              <1> 	      ; / argument strings
 17486                              <1> 		; cmp r2,r4
 17487                              <1> 		; bhis 1f / branch to 1f when all pointers
 17488                              <1> 			; / are moved
 17489                              <1> 		; mov (r2)+,-(r5)
 17490                              <1> 		; br 1b
 17491                              <1> 	; 1:
 17492                              <1> 		; sub $core,r4 / gives number of arguments *2
 17493                              <1> 		; asr r4 / divide r4 by 2 to calculate 
 17494                              <1> 		       ; / the number of args stored
 17495                              <1> 		; mov r4,-(r5) / save number of arguments ahead
 17496                              <1> 			     ; / of the argument pointers
 17497                              <1> sysexec_13:
 17498                              <1> 	; 30/11/2021
 17499                              <1> 	; 28/11/2021
 17500                              <1> 	; 19/10/2015
 17501                              <1> 	; 18/10/2015
 17502                              <1> 	; 29/07/2015
 17503                              <1> 	; 25/07/2015
 17504                              <1> 	; 24/07/2015
 17505                              <1> 	; 20/07/2015
 17506                              <1> 	; 25/06/2015
 17507                              <1> 	; 24/06/2015
 17508                              <1> 	; 23/06/2015
 17509                              <1> 	;
 17510                              <1> 	; moving arguments to [ecore] is OK here..
 17511                              <1> 	; 18/10/2015
 17512 000047F0 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
 17513                              <1> 	; ebx = beginning addres of argument list pointers
 17514                              <1> 	;	in user's stack
 17515                              <1> 	; 19/10/2015
 17516 000047F2 2B1D[1C710000]      <1> 	sub 	ebx, [ecore]
 17517 000047F8 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
 17518                              <1> 			; end of core - 4096 (last page)
 17519                              <1> 			; (virtual address)
 17520 000047FE 891D[28710000]      <1> 	mov	[argv], ebx
 17521 00004804 891D[28700000]      <1> 	mov	[u.break], ebx ; available user memory
 17522                              <1> 	;
 17523 0000480A 29C0                <1> 	sub	eax, eax
 17524 0000480C C705[20700000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
 17525 00004814 0000                <1>
 17526                              <1> 		; mov $14,u.count
 17527 00004816 C705[08700000]-     <1> 	mov	dword [u.fofp], u.off
 17528 0000481C [14700000]          <1>
 17529                              <1> 		; mov $u.off,u.fofp
 17530 00004820 A3[14700000]        <1> 	mov	[u.off], eax ; 0
 17531                              <1> 		; clr u.off / set offset in file to be read to zero
 17532                              <1> 	; 25/07/2015
 17533 00004825 A3[1C700000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
 17534                              <1> 	; 25/06/2015 
 17535 0000482A A1[D06F0000]        <1> 	mov	eax, [ii] ; 28/11/2021 (32 bit inode number)
 17536                              <1> 	; AX = i-number of the executable file
 17537 0000482F E8050F0000          <1> 	call	readi
 17538                              <1> 		; jsr r0,readi / read in first six words of 
 17539                              <1> 			; / user's file, starting at $core
 17540                              <1> 		; mov sp,r5 / put users stack address in r5
 17541                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
 17542                              <1> 				; / from r5 (leaves number of words
 17543                              <1> 				; / less 26 available for
 17544                              <1> 			     	; / program in user core
 17545                              <1> 		; mov r5,u.count /
 17546                              <1> 	; 25/06/2015
 17547 00004834 8B0D[28700000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
 17548 0000483A 890D[20700000]      <1> 	mov	[u.count], ecx ; save for overrun check
 17549                              <1> 	;
 17550 00004840 8B0D[24700000]      <1> 	mov	ecx, [u.nread]
 17551 00004846 890D[28700000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
 17552 0000484C 80F920              <1> 	cmp	cl, 32
 17553 0000484F 7540                <1>         jne     short sysexec_15
 17554                              <1> 	;:
 17555                              <1> 	; 25/06/2015
 17556                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
 17557                              <1> 	; 18/10/2015
 17558 00004851 8B35[18710000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
 17559                              <1> 		             ; (phys. start addr. of the exec. file)
 17560 00004857 AD                  <1> 	lodsd
 17561 00004858 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBh, 1Eh -> jump to +32
 17562 0000485C 7533                <1> 	jne	short sysexec_15
 17563                              <1> 		; cmp core,$405 / br .+14 is first instruction 
 17564                              <1> 			      ; / if file is standard a.out format
 17565                              <1> 		; bne 1f / branch, if not standard format
 17566 0000485E AD                  <1> 	lodsd
 17567 0000485F 89C1                <1> 	mov	ecx, eax ; text (code) section size
 17568 00004861 AD                  <1> 	lodsd
 17569 00004862 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
 17570                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
 17571                              <1> 		              ; / number of bytes in program text
 17572                              <1> 		; sub $14,r5 / subtract 12
 17573 00004864 89CB                <1> 	mov	ebx, ecx
 17574                              <1> 	;
 17575                              <1> 	; 25/06/2015
 17576                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
 17577                              <1> 	;	and SINGLIX operating systems (as code template).
 17578                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
 17579                              <1> 	;	due to RUFS (floppy disk file system) restriction...
 17580                              <1> 	;	Overrun is not possible for current version.
 17581                              <1> 	;
 17582 00004866 AD                  <1> 	lodsd	
 17583 00004867 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
 17584 00004869 3B1D[20700000]      <1> 	cmp	ebx, [u.count]
 17585 0000486F 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
 17586                              <1> 	;
 17587                              <1> 	; 24/07/2015
 17588                              <1> 	; add bss section size to [u.break]
 17589 00004871 0105[28700000]      <1> 	add 	[u.break], eax
 17590                              <1> 	;
 17591 00004877 83E920              <1> 	sub	ecx, 32 ; header size (already loaded)
 17592                              <1> 	;cmp	ecx, [u.count]
 17593                              <1> 	;jnb	short sysexec_16
 17594                              <1> 		; cmp r5,u.count /
 17595                              <1> 		; bgt 1f / branch if r5 greater than u.count
 17596 0000487A 890D[20700000]      <1> 	mov	[u.count], ecx ; required read count
 17597                              <1> 		; mov r5,u.count
 17598                              <1> 	;
 17599 00004880 EB29                <1> 	jmp	short sysexec_16
 17600                              <1> 	;
 17601                              <1> sysexec_14:
 17602                              <1> 	; 23/06/2015
 17603                              <1> 	; insufficient (out of) memory
 17604 00004882 C705[6A700000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
 17605 0000488A 0000                <1>
 17606 0000488C E9E1F3FFFF          <1> 	jmp	error
 17607                              <1> 	;
 17608                              <1> sysexec_15:
 17609                              <1> 	; 25/06/2015
 17610                              <1>         ;movzx   edx, word [i.size] ; file size
 17611                              <1> 	; 30/11/2021
 17612 00004891 8B15[986C0000]      <1> 	mov	edx, [i.size] ; file size
 17613 00004897 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
 17614 00004899 7626                <1> 	jna	short sysexec_17 ; no need to next read
 17615 0000489B 01D1                <1> 	add	ecx, edx ; [i.size]
 17616 0000489D 3B0D[20700000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
 17617 000048A3 77DD                <1> 	ja	short sysexec_14
 17618 000048A5 8915[20700000]      <1> 	mov	[u.count], edx
 17619                              <1> sysexec_16:
 17620                              <1> 	;mov	ax, [ii] ; i-number
 17621                              <1> 	; 28/11/2021
 17622 000048AB A1[D06F0000]        <1> 	mov	eax, [ii] ; 32 bit inode number
 17623 000048B0 E8840E0000          <1> 	call	readi
 17624                              <1> 		; add core+10,u.nread / add size of user data area
 17625                              <1> 		                    ; / to u.nread
 17626                              <1> 		; br 2f
 17627                              <1> 	; 1:
 17628                              <1> 		; jsr r0,readi / read in rest of file
 17629                              <1> 	; 2:
 17630 000048B5 8B0D[24700000]      <1> 	mov	ecx, [u.nread]
 17631 000048BB 010D[28700000]      <1> 	add	[u.break], ecx
 17632                              <1> 		; mov u.nread,u.break / set users program break to end of
 17633                              <1> 				    ; / user code
 17634                              <1> 		; add $core+14,u.break / plus data area
 17635                              <1> 	; 20/07/2015
 17636                              <1> sysexec_17:
 17637                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 17638                              <1> 	; ('iclose' is not needed for regular files, from now on)
 17639                              <1> 	;;mov	ax, [ii] ; i-number
 17640                              <1> 	;call	iclose
 17641                              <1> 	;	; jsr r0,iclose / does nothing
 17642 000048C1 31C0                <1>         xor     eax, eax
 17643 000048C3 FEC0                <1> 	inc	al
 17644 000048C5 66A3[44700000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
 17645 000048CB 66A3[46700000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
 17646                              <1> 	; 30/11/2021
 17647 000048D1 FEC8                <1> 	dec	al  ; eax = 0
 17648                              <1> 	; 02/07/2015
 17649                              <1>         ;cmp	dword [u.ppgdir], 0 ; is the caller sys_init (kernel) ?
 17650 000048D3 3905[5C700000]      <1> 	cmp	[u.ppgdir], eax ; 0 ; is the caller sys_init (kernel) ?
 17651 000048D9 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
 17652                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
 17653 000048DB 8B15[F86E0000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
 17654 000048E1 8915[5C700000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here
 17655                              <1> sysexec_18:
 17656                              <1> 
 17657                              <1> ; temporary - 28/11/2021
 17658 000048E7 C70504800B00394E39- <1> mov	dword [0B8004h], 4E394E39h
 17659 000048F0 4E                  <1>
 17660 000048F1 B9FFFF0000          <1> mov	ecx, 0FFFFh
 17661                              <1> above7:
 17662 000048F6 4A                  <1> dec	edx
 17663 000048F7 42                  <1> inc	edx
 17664 000048F8 E2FC                <1> loop	above7
 17665                              <1> 
 17666                              <1> 	; 18/10/2015
 17667                              <1> 	; 05/08/2015
 17668                              <1> 	; 29/07/2015
 17669 000048FA 8B2D[28710000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
 17670                              <1> 			    ; list pointers (argument count)
 17671 00004900 FA                  <1> 	cli
 17672 00004901 8B25[946E0000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
 17673                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
 17674                              <1> 			    ; for this process	 
 17675                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
 17676                              <1> 	;;xor	eax, eax ; 0
 17677                              <1> 	;dec	al ; eax = 0
 17678                              <1> 	; eax = 0 ; 30/11/2021 
 17679 00004907 66BA2300            <1> 	mov	dx, UDATA
 17680 0000490B 6652                <1> 	push	dx  ; user's stack segment
 17681 0000490D 55                  <1> 	push	ebp ; user's stack pointer
 17682                              <1> 		    ; (points to number of arguments)
 17683 0000490E FB                  <1> 	sti
 17684 0000490F 9C                  <1> 	pushfd	; EFLAGS
 17685                              <1> 		; Set IF for enabling interrupts in user mode
 17686                              <1> 	;or	dword [esp], 200h 
 17687                              <1> 	;
 17688                              <1> 	;mov	bx, UCODE
 17689                              <1> 	;push	bx ; user's code segment
 17690 00004910 6A1B                <1> 	push	UCODE
 17691                              <1> 	;push	0
 17692 00004912 50                  <1> 	push	eax ; EIP (=0) - start address -
 17693                              <1> 		; clr -(r5) / popped into ps when rti in 
 17694                              <1> 			  ; / sysrele is executed
 17695                              <1> 		; mov $core,-(r5) / popped into pc when rti 
 17696                              <1> 		                ; / in sysrele is executed
 17697                              <1> 		;mov r5,0f / load second copyz argument
 17698                              <1> 		;tst -(r5) / decrement r5
 17699 00004913 8925[EC6F0000]      <1> 	mov	[u.sp], esp ; 29/07/2015
 17700                              <1> 	; 05/08/2015
 17701                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
 17702                              <1> 	; ('push dx' would cause to general protection fault, 
 17703                              <1> 	; after 'pop ds' etc.)
 17704                              <1> 	;
 17705                              <1> 	;; push dx ; ds (UDATA)
 17706                              <1> 	;; push dx ; es (UDATA)
 17707                              <1> 	;; push dx ; fs (UDATA)
 17708                              <1> 	;; push dx ; gs (UDATA)
 17709                              <1> 	;
 17710                              <1> 	; This is a trick to prevent general protection fault
 17711                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
 17712 00004919 8EC2                <1> 	mov 	es, dx ; UDATA
 17713 0000491B 06                  <1> 	push 	es ; ds (UDATA)
 17714 0000491C 06                  <1> 	push 	es ; es (UDATA)
 17715 0000491D 06                  <1> 	push 	es ; fs (UDATA)
 17716 0000491E 06                  <1> 	push	es ; gs (UDATA)
 17717 0000491F 66BA1000            <1> 	mov	dx, KDATA
 17718 00004923 8EC2                <1> 	mov	es, dx
 17719                              <1> 	;
 17720                              <1> 	;; pushad simulation
 17721 00004925 89E5                <1> 	mov	ebp, esp ; esp before pushad
 17722 00004927 50                  <1> 	push	eax ; eax (0)
 17723 00004928 50                  <1> 	push	eax ; ecx (0)
 17724 00004929 50                  <1> 	push	eax ; edx (0)
 17725 0000492A 50                  <1> 	push	eax ; ebx (0)
 17726 0000492B 55                  <1> 	push	ebp ; esp before pushad
 17727 0000492C 50                  <1> 	push	eax ; ebp (0)
 17728 0000492D 50                  <1> 	push	eax ; esi (0)		
 17729 0000492E 50                  <1> 	push	eax ; edi (0)	
 17730                              <1> 	;
 17731 0000492F A3[F46F0000]        <1> 	mov	[u.r0], eax ; eax = 0
 17732 00004934 8925[F06F0000]      <1> 	mov	[u.usp], esp
 17733                              <1> 		; mov r5,u.r0 /
 17734                              <1> 		; sub $16.,r5 / skip 8 words
 17735                              <1> 		; mov r5,u.sp / assign user stack pointer value,
 17736                              <1> 		;             / effectively zeroes all regs
 17737                              <1> 			    ; / when sysrele is executed
 17738                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
 17739                              <1> 		; clr u.break
 17740                              <1> 		; mov r5,sp / point sp to user's stack
 17741                              <1> 	;
 17742 0000493A E955F3FFFF          <1> 	jmp	sysret0
 17743                              <1> 	;jmp	sysret
 17744                              <1> 		; br sysret3 / return to core image at $core
 17745                              <1> 
 17746                              <1> get_argp:
 17747                              <1> 	; 18/10/2015 (nbase, ncount)
 17748                              <1> 	; 21/07/2015
 17749                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
 17750                              <1> 	; Get (virtual) address of argument from user's core memory
 17751                              <1> 	;
 17752                              <1> 	; INPUT:
 17753                              <1> 	;	esi = virtual address of argument pointer
 17754                              <1> 	; OUTPUT:
 17755                              <1> 	;	eax = virtual address of argument
 17756                              <1> 	;
 17757                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
 17758                              <1> 	;
 17759 0000493F 833D[5C700000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
 17760                              <1> 				    ; (the caller is kernel)
 17761 00004946 7667                <1>         jna     short get_argpk 
 17762                              <1> 	;
 17763 00004948 89F3                <1>      	mov	ebx, esi
 17764 0000494A E8C7E9FFFF          <1> 	call	get_physical_addr ; get physical address
 17765 0000494F 0F8289000000        <1>         jc      get_argp_err
 17766 00004955 A3[20710000]        <1> 	mov 	[nbase], eax ; physical address	
 17767 0000495A 66890D[24710000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
 17768 00004961 B804000000          <1> 	mov	eax, 4 ; 21/07/2015
 17769 00004966 6639C1              <1> 	cmp	cx, ax ; 4
 17770 00004969 735D                <1> 	jnb	short get_argp2
 17771 0000496B 89F3                <1> 	mov	ebx, esi
 17772 0000496D 01CB                <1> 	add	ebx, ecx
 17773 0000496F E8A2E9FFFF          <1> 	call	get_physical_addr ; get physical address
 17774 00004974 7268                <1> 	jc	short get_argp_err
 17775                              <1> 	;push	esi
 17776 00004976 89C6                <1> 	mov	esi, eax
 17777 00004978 66870D[24710000]    <1> 	xchg	cx, [ncount]
 17778 0000497F 8735[20710000]      <1> 	xchg	esi, [nbase]
 17779 00004985 B504                <1> 	mov	ch, 4
 17780 00004987 28CD                <1> 	sub	ch, cl
 17781                              <1> get_argp0:
 17782 00004989 AC                  <1> 	lodsb
 17783 0000498A 6650                <1> 	push	ax
 17784 0000498C FEC9                <1> 	dec	cl
 17785 0000498E 75F9                <1>         jnz     short get_argp0
 17786 00004990 8B35[20710000]      <1> 	mov	esi, [nbase]
 17787                              <1> 	; 21/07/2015
 17788 00004996 0FB6C5              <1> 	movzx	eax, ch
 17789 00004999 0105[20710000]      <1> 	add	[nbase], eax
 17790 0000499F 662905[24710000]    <1> 	sub	[ncount], ax
 17791                              <1> get_argp1:
 17792 000049A6 AC                  <1> 	lodsb
 17793 000049A7 FECD                <1> 	dec	ch
 17794 000049A9 743D                <1>         jz      short get_argp3
 17795 000049AB 6650                <1>         push	ax
 17796 000049AD EBF7                <1> 	jmp     short get_argp1
 17797                              <1> get_argpk:
 17798                              <1> 	; Argument is in kernel's memory space
 17799 000049AF 66C705[24710000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
 17800 000049B7 10                  <1>
 17801 000049B8 8935[20710000]      <1> 	mov	[nbase], esi
 17802 000049BE 8305[20710000]04    <1> 	add	dword [nbase], 4
 17803 000049C5 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
 17804 000049C7 C3                  <1> 	retn
 17805                              <1> get_argp2:
 17806                              <1> 	; 21/07/2015
 17807                              <1> 	;mov	eax, 4
 17808 000049C8 8B15[20710000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
 17809 000049CE 0105[20710000]      <1> 	add	[nbase], eax
 17810 000049D4 662905[24710000]    <1> 	sub	[ncount], ax
 17811                              <1> 	;
 17812 000049DB 8B02                <1> 	mov	eax, [edx]
 17813 000049DD C3                  <1> 	retn
 17814                              <1> get_argp_err:
 17815 000049DE A3[6A700000]        <1> 	mov	[u.error], eax
 17816 000049E3 E98AF2FFFF          <1> 	jmp	error
 17817                              <1> get_argp3:
 17818 000049E8 B103                <1> 	mov	cl, 3
 17819                              <1> get_argp4:
 17820 000049EA C1E008              <1> 	shl	eax, 8
 17821 000049ED 665A                <1> 	pop	dx
 17822 000049EF 88D0                <1> 	mov 	al, dl
 17823 000049F1 E2F7                <1>         loop    get_argp4
 17824                              <1> 	;pop	esi
 17825 000049F3 C3                  <1> 	retn	
 17826                              <1> 
 17827                              <1> sysfstat: 
 17828                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17829                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17830                              <1> 	;
 17831                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
 17832                              <1> 	; on open files instead of files given by name. It puts the
 17833                              <1> 	; buffer address on the stack, gets the i-number and
 17834                              <1> 	; checks to see if the file is open for reading or writing.
 17835                              <1> 	; If the file is open for writing (i-number is negative)
 17836                              <1> 	; the i-number is set positive and a branch into 'sysstat'
 17837                              <1> 	; is made.	
 17838                              <1> 	;
 17839                              <1> 	; Calling sequence:
 17840                              <1> 	;	sysfstat; buf
 17841                              <1> 	; Arguments:
 17842                              <1> 	;	buf - buffer address
 17843                              <1> 	;
 17844                              <1> 	; Inputs: *u.r0 - file descriptor
 17845                              <1> 	; Outputs: buffer is loaded with file information
 17846                              <1> 	; ...............................................................
 17847                              <1> 	;				
 17848                              <1> 	; Retro UNIX 8086 v1 modification:
 17849                              <1> 	;       'sysfstat' system call has two arguments; so,
 17850                              <1> 	;	* 1st argument, file descriptor is in BX register
 17851                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 17852                              <1> 
 17853                              <1> 	; / set status of open file
 17854                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
 17855 000049F4 51                  <1> 	push	ecx
 17856                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
 17857                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
 17858                              <1> 		; jsr r0,getf / get the files i-number
 17859                              <1> 	; BX = file descriptor (file number)
 17860 000049F5 E8FF000000          <1> 	call	getf1
 17861 000049FA 6621C0              <1> 	and	ax, ax ; i-number of the file
 17862                              <1> 		; tst	r1 / is it 0?
 17863                              <1> 	;jz	error
 17864                              <1> 		; beq error3 / yes, error
 17865 000049FD 750F                <1> 	jnz	short sysfstat1
 17866 000049FF C705[6A700000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 17867 00004A07 0000                <1>
 17868 00004A09 E964F2FFFF          <1> 	jmp	error
 17869                              <1> sysfstat1:
 17870 00004A0E 80FC80              <1> 	cmp	ah, 80h
 17871 00004A11 7223                <1>         jb      short sysstat1
 17872                              <1> 		; bgt 1f / if i-number is negative (open for writing)
 17873 00004A13 66F7D8              <1> 	neg	ax
 17874                              <1> 		; neg r1 / make it positive, then branch
 17875 00004A16 EB1E                <1> 	jmp	short sysstat1
 17876                              <1> 		; br 1f / to 1f
 17877                              <1> sysstat:
 17878                              <1> 	; 18/10/2015
 17879                              <1> 	; 07/10/2015
 17880                              <1> 	; 02/09/2015
 17881                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17882                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17883                              <1> 	;
 17884                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
 17885                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
 17886                              <1> 	; long and information about the file placed in it.	
 17887                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
 17888                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
 17889                              <1> 	; is then loaded and the results are given in the UNIX
 17890                              <1> 	; Programmers Manual sysstat (II).	
 17891                              <1> 	;
 17892                              <1> 	; Calling sequence:
 17893                              <1> 	;	sysstat; name; buf
 17894                              <1> 	; Arguments:
 17895                              <1> 	;	name - points to the name of the file
 17896                              <1> 	;	buf - address of a 34 bytes buffer
 17897                              <1> 	; Inputs: -
 17898                              <1> 	; Outputs: buffer is loaded with file information
 17899                              <1> 	; ...............................................................
 17900                              <1> 	;				
 17901                              <1> 	; Retro UNIX 8086 v1 modification: 
 17902                              <1> 	;       'sysstat' system call has two arguments; so,
 17903                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 17904                              <1> 	;	to get sysstat system call arguments from the user;
 17905                              <1> 	;	* 1st argument, name is pointed to by BX register
 17906                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 17907                              <1> 	;
 17908                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 17909                              <1> 	;	      arguments which were in these registers;
 17910                              <1> 	;	      but, it returns by putting the 1st argument
 17911                              <1> 	;	      in 'u.namep' and the 2nd argument
 17912                              <1> 	;	      on top of stack. (1st argument is offset of the
 17913                              <1> 	;	      file/path name in the user's program segment.)		 	
 17914                              <1> 	
 17915                              <1> 	; / ; name of file; buffer - get files status
 17916                              <1> 		; jsr r0,arg2 / get the 2 arguments
 17917 00004A18 891D[10700000]      <1> 	mov	[u.namep], ebx
 17918 00004A1E 51                  <1> 	push	ecx
 17919 00004A1F E80C010000          <1> 	call	namei
 17920                              <1> 		; jsr r0,namei / get the i-number for the file
 17921                              <1> 	;jc	error
 17922                              <1> 		; br error3 / no such file, error
 17923 00004A24 7310                <1> 	jnc	short sysstat1
 17924                              <1> 	; pop 	ecx
 17925                              <1> sysstat_err0:
 17926                              <1> 	; 'file not found !' error
 17927 00004A26 C705[6A700000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17928 00004A2E 0000                <1>
 17929 00004A30 E93DF2FFFF          <1> 	jmp	error
 17930                              <1> 
 17931 00004A35 00                  <1> statx: db 0
 17932                              <1> 
 17933                              <1> sysstat1: ; 1:
 17934 00004A36 E89E0A0000          <1> 	call	iget
 17935                              <1> 		; jsr r0,iget / get the i-node into core
 17936                              <1> 	; 07/10/2015 (ax = [ii], inode number)
 17937                              <1> 	; 02/09/2015
 17938 00004A3B 8F05[1C700000]      <1> 	pop	dword [u.base]
 17939                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
 17940 00004A41 E858000000          <1> 	call	sysstat_gpa ; get physical address
 17941 00004A46 730A                <1> 	jnc 	short sysstat2
 17942                              <1> sysstat_err1:
 17943 00004A48 A3[6A700000]        <1> 	mov	dword [u.error], eax ; error code
 17944 00004A4D E920F2FFFF          <1> 	jmp	error
 17945                              <1> sysstat2:
 17946 00004A52 A0[D06F0000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
 17947 00004A57 AA                  <1> 	stosb
 17948 00004A58 FF05[1C700000]      <1> 	inc 	dword [u.base]
 17949 00004A5E 6649                <1> 	dec 	cx
 17950 00004A60 7505                <1> 	jnz	short sysstat3
 17951 00004A62 E837000000          <1> 	call	sysstat_gpa
 17952                              <1> 	;jc	short sysstat_err1
 17953                              <1> sysstat3:
 17954 00004A67 A0[D16F0000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
 17955 00004A6C AA                  <1> 	stosb
 17956                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
 17957 00004A6D FF05[1C700000]      <1> 	inc 	dword [u.base]
 17958                              <1> 	;dec 	word [u.pcount]
 17959 00004A73 6649                <1> 	dec	cx
 17960 00004A75 7505                <1> 	jnz	short sysstat4
 17961 00004A77 E822000000          <1> 	call	sysstat_gpa
 17962                              <1> 	;jc	short sysstat_err1	
 17963                              <1> sysstat4:
 17964 00004A7C BE[906C0000]        <1> 	mov	esi, inode
 17965                              <1> 		; mov $inode,r2 / r2 points to i-node
 17966                              <1> sysstat5: ; 1:
 17967 00004A81 A4                  <1> 	movsb
 17968                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
 17969 00004A82 FF05[1C700000]      <1> 	inc 	dword [u.base]
 17970                              <1> 	;dec 	word [u.pcount]
 17971 00004A88 6649                <1> 	dec	cx
 17972 00004A8A 7505                <1> 	jnz	short sysstat6
 17973 00004A8C E80D000000          <1> 	call	sysstat_gpa
 17974                              <1> 	;jc	short sysstat_err1
 17975                              <1> sysstat6:		
 17976 00004A91 81FE[B06C0000]      <1> 	cmp	esi, inode + 32
 17977                              <1> 		; cmp r2,$inode+32 / done?
 17978 00004A97 75E8                <1> 	jne	short sysstat5
 17979                              <1> 		; bne 1b / no, go back
 17980 00004A99 E9F4F1FFFF          <1> 	jmp	sysret
 17981                              <1> 		; br sysret3 / return through sysret
 17982                              <1> 	;
 17983                              <1> sysstat_gpa: ; get physical address of file status buffer
 17984                              <1> 	; 02/09/2015
 17985 00004A9E 8B1D[1C700000]      <1> 	mov 	ebx, [u.base]
 17986                              <1> 	; 07/10/2015
 17987 00004AA4 E86DE8FFFF          <1> 	call	get_physical_addr ; get physical address
 17988                              <1> 	;jc	short sysstat_gpa1
 17989 00004AA9 729D                <1> 	jc	short sysstat_err1
 17990                              <1> 	; 18/10/2015
 17991 00004AAB 89C7                <1> 	mov	edi, eax ; physical address
 17992                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
 17993                              <1> ;sysstat_gpa1:
 17994 00004AAD C3                  <1> 	retn
 17995                              <1> 
 17996                              <1> fclose:
 17997                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
 17998                              <1> 	;            (32 bit offset pointer modification)
 17999                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
 18000                              <1> 	;
 18001                              <1> 	; Given the file descriptor (index to the u.fp list)
 18002                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
 18003                              <1> 	; If i-node is active (i-number > 0) the entry in 
 18004                              <1> 	; u.fp list is cleared. If all the processes that opened
 18005                              <1> 	; that file close it, then fsp etry is freed and the file
 18006                              <1> 	; is closed. If not a return is taken. 
 18007                              <1> 	; If the file has been deleted while open, 'anyi' is called
 18008                              <1> 	; to see anyone else has it open, i.e., see if it is appears
 18009                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
 18010                              <1> 	; a check is made to see if the file is special.	
 18011                              <1> 	;
 18012                              <1> 	; INPUTS ->
 18013                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
 18014                              <1> 	;    u.fp - list of entries in the fsp table
 18015                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
 18016                              <1> 	; OUTPUTS ->
 18017                              <1> 	;    r1 - contains the same file descriptor
 18018                              <1> 	;    r2 - contains i-number
 18019                              <1> 	;
 18020                              <1> 	; ((AX = R1))
 18021                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
 18022                              <1> 	;
 18023                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
 18024                              <1> 	;              if i-number of the file is 0. (error)  	
 18025                              <1> 	;
 18026 00004AAE 0FB7D0              <1> 	movzx	edx, ax ; **
 18027 00004AB1 6650                <1> 	push	ax ; ***
 18028                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
 18029                              <1> 			     ; / the index to u.fp list)
 18030 00004AB3 E83F000000          <1> 	call	getf
 18031                              <1> 		; jsr r0,getf / r1 contains i-number, 
 18032                              <1> 			    ; / cdev has device =, u.fofp 
 18033                              <1> 			    ; / points to 3rd word of fsp entry
 18034 00004AB8 6683F801            <1> 	cmp	ax, 1 ; r1
 18035                              <1> 		; tst r1 / is i-number 0?
 18036 00004ABC 7236                <1> 	jb	short fclose_2
 18037                              <1> 		; beq 1f / yes, i-node not active so return
 18038                              <1> 		; tst (r0)+ / no, jump over error return
 18039 00004ABE 89D3                <1> 	mov	ebx, edx ; **
 18040 00004AC0 6689C2              <1> 	mov 	dx, ax ; *
 18041                              <1> 		; mov r1,r2 / move i-number to r2 ;*
 18042                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
 18043                              <1> 			    ; / which is index to u.fp ; **
 18044 00004AC3 C683[FE6F0000]00    <1> 	mov	byte [ebx+u.fp], 0
 18045                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
 18046 00004ACA 8B1D[08700000]      <1> 	mov	ebx, [u.fofp]
 18047                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
 18048                              <1> fclose_0:
 18049 00004AD0 FE4B04              <1> 	dec	byte [ebx+4] ; 18/06/2015
 18050                              <1> 		; decb 2(r1) / decrement the number of processes 
 18051                              <1> 			   ; / that have opened the file
 18052 00004AD3 791F                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
 18053                              <1> 		; bge 1f / if all processes haven't closed the file, return
 18054                              <1> 	;
 18055 00004AD5 6652                <1> 	push	dx ;*
 18056                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
 18057 00004AD7 6631C0              <1> 	xor	ax, ax ; 0
 18058 00004ADA 668943FC            <1> 	mov	[ebx-4], ax ; 0
 18059                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
 18060 00004ADE 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
 18061                              <1> 		; tstb	3(r1) / has this file been deleted
 18062 00004AE1 20C0                <1> 	and	al, al
 18063 00004AE3 7408                <1> 	jz	short fclose_1
 18064                              <1> 		; beq 2f / no, branch
 18065 00004AE5 6689D0              <1> 	mov	ax, dx ; *
 18066                              <1> 		; mov r2,r1 / yes, put i-number back into r1
 18067                              <1> 	; AX = inode number
 18068 00004AE8 E865040000          <1> 	call	anyi
 18069                              <1> 		; jsr r0,anyi / free all blocks related to i-number
 18070                              <1> 			    ; / check if file appears in fsp again
 18071                              <1> fclose_1: ; 2:
 18072 00004AED 6658                <1> 	pop	ax ; *
 18073                              <1> 		; mov (sp)+,r1 / put i-number back into r1
 18074 00004AEF E850130000          <1> 	call	iclose ; close if it is special file 
 18075                              <1> 		; jsr r0,iclose / check to see if its a special file
 18076                              <1> fclose_2: ; 1:
 18077 00004AF4 6658                <1> 	pop	ax ; ***
 18078                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
 18079 00004AF6 C3                  <1> 	retn
 18080                              <1> 		; rts r0
 18081                              <1> 
 18082                              <1> getf:	; / get the device number and the i-number of an open file
 18083                              <1> 	; 13/05/2015
 18084                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 18085                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 18086                              <1> 	;
 18087 00004AF7 89C3                <1> 	mov	ebx, eax
 18088                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
 18089 00004AF9 83FB0A              <1> 	cmp	ebx, 10
 18090                              <1> 		; cmp r1,$10. / user limited to 10 open files
 18091 00004AFC 730A                <1>         jnb	short getf2 ; 13/05/2015
 18092                              <1> 	;jnb     error
 18093                              <1> 		; bhis error3 / u.fp is table of users open files, 
 18094                              <1> 			    ; / index in fsp table
 18095 00004AFE 8A9B[FE6F0000]      <1> 	mov	bl, [ebx+u.fp]
 18096                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
 18097                              <1> 		                  ; / in fsp table
 18098 00004B04 08DB                <1> 	or	bl, bl
 18099 00004B06 7503                <1> 	jnz	short getf3
 18100                              <1> 	;jz	short getf4
 18101                              <1> 		; beq 1f / if its zero return
 18102                              <1> getf2:
 18103                              <1> 	; 'File not open !' error (ax=0)
 18104 00004B08 29C0                <1> 	sub	eax, eax
 18105 00004B0A C3                  <1> 	retn
 18106                              <1> getf3:	
 18107                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
 18108                              <1> 	;
 18109                              <1> 	; 'fsp' table (10 bytes/entry)
 18110                              <1> 	; bit 15				   bit 0
 18111                              <1> 	; ---|-------------------------------------------
 18112                              <1> 	; r/w|		i-number of open file
 18113                              <1> 	; ---|-------------------------------------------
 18114                              <1> 	;		   device number
 18115                              <1> 	; -----------------------------------------------
 18116                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 18117                              <1> 	; -----------------------------------------------
 18118                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 18119                              <1> 	; ----------------------|------------------------
 18120                              <1> 	;  flag that says file 	| number of processes
 18121                              <1> 	;   has been deleted	| that have file open 
 18122                              <1> 	; ----------------------|------------------------
 18123                              <1> 	;
 18124 00004B0B B80A000000          <1> 	mov	eax, 10
 18125 00004B10 F6E3                <1> 	mul	bl
 18126 00004B12 BB[8A6C0000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
 18127 00004B17 01C3                <1> 	add	ebx, eax
 18128                              <1> 		; asl r1
 18129                              <1> 		; asl r1 / multiply by 8 to get index into 
 18130                              <1> 		       ; / fsp table entry
 18131                              <1> 		; asl r1
 18132                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
 18133                              <1> 			      ; / in the fsp entry
 18134 00004B19 891D[08700000]      <1> 	mov	[u.fofp], ebx
 18135                              <1> 		; mov r1,u.fofp / save address of 3rd word 
 18136                              <1> 			      ; / in fsp entry in u.fofp
 18137 00004B1F 4B                  <1> 	dec	ebx
 18138 00004B20 4B                  <1> 	dec	ebx
 18139 00004B21 668B03              <1> 	mov	ax, [ebx]
 18140                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
 18141 00004B24 66A3[D56F0000]      <1> 	mov	[cdev], ax ; ;;in fact (!) 
 18142                              <1> 			     ;;dev number is in 1 byte
 18143                              <1> 		; mov -(r1),cdev / remove the device number  cdev
 18144 00004B2A 4B                  <1> 	dec	ebx
 18145 00004B2B 4B                  <1> 	dec	ebx
 18146 00004B2C 668B03              <1> 	mov	ax, [ebx]
 18147                              <1> 		; mov -(r1),r1 / and the i-number  r1
 18148                              <1> getf4:	; 1:
 18149 00004B2F C3                  <1> 	retn
 18150                              <1> 		; rts r0
 18151                              <1> 
 18152                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 18153                              <1> namei:
 18154                              <1> 	; 18/10/2021
 18155                              <1> 	; 12/06/2021
 18156                              <1> 	; 01/05/2021
 18157                              <1> 	; 26/03/2021
 18158                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 18159                              <1> 	; 04/12/2015 (14 byte file names)
 18160                              <1> 	; 18/10/2015 (nbase, ncount)
 18161                              <1> 	; 12/10/2015
 18162                              <1> 	; 21/08/2015
 18163                              <1> 	; 18/07/2015
 18164                              <1> 	; 02/07/2015
 18165                              <1> 	; 17/06/2015
 18166                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
 18167                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 18168                              <1> 	;
 18169                              <1> 	; 'namei' takes a file path name and returns i-number of
 18170                              <1> 	; the file in the current directory or the root directory
 18171                              <1> 	; (if the first character of the pathname is '/').	
 18172                              <1> 	;
 18173                              <1> 	; INPUTS ->
 18174                              <1> 	;    u.namep - points to a file path name
 18175                              <1> 	;    u.cdir - i-number of users directory
 18176                              <1> 	;    u.cdev - device number on which user directory resides	
 18177                              <1> 	; OUTPUTS ->
 18178                              <1> 	;    r1 - i-number of file
 18179                              <1> 	;    cdev
 18180                              <1> 	;    u.dirbuf - points to directory entry where a match 
 18181                              <1> 	;               occurs in the search for file path name.
 18182                              <1> 	;	        If no match u.dirb points to the end of 
 18183                              <1> 	;               the directory and r1 = i-number of the current
 18184                              <1> 	;	        directory.	
 18185                              <1> 	; ((AX = R1))
 18186                              <1> 	;
 18187                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
 18188                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 18189                              <1> 	;
 18190                              <1> 
 18191                              <1> 	;mov	ax, [u.cdir]
 18192                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
 18193                              <1> 			      ; / in r1
 18194                              <1> 	; 01/05/2021
 18195 00004B30 A1[F86F0000]        <1> 	mov	eax, [u.cdir]	
 18196 00004B35 8A15[FC6F0000]      <1> 	mov	dl, [u.cdrv]
 18197 00004B3B 8815[D56F0000]      <1> 	mov	[cdev], dl
 18198                              <1> 	;mov	dx, [u.cdrv]
 18199                              <1> 	;mov	[cdev], dx	; NOTE: Retro UNIX 8086 v1 
 18200                              <1> 				; device/drive number is in 1 byte, 
 18201                              <1> 				; not in 1 word!
 18202                              <1> 		; mov u.cdev,cdev / device number for users directory 
 18203                              <1> 				; / into cdev
 18204                              <1> 	; 12/10/2015
 18205                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 18206                              <1>       	; convert virtual (pathname) addr to physical address
 18207 00004B41 E80F010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
 18208                              <1> 		; esi = physical address of [u.namep]
 18209                              <1> 		; ecx = byte count in the page
 18210 00004B46 803E2F              <1> 	cmp	byte [esi], '/'
 18211                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
 18212 00004B49 751C                <1> 	jne	short namei_1
 18213                              <1> 		; bne 1f
 18214 00004B4B FF05[10700000]      <1> 	inc	dword [u.namep]
 18215                              <1> 		; inc u.namep / go to next char
 18216                              <1> 	;dec	cx ; remain byte count in the page
 18217 00004B51 49                  <1> 	dec	ecx ; 18/10/2021
 18218 00004B52 7506                <1> 	jnz	short namei_0
 18219                              <1> 	; 12/10/2015
 18220 00004B54 E8FC000000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 18221                              <1> 		; esi = physical address (page start + offset)
 18222                              <1> 		; ecx = byte count in the page
 18223 00004B59 4E                  <1> 	dec	esi
 18224                              <1> namei_0:
 18225 00004B5A 46                  <1> 	inc 	esi  ; go to next char
 18226                              <1> 	;mov	ax, [rootdir] ; 09/07/2013
 18227                              <1> 	; 18/10/2021
 18228 00004B5B A1[DC6F0000]        <1> 	mov	eax, [rootdir]
 18229                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
 18230 00004B60 C605[D56F0000]00    <1> 	mov	byte [cdev], 0
 18231                              <1> 		; clr cdev / clear device number
 18232                              <1> namei_1: ; 1:
 18233 00004B67 F606FF              <1> 	test	byte [esi], 0FFh
 18234                              <1> 	;jz	short getf4
 18235                              <1> 	; 26/03/2021
 18236                              <1> 	;jz	short getf2 ; retn
 18237                              <1> 	;;jz	nig
 18238                              <1> 		; tstb *u.namep / is the character in file name a nul
 18239                              <1> 		; beq nig / yes, end of file name reached; 
 18240                              <1> 			; / branch to "nig"
 18241                              <1> 	; 12/06/2021
 18242 00004B6A 7501                <1> 	jnz	short namei_2
 18243 00004B6C C3                  <1> 	retn
 18244                              <1> namei_2: ; 1:
 18245                              <1> 	; 18/10/2015
 18246 00004B6D 8935[20710000]      <1> 	mov 	[nbase], esi
 18247                              <1> 	;mov 	[ncount], cx
 18248                              <1> 	; 18/10/2021
 18249 00004B73 890D[24710000]      <1> 	mov	[ncount], ecx
 18250                              <1> 	;
 18251                              <1> 	;;mov	dx, 2
 18252                              <1> 	;mov	dl, 2 ; user flag (read, non-owner)
 18253                              <1> 	; 25/03/2021
 18254                              <1> 	;mov	dx, 100h ; IREAD - read, owner 
 18255                              <1> 	; 18/10/2021
 18256 00004B79 29D2                <1> 	sub	edx, edx
 18257 00004B7B FEC6                <1> 	inc	dh ; dx = 100h ; IREAD - read, owner 
 18258 00004B7D E83E0A0000          <1> 	call	access
 18259                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
 18260                              <1> 	; 'access' will not return here if user has not "r" permission !
 18261                              <1> 
 18262                              <1> 	;test 	word [i.flgs], 4000h
 18263                              <1> 	;	; bit $40000,i.flgs / directory i-node?
 18264                              <1>         ;jz	short namei_err
 18265                              <1> 		; beq error3 / no, got an error
 18266                              <1> 	; 26/03/2021 
 18267                              <1> ;	mov	al, [i.flgs+1]
 18268                              <1> ;	;test	al, 80h ; IFREG ; 80h
 18269                              <1> ;	;jz	short namei_err ; not a regular file ! (device!?)
 18270                              <1> ;	;and	al, 40h ; IFDIR ; 40h
 18271                              <1> ;	;jz	short namei_err ; not a sub directory !
 18272                              <1> ;	shl	al, 1 ; 80h (IFREG flag) -> cf = 1
 18273                              <1> ;	jnc	short namei_err ; not a regular file ! (device!?)
 18274                              <1> ;	shl	al, 1 ; 80h (IFDIR flag) -> cf = 1
 18275                              <1> ;	jnc	short namei_err ; not a sub directory !
 18276                              <1> 
 18277                              <1> 	; 27/03/2021
 18278 00004B82 E8FF000000          <1> 	call	chk_dir ; check for directory, jump to 'error' if not
 18279                              <1> 	; CPU will be here if the inode is a (valid) directory inode
 18280                              <1> 
 18281                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 18282                              <1> 	;xor	eax, eax
 18283                              <1> 	;mov	[u.off], eax ; 0
 18284                              <1> 	; 01/05/2021 - Retro UNIX 386 v2 inode structure
 18285 00004B87 A1[986C0000]        <1> 	mov	eax, [i.size]
 18286                              <1> 	;mov	ax, [i.size]
 18287 00004B8C A3[0C700000]        <1> 	mov	[u.dirp], eax
 18288                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
 18289                              <1> 		; clr u.off / u.off is file offset used by user
 18290                              <1> 	; 18/10/2021
 18291 00004B91 31C0                <1> 	xor	eax, eax
 18292                              <1> 	;mov	[u.off], eax ; 0
 18293 00004B93 BB[14700000]        <1> 	mov	ebx, u.off
 18294 00004B98 8903                <1> 	mov	[ebx], eax ; mov dword [u.off], 0
 18295                              <1> 	;
 18296 00004B9A 891D[08700000]      <1> 	mov	[u.fofp], ebx ; u.off ; 18/10/2021
 18297                              <1> 	;mov	dword [u.fofp], u.off
 18298                              <1> 			; mov $u.off,u.fofp / u.fofp is a pointer to 
 18299                              <1> 				  ; / the offset portion of fsp entry
 18300                              <1> namei_3: ; 2:
 18301 00004BA0 C705[1C700000]-     <1> 	mov	dword [u.base], u.dirbuf
 18302 00004BA6 [30700000]          <1>
 18303                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
 18304                              <1> 				    ; / copied from a directory
 18305 00004BAA C705[20700000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
 18306 00004BB2 0000                <1>
 18307                              <1>  		; mov $10.,u.count / u.count is byte count 
 18308                              <1> 				 ; / for reads and writes
 18309                              <1> 	;mov 	ax, [ii]
 18310                              <1> 	; 18/10/2021
 18311 00004BB4 A1[D06F0000]        <1> 	mov	eax, [ii] ; (32 bit inode number)
 18312                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
 18313 00004BB9 FE05[68700000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
 18314 00004BBF E8750B0000          <1>     	call	readi
 18315                              <1> 		; jsr r0,readi / read 10. bytes of file 
 18316                              <1> 		      ; with i-number (r1); i.e. read a directory entry
 18317                              <1> 
 18318 00004BC4 8B0D[24700000]      <1> 	mov 	ecx, [u.nread]
 18319 00004BCA 09C9                <1> 	or 	ecx, ecx
 18320                              <1> 		; tst u.nread
 18321 00004BCC 741A                <1> 	jz	short nib
 18322                              <1> 		; ble nib / gives error return
 18323                              <1> 	;
 18324                              <1> 	;mov 	bx, [u.dirbuf]
 18325                              <1> 	;and 	bx, bx       
 18326                              <1> 	; 18/10/2021
 18327 00004BCE 66F705[30700000]FF- <1> 	test	word [u.dirbuf], 0FFFFh
 18328 00004BD6 FF                  <1>
 18329                              <1> 		; tst u.dirbuf /
 18330 00004BD7 7513                <1> 	jnz	short namei_4
 18331                              <1> 		; bne 3f / branch when active directory entry 
 18332                              <1> 		       ; / (i-node word in entry non zero)
 18333 00004BD9 A1[14700000]        <1> 	mov	eax, [u.off]
 18334 00004BDE 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
 18335 00004BE1 A3[0C700000]        <1> 	mov	[u.dirp], eax
 18336                              <1> 		; mov u.off,u.dirp
 18337                              <1> 		; sub $10.,u.dirp
 18338 00004BE6 EBB8                <1> 	jmp	short namei_3
 18339                              <1> 		; br 2b
 18340                              <1> 
 18341                              <1> 	; 18/07/2013
 18342                              <1> nib: 
 18343 00004BE8 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
 18344 00004BEA F9                  <1> 	stc
 18345                              <1> nig:
 18346 00004BEB C3                  <1> 	retn
 18347                              <1> 
 18348                              <1> 	; 27/03/2021
 18349                              <1> ;namei_err:
 18350                              <1> 	; 16/06/2015
 18351                              <1> ;	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
 18352                              <1> ;	jmp	error
 18353                              <1> 
 18354                              <1> namei_4: ; 3:
 18355                              <1> 	; 18/10/2015
 18356                              <1> 	; 12/10/2015
 18357                              <1> 	; 21/08/2015
 18358                              <1> 	; 18/07/2015
 18359 00004BEC 8B2D[10700000]      <1> 	mov	ebp, [u.namep]
 18360                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
 18361 00004BF2 BF[32700000]        <1> 	mov 	edi, u.dirbuf + 2
 18362                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
 18363                              <1> 	; 18/10/2015
 18364 00004BF7 8B35[20710000]      <1> 	mov	esi, [nbase]
 18365                              <1> 	;mov	cx, [ncount]
 18366                              <1> 	;and	cx, cx
 18367                              <1> 	; 18/10/2021
 18368 00004BFD 8B0D[24710000]      <1> 	mov	ecx, [ncount]
 18369 00004C03 21C9                <1> 	and	ecx, ecx
 18370 00004C05 7505                <1> 	jnz	short namei_5	
 18371                              <1> 	;
 18372 00004C07 E84F000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 18373                              <1> 		; esi = physical address (page start + offset)
 18374                              <1> 		; ecx = byte count in the page
 18375                              <1> namei_5: ; 3:
 18376 00004C0C 45                  <1> 	inc	ebp ; 18/07/2015
 18377 00004C0D AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
 18378                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
 18379 00004C0E 08C0                <1> 	or 	al, al
 18380 00004C10 741C                <1> 	jz 	short namei_7
 18381                              <1> 		; beq 3f / if char is nul, then the last char in string
 18382                              <1> 			; / has been moved
 18383 00004C12 3C2F                <1> 	cmp	al, '/'
 18384                              <1> 		; cmp r4,$'/ / is char a </>
 18385 00004C14 7418                <1> 	je 	short namei_7
 18386                              <1> 		; beq 3f	
 18387                              <1> 	; 12/10/2015
 18388                              <1> 	;dec	cx ; remain byte count in the page
 18389 00004C16 49                  <1> 	dec	ecx ; 18/10/2021
 18390 00004C17 7505                <1> 	jnz	short namei_6
 18391 00004C19 E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 18392                              <1> 		; esi = physical address (page start + offset)
 18393                              <1> 		; ecx = byte count in the page
 18394                              <1> namei_6:
 18395 00004C1E 81FF[40700000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 18396                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
 18397                              <1> 				     ; / all 8 bytes of file name
 18398 00004C24 74E6                <1> 	je	short namei_5
 18399                              <1> 		; beq 3b
 18400 00004C26 AE                  <1> 	scasb	
 18401                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
 18402                              <1> 			      ; / char read from directory
 18403 00004C27 74E3                <1> 	je 	short namei_5
 18404                              <1> 		; beq 3b / branch if chars match
 18405                              <1> 
 18406 00004C29 E972FFFFFF          <1>         jmp	namei_3 ; 2b
 18407                              <1> 		; br 2b / file names do not match go to next directory entry
 18408                              <1> namei_7: ; 3:
 18409 00004C2E 81FF[40700000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 18410                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
 18411 00004C34 7409                <1> 	je	short namei_8
 18412                              <1> 		; beq 3f
 18413                              <1> 	;mov 	ah, [edi]
 18414                              <1> 	;;inc 	edi 
 18415                              <1> 	;and 	ah, ah
 18416                              <1> 	;	; tstb (r3)+ /
 18417                              <1>         ; 18/10/2021
 18418 00004C36 F607FF              <1> 	test	byte [edi], 0FFh
 18419 00004C39 0F8561FFFFFF        <1> 	jnz	namei_3
 18420                              <1> 		; bne 2b
 18421                              <1> namei_8: ; 3
 18422 00004C3F 892D[10700000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
 18423                              <1> 		; mov r2,u.namep / u.namep points to char 
 18424                              <1> 			       ; / following a / or nul
 18425                              <1> 	;mov	bx, [u.dirbuf]
 18426                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
 18427                              <1> 				; / entry to r1
 18428 00004C45 20C0                <1> 	and 	al, al
 18429                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
 18430                              <1> 		      ;  / if r4 = </> then go to next directory
 18431                              <1> 	;mov	ax, bx
 18432                              <1> 	;mov 	ax, [u.dirbuf] ; 17/06/2015
 18433                              <1>         ; 18/10/2021 (16 bit inode number in 32 bit register)
 18434 00004C47 0FB705[30700000]    <1> 	movzx	eax, word [u.dirbuf] 
 18435 00004C4E 0F8519FFFFFF        <1> 	jnz	namei_2 
 18436                              <1> 		; bne 1b
 18437                              <1> 	; AX = i-number of the file
 18438                              <1> ;;nig:
 18439 00004C54 C3                  <1> 	retn
 18440                              <1> 		; tst (r0)+ / gives non-error return
 18441                              <1> ;;nib:
 18442                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
 18443                              <1> 		       ; ax = 0 -> file not found 
 18444                              <1> ;;	stc	; 27/05/2013
 18445                              <1> ;;	retn
 18446                              <1> 		; rts r0
 18447                              <1> 
 18448                              <1> trans_addr_nmbp:
 18449                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
 18450                              <1> 	; 18/10/2015
 18451                              <1> 	; 12/10/2015
 18452 00004C55 8B2D[10700000]      <1> 	mov 	ebp, [u.namep]
 18453                              <1> trans_addr_nm: 
 18454                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
 18455                              <1> 	; Convert virtual (pathname) address to physical address
 18456                              <1> 	; (Retro UNIX 386 v1 feature only !)
 18457                              <1> 	; 18/10/2015
 18458                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
 18459                              <1> 	; 02/07/2015
 18460                              <1> 	; 17/06/2015
 18461                              <1> 	; 16/06/2015
 18462                              <1> 	;
 18463                              <1> 	; INPUTS: 
 18464                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
 18465                              <1> 	;	[u.pgdir] = user's page directory
 18466                              <1> 	; OUTPUT:
 18467                              <1> 	;       esi = physical address of the pathname
 18468                              <1> 	;	ecx = remain byte count in the page
 18469                              <1> 	;
 18470                              <1> 	; (Modified registers: EBX, ECX, EDX, ESI) ; 18/10/2021
 18471                              <1> 	;
 18472                              <1> 
 18473                              <1> 	; 18/10/2021
 18474 00004C5B 29C9                <1> 	sub	ecx, ecx
 18475                              <1> 	;
 18476                              <1>         ;cmp	dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
 18477 00004C5D 390D[5C700000]      <1> 	cmp	[u.ppgdir], ecx ; 0 ; 18/10/2021
 18478 00004C63 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
 18479                              <1> 				     ; it is already physical address
 18480 00004C65 50                  <1>    	push	eax	
 18481 00004C66 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
 18482 00004C68 E8A9E6FFFF          <1>        	call	get_physical_addr ; get physical address
 18483 00004C6D 7204                <1> 	jc	short tr_addr_nm_err
 18484                              <1> 	; 18/10/2015
 18485                              <1> 	; eax = physical address 
 18486                              <1> 	; ecx = remain byte count in page (1-4096) ; 18/10/2021
 18487                              <1> 		; 12/10/2015 (cx = [u.pncount])
 18488 00004C6F 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
 18489 00004C71 58                  <1> 	pop	eax 
 18490 00004C72 C3                  <1> 	retn
 18491                              <1> 
 18492                              <1> tr_addr_nm_err:
 18493 00004C73 A3[6A700000]        <1> 	mov	[u.error], eax
 18494                              <1> 	;pop 	eax
 18495 00004C78 E9F5EFFFFF          <1> 	jmp	error
 18496                              <1> 
 18497                              <1> trans_addr_nmk:
 18498                              <1> 	; 12/10/2015
 18499                              <1> 	; 02/07/2015
 18500 00004C7D 8B35[10700000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
 18501                              <1> 	;mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
 18502                              <1> 	; 18/10/2021
 18503 00004C83 B510                <1> 	mov	ch, PAGE_SIZE/256
 18504 00004C85 C3                  <1> 	retn
 18505                              <1> 
 18506                              <1> 
 18507                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 18508                              <1> chk_dir:
 18509                              <1> 	; 12/06/2021
 18510                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
 18511                              <1> 	; Check for directory inode
 18512                              <1> 
 18513 00004C86 8A0D[916C0000]      <1> 	mov	cl, [i.flgs+1]
 18514                              <1> 	;test	cl, 80h ; IFREG ; 80h
 18515                              <1> 	;jz	short chk_dir_err ; not a regular file ! (device!?)
 18516                              <1> 	;and	cl, 40h ; IFDIR ; 40h
 18517                              <1> 	;jz	short chk_dir_err ; not a sub directory !
 18518 00004C8C D0E1                <1> 	shl	cl, 1 ; 80h (IFREG flag) -> cf = 1
 18519 00004C8E 7305                <1> 	jnc	short chk_dir_err ; not a regular file ! (device!?)
 18520 00004C90 D0E1                <1> 	shl	cl, 1 ; 80h (IFDIR flag) -> cf = 1
 18521 00004C92 7301                <1> 	jnc	short chk_dir_err ; not a sub directory !
 18522                              <1> 	; 12/06/2021
 18523 00004C94 C3                  <1> 	retn
 18524                              <1> chk_dir_err:
 18525 00004C95 C705[6A700000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 18526 00004C9D 0000                <1>
 18527 00004C9F E9CEEFFFFF          <1> 	jmp	error
 18528                              <1> 
 18529                              <1> syschdir:
 18530                              <1> 	; / makes the directory specified in the argument
 18531                              <1> 	; / the current directory
 18532                              <1> 	;
 18533                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18534                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18535                              <1> 	;
 18536                              <1> 	; 'syschdir' makes the directory specified in its argument
 18537                              <1> 	; the current working directory.
 18538                              <1> 	;
 18539                              <1> 	; Calling sequence:
 18540                              <1> 	;	syschdir; name
 18541                              <1> 	; Arguments:
 18542                              <1> 	;	name - address of the path name of a directory
 18543                              <1> 	;	       terminated by nul byte.	
 18544                              <1> 	; Inputs: -
 18545                              <1> 	; Outputs: -
 18546                              <1> 	; ...............................................................
 18547                              <1> 	;				
 18548                              <1> 	; Retro UNIX 8086 v1 modification:
 18549                              <1> 	;	 The user/application program puts address of 
 18550                              <1> 	;	 the path name in BX register as 'syschdir' 
 18551                              <1> 	; 	 system call argument.
 18552                              <1> 
 18553 00004CA4 891D[10700000]      <1> 	mov	[u.namep], ebx
 18554                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
 18555 00004CAA E881FEFFFF          <1> 	call	namei
 18556                              <1> 		; jsr r0,namei / find its i-number
 18557                              <1> 	;jc	error
 18558                              <1> 		; br error3
 18559 00004CAF 730F                <1> 	jnc	short syschdir0
 18560                              <1> 	; 'directory not found !' error
 18561 00004CB1 C705[6A700000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
 18562 00004CB9 0000                <1>
 18563 00004CBB E9B2EFFFFF          <1> 	jmp	error
 18564                              <1> syschdir0:
 18565 00004CC0 E8FB080000          <1> 	call	access
 18566                              <1> 		; jsr r0,access; 2 / get i-node into core
 18567 00004CC5 66F705[906C0000]00- <1> 	test	word [i.flgs], 4000h
 18568 00004CCD 40                  <1>
 18569                              <1> 		; bit $40000,i.flgs / is it a directory?
 18570                              <1> 	;jz	error 
 18571                              <1> 		; beq error3 / no error
 18572 00004CCE 750F                <1> 	jnz	short syschdir1
 18573 00004CD0 C705[6A700000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 18574 00004CD8 0000                <1>
 18575 00004CDA E993EFFFFF          <1> 	jmp	error
 18576                              <1> syschdir1:
 18577 00004CDF 66A3[F86F0000]      <1> 	mov	[u.cdir], ax
 18578                              <1> 		; mov r1,u.cdir / move i-number to users 
 18579                              <1> 			      ; / current directory
 18580 00004CE5 66A1[D56F0000]      <1> 	mov	ax, [cdev]
 18581 00004CEB 66A3[FC6F0000]      <1> 	mov	[u.cdrv], ax
 18582                              <1> 		; mov cdev,u.cdev / move its device to users 
 18583                              <1> 			        ; / current device
 18584 00004CF1 E99CEFFFFF          <1> 	jmp	sysret
 18585                              <1> 		; br sysret3
 18586                              <1> 	
 18587                              <1> syschmod: ; < change mode of file >
 18588                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18589                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 18590                              <1> 	;
 18591                              <1> 	; 'syschmod' changes mode of the file whose name is given as
 18592                              <1> 	; null terminated string pointed to by 'name' has it's mode 
 18593                              <1> 	; changed to 'mode'.
 18594                              <1> 	;
 18595                              <1> 	; Calling sequence:
 18596                              <1> 	;	syschmod; name; mode
 18597                              <1> 	; Arguments:
 18598                              <1> 	;	name - address of the file name
 18599                              <1> 	;	       terminated by null byte.
 18600                              <1> 	;	mode - (new) mode/flags < attributes >
 18601                              <1> 	;	
 18602                              <1> 	; Inputs: -
 18603                              <1> 	; Outputs: -
 18604                              <1> 	; ...............................................................
 18605                              <1> 	;				
 18606                              <1> 	; Retro UNIX 8086 v1 modification: 
 18607                              <1> 	;       'syschmod' system call has two arguments; so,
 18608                              <1> 	;	* 1st argument, name is pointed to by BX register
 18609                              <1> 	;	* 2nd argument, mode is in CX register
 18610                              <1> 	;
 18611                              <1> 	; Mode bits (Flags):
 18612                              <1> 	;	bit 0 - write permission for non-owner (1)
 18613                              <1> 	;	bit 1 - read permission for non-owner (2)
 18614                              <1> 	;	bit 2 - write permission for owner (4)
 18615                              <1> 	;	bit 3 - read permission for owner (8)
 18616                              <1> 	;	bit 4 - executable flag (16) 	
 18617                              <1> 	;	bit 5 - set user ID on execution flag (32) 
 18618                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
 18619                              <1> 	;	bit 12 - large file flag (4096)
 18620                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
 18621                              <1> 	;	bit 14 - directory flag (16384)
 18622                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
 18623                              <1> 
 18624                              <1> 	; / name; mode
 18625 00004CF6 E814000000          <1> 	call	isown
 18626                              <1> 		;jsr r0,isown / get the i-node and check user status
 18627 00004CFB 66F705[906C0000]00- <1> 	test	word [i.flgs], 4000h
 18628 00004D03 40                  <1>
 18629                              <1> 		; bit	$40000,i.flgs / directory?
 18630 00004D04 7402                <1> 	jz	short syschmod1
 18631                              <1> 		; beq 2f / no
 18632                              <1> 	; AL = (new) mode
 18633 00004D06 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
 18634                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
 18635                              <1> 			   ; / executable modes
 18636                              <1> syschmod1: ; 2:
 18637 00004D08 A2[906C0000]        <1> 	mov	[i.flgs], al	
 18638                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
 18639 00004D0D EB42                <1> 	jmp	short isown1
 18640                              <1> 		; br 1f
 18641                              <1> 
 18642                              <1> isown:
 18643                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18644                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 18645                              <1> 	;
 18646                              <1> 	; 'isown' is given a file name (the 1st argument).
 18647                              <1> 	;  It find the i-number of that file via 'namei' 
 18648                              <1> 	;  then gets the i-node into core via 'iget'.
 18649                              <1> 	;  It then tests to see if the user is super user. 
 18650                              <1> 	;  If not, it cheks to see if the user is owner of 
 18651                              <1> 	;  the file. If he is not an error occurs.
 18652                              <1> 	;  If user is the owner 'setimod' is called to indicate
 18653                              <1> 	;  the inode has been modificed and the 2nd argument of
 18654                              <1> 	;  the call is put in r2.
 18655                              <1> 	;
 18656                              <1> 	; INPUTS ->
 18657                              <1> 	;    arguments of syschmod and syschown calls
 18658                              <1> 	; OUTPUTS ->
 18659                              <1> 	;    u.uid - id of user
 18660                              <1> 	;    imod - set to a 1
 18661                              <1> 	;    r2 - contains second argument of the system call				 	
 18662                              <1> 	;
 18663                              <1> 	;   ((AX=R2) output as 2nd argument)
 18664                              <1> 	;
 18665                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 18666                              <1> 	;
 18667                              <1> 		; jsr r0,arg2 / u.namep points to file name
 18668                              <1> 	;; ! 2nd argument on top of stack !
 18669                              <1> 	;; 22/06/2015 - 32 bit modifications
 18670                              <1> 	;; 07/07/2013
 18671 00004D0F 891D[10700000]      <1> 	mov	[u.namep], ebx ;; 1st argument
 18672 00004D15 51                  <1> 	push 	ecx ;; 2nd argument
 18673                              <1> 	;;
 18674 00004D16 E815FEFFFF          <1> 	call	namei
 18675                              <1> 		; jsr r0,namei / get its i-number
 18676                              <1>        ; Retro UNIX 8086 v1 modification !
 18677                              <1>        ; ax = 0 -> file not found 
 18678                              <1> 	;and	ax, ax
 18679                              <1> 	;jz	error
 18680                              <1> 	;jc	error ; 27/05/2013
 18681                              <1> 		; br error3
 18682 00004D1B 730F                <1> 	jnc	short isown0
 18683                              <1> 	; 'file not found !' error
 18684 00004D1D C705[6A700000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 18685 00004D25 0000                <1>
 18686 00004D27 E946EFFFFF          <1> 	jmp	error
 18687                              <1> isown0:
 18688 00004D2C E8A8070000          <1> 	call	iget
 18689                              <1> 		; jsr r0,iget / get i-node into core
 18690 00004D31 A0[4A700000]        <1> 	mov	al, [u.uid] ; 02/08/2013
 18691 00004D36 08C0                <1> 	or	al, al
 18692                              <1> 		; tstb u.uid / super user?
 18693 00004D38 7417                <1> 	jz	short isown1
 18694                              <1> 		; beq 1f / yes, branch
 18695 00004D3A 3A05[946C0000]      <1> 	cmp	al, [i.uid]
 18696                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
 18697                              <1> 				 ; / the file
 18698                              <1> 	;jne	error
 18699                              <1> 		; beq 1f / yes
 18700                              <1> 		; jmp error3 / no, error
 18701 00004D40 740F                <1> 	je	short isown1
 18702                              <1> 
 18703 00004D42 C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
 18704 00004D4A 0000                <1>
 18705                              <1> 			;  'permission denied !' error
 18706 00004D4C E921EFFFFF          <1> 	jmp	error
 18707                              <1> isown1: ; 1:
 18708 00004D51 E816090000          <1> 	call	setimod
 18709                              <1> 		; jsr r0,setimod / indicates 
 18710                              <1> 		;	       ; / i-node has been modified
 18711 00004D56 58                  <1> 	pop	eax ; 2nd argument
 18712                              <1> 		; mov (sp)+,r2 / mode is put in r2 
 18713                              <1> 		       ; / (u.off put on stack with 2nd arg)
 18714 00004D57 C3                  <1> 	retn
 18715                              <1> 		; rts r0
 18716                              <1> 
 18717                              <1> ;;arg:  ; < get system call arguments >
 18718                              <1> 	; 'arg' extracts an argument for a routine whose call is 
 18719                              <1> 	; of form:
 18720                              <1> 	;	sys 'routine' ; arg1
 18721                              <1> 	;		or
 18722                              <1> 	;	sys 'routine' ; arg1 ; arg2
 18723                              <1> 	;		or
 18724                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
 18725                              <1> 	;	
 18726                              <1> 	; INPUTS ->
 18727                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
 18728                              <1> 	;	This pointers's value is actually the value of
 18729                              <1> 	;	update pc at the the trap to sysent (unkni) is
 18730                              <1> 	;	made to process the sys instruction
 18731                              <1> 	;    r0 - contains the return address for the routine
 18732                              <1> 	;	that called arg. The data in the word pointer 
 18733                              <1> 	;	to by the return address is used as address
 18734                              <1> 	;	in which the extracted argument is stored   		
 18735                              <1> 	;    	
 18736                              <1> 	; OUTPUTS ->
 18737                              <1> 	;    'address' - contains the extracted argument 
 18738                              <1> 	;    u.sp+18 - is incremented by 2 
 18739                              <1> 	;    r1 - contains the extracted argument
 18740                              <1> 	;    r0 - points to the next instruction to be
 18741                              <1> 	;	 executed in the calling routine.
 18742                              <1> 	;
 18743                              <1>   
 18744                              <1> 	; mov u.sp,r1
 18745                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
 18746                              <1> 			; / into argument of arg2
 18747                              <1> 	; add $2,18.(r1) / point pc on stack 
 18748                              <1> 			      ; / to next system argument
 18749                              <1> 	; rts r0
 18750                              <1> 
 18751                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
 18752                              <1> 	; 'arg2' takes first argument in system call
 18753                              <1> 	;  (pointer to name of the file) and puts it in location
 18754                              <1> 	;  u.namep; takes second argument and puts it in u.off
 18755                              <1> 	;  and on top of the stack
 18756                              <1> 	;	
 18757                              <1> 	; INPUTS ->
 18758                              <1> 	;    u.sp, r0
 18759                              <1> 	;    	
 18760                              <1> 	; OUTPUTS ->
 18761                              <1> 	;    u.namep
 18762                              <1> 	;    u.off 
 18763                              <1> 	;    u.off pushed on stack
 18764                              <1> 	;    r1
 18765                              <1> 	;
 18766                              <1> 
 18767                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
 18768                              <1> 				; / first arg in sys call
 18769                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
 18770                              <1> 				; / second arg in sys call
 18771                              <1> 	; mov r0,r1 / r0 points to calling routine
 18772                              <1> 	; mov (sp),r0 / put operation code back in r0
 18773                              <1> 	; mov u.off,(sp) / put pointer to second argument 
 18774                              <1> 			; / on stack
 18775                              <1> 	; jmp (r1) / return to calling routine
 18776                              <1> 
 18777                              <1> syschown: ; < change owner of file >
 18778                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18779                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18780                              <1> 	;
 18781                              <1> 	; 'syschown' changes the owner of the file whose name is given
 18782                              <1> 	; as null terminated string pointed to by 'name' has it's owner
 18783                              <1> 	; changed to 'owner'
 18784                              <1> 	;
 18785                              <1> 	; Calling sequence:
 18786                              <1> 	;	syschown; name; owner
 18787                              <1> 	; Arguments:
 18788                              <1> 	;	name - address of the file name
 18789                              <1> 	;	       terminated by null byte.
 18790                              <1> 	;	owner - (new) owner (number/ID)
 18791                              <1> 	;	
 18792                              <1> 	; Inputs: -
 18793                              <1> 	; Outputs: -
 18794                              <1> 	; ...............................................................
 18795                              <1> 	;				
 18796                              <1> 	; Retro UNIX 8086 v1 modification: 
 18797                              <1> 	;       'syschown' system call has two arguments; so,
 18798                              <1> 	;	* 1st argument, name is pointed to by BX register
 18799                              <1> 	;	* 2nd argument, owner number is in CX register
 18800                              <1> 	;
 18801                              <1> 	; / name; owner
 18802 00004D58 E8B2FFFFFF          <1> 	call	isown
 18803                              <1> 		; jsr r0,isown / get the i-node and check user status
 18804 00004D5D 803D[4A700000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
 18805                              <1> 		; tstb u.uid / super user
 18806 00004D64 7418                <1> 	jz	short syschown1
 18807                              <1> 		; beq 2f / yes, 2f
 18808 00004D66 F605[906C0000]20    <1>         test    byte [i.flgs], 20h ; 32
 18809                              <1> 		; bit $40,i.flgs / no, set userid on execution?
 18810                              <1> 	;jnz	error
 18811                              <1> 		; bne 3f / yes error, could create Trojan Horses
 18812 00004D6D 740F                <1> 	jz	short syschown1
 18813                              <1> 	; 'permission denied !'
 18814 00004D6F C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
 18815 00004D77 0000                <1>
 18816 00004D79 E9F4EEFFFF          <1> 	jmp	error
 18817                              <1> syschown1: ; 2:
 18818                              <1> 	; AL = owner (number/ID)
 18819 00004D7E A2[946C0000]        <1> 	mov	[i.uid], al ; 23/06/2015
 18820                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
 18821                              <1> 			       ; / in the i-node
 18822 00004D83 E90AEFFFFF          <1> 	jmp	sysret
 18823                              <1> 	; 1: 
 18824                              <1> 		; jmp sysret4
 18825                              <1> 	; 3:
 18826                              <1> 		; jmp	error
 18827                              <1> 
 18828                              <1> systime: ; / get time of year
 18829                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18830                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 18831                              <1> 	;
 18832                              <1> 	; 20/06/2013
 18833                              <1> 	; 'systime' gets the time of the year.
 18834                              <1> 	; The present time is put on the stack.
 18835                              <1> 	;
 18836                              <1> 	; Calling sequence:
 18837                              <1> 	;	systime
 18838                              <1> 	; Arguments: -
 18839                              <1> 	;	
 18840                              <1> 	; Inputs: -
 18841                              <1> 	; Outputs: sp+2, sp+4 - present time
 18842                              <1> 	; ...............................................................
 18843                              <1> 	;	
 18844                              <1> 	; Retro UNIX 8086 v1 modification: 
 18845                              <1> 	;       'systime' system call will return to the user
 18846                              <1> 	;	with unix time (epoch) in DX:AX register pair
 18847                              <1> 	;
 18848                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
 18849                              <1> 	;	system call for PC compatibility !!		 	
 18850                              <1> 
 18851 00004D88 E821EAFFFF          <1> 	call 	epoch
 18852 00004D8D A3[F46F0000]        <1> 	mov 	[u.r0], eax
 18853                              <1> 		; mov s.time,4(sp)
 18854                              <1> 		; mov s.time+2,2(sp) / put the present time 
 18855                              <1> 				   ; / on the stack
 18856                              <1> 		; br sysret4
 18857 00004D92 E9FBEEFFFF          <1> 	jmp	sysret 
 18858                              <1> 
 18859                              <1> sysstime: ; / set time
 18860                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18861                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18862                              <1> 	;
 18863                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
 18864                              <1> 	;
 18865                              <1> 	; Calling sequence:
 18866                              <1> 	;	sysstime
 18867                              <1> 	; Arguments: -
 18868                              <1> 	;	
 18869                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
 18870                              <1> 	; Outputs: -
 18871                              <1> 	; ...............................................................
 18872                              <1> 	;	
 18873                              <1> 	; Retro UNIX 8086 v1 modification: 
 18874                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
 18875                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
 18876                              <1> 	; 
 18877                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 18878                              <1> 	;	to get sysstime system call arguments from the user;
 18879                              <1> 	;	* 1st argument, lowword of unix time is in BX register
 18880                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
 18881                              <1> 	;
 18882                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
 18883                              <1> 	;	system call for PC compatibility !!	
 18884                              <1> 
 18885 00004D97 803D[4A700000]00    <1> 	cmp	byte [u.uid], 0
 18886                              <1> 		; tstb u.uid / is user the super user
 18887                              <1> 	;ja	error
 18888                              <1> 		; bne error4 / no, error
 18889 00004D9E 760F                <1> 	jna	short systime1
 18890                              <1> 	; 'permission denied !'
 18891 00004DA0 C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
 18892 00004DA8 0000                <1>
 18893 00004DAA E9C3EEFFFF          <1> 	jmp	error
 18894                              <1> systime1:
 18895                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
 18896                              <1> 	; EBX = unix (epoch) time (from user)
 18897 00004DAF 89D8                <1> 	mov	eax, ebx
 18898 00004DB1 E87AEBFFFF          <1> 	call 	set_date_time
 18899                              <1> 		; mov 4(sp),s.time
 18900                              <1> 		; mov 2(sp),s.time+2 / set the system time
 18901 00004DB6 E9D7EEFFFF          <1> 	jmp	sysret
 18902                              <1> 		; br sysret4
 18903                              <1> 
 18904                              <1> sysbreak:
 18905                              <1> 	; 18/10/2015
 18906                              <1> 	; 07/10/2015
 18907                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18908                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
 18909                              <1> 	;
 18910                              <1> 	; 'sysbreak' sets the programs break points. 
 18911                              <1> 	; It checks the current break point (u.break) to see if it is
 18912                              <1> 	; between "core" and the stack (sp). If it is, it is made an
 18913                              <1> 	; even address (if it was odd) and the area between u.break
 18914                              <1> 	; and the stack is cleared. The new breakpoint is then put
 18915                              <1> 	; in u.break and control is passed to 'sysret'.
 18916                              <1> 	;
 18917                              <1> 	; Calling sequence:
 18918                              <1> 	;	sysbreak; addr
 18919                              <1> 	; Arguments: -
 18920                              <1> 	;	
 18921                              <1> 	; Inputs: u.break - current breakpoint
 18922                              <1> 	; Outputs: u.break - new breakpoint 
 18923                              <1> 	;	area between old u.break and the stack (sp) is cleared.
 18924                              <1> 	; ...............................................................
 18925                              <1> 	;	
 18926                              <1> 	; Retro UNIX 8086 v1 modification:
 18927                              <1> 	;	The user/application program puts breakpoint address
 18928                              <1> 	;       in BX register as 'sysbreak' system call argument.
 18929                              <1> 	; 	(argument transfer method 1)
 18930                              <1> 	;
 18931                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
 18932                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
 18933                              <1> 	;  NOTE:
 18934                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
 18935                              <1> 	;	'u.break' address) of user's memory for original unix's
 18936                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
 18937                              <1> 
 18938                              <1> 		; mov u.break,r1 / move users break point to r1
 18939                              <1> 		; cmp r1,$core / is it the same or lower than core?
 18940                              <1> 		; blos 1f / yes, 1f
 18941                              <1> 	; 23/06/2015
 18942 00004DBB 8B2D[28700000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
 18943                              <1> 	;and	ebp, ebp
 18944                              <1> 	;jz	short sysbreak_3 
 18945                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
 18946                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
 18947 00004DC1 8B15[EC6F0000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
 18948 00004DC7 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
 18949                              <1> 	; 07/10/2015
 18950 00004DCA 891D[28700000]      <1> 	mov	[u.break], ebx ; virtual address !!!
 18951                              <1> 	;
 18952 00004DD0 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
 18953                              <1> 			   ; with top of user's stack (virtual!)
 18954 00004DD2 7327                <1> 	jnb	short sysbreak_3
 18955                              <1> 		; cmp r1,sp / is it the same or higher 
 18956                              <1> 			  ; / than the stack?
 18957                              <1> 		; bhis 1f / yes, 1f
 18958 00004DD4 89DE                <1> 	mov	esi, ebx
 18959 00004DD6 29EE                <1> 	sub	esi, ebp ; new break point - old break point
 18960 00004DD8 7621                <1> 	jna	short sysbreak_3 
 18961                              <1> 	;push	ebx
 18962                              <1> sysbreak_1:
 18963 00004DDA 89EB                <1> 	mov	ebx, ebp  
 18964 00004DDC E835E5FFFF          <1> 	call	get_physical_addr ; get physical address
 18965 00004DE1 0F828CFEFFFF        <1> 	jc	tr_addr_nm_err
 18966                              <1> 	; 18/10/2015
 18967 00004DE7 89C7                <1> 	mov	edi, eax 
 18968 00004DE9 29C0                <1> 	sub	eax, eax ; 0
 18969                              <1> 		 ; ECX = remain byte count in page (1-4096)
 18970 00004DEB 39CE                <1> 	cmp	esi, ecx
 18971 00004DED 7302                <1> 	jnb	short sysbreak_2
 18972 00004DEF 89F1                <1> 	mov	ecx, esi
 18973                              <1> sysbreak_2:
 18974 00004DF1 29CE                <1> 	sub	esi, ecx
 18975 00004DF3 01CD                <1> 	add	ebp, ecx
 18976 00004DF5 F3AA                <1> 	rep 	stosb
 18977 00004DF7 09F6                <1> 	or	esi, esi
 18978 00004DF9 75DF                <1> 	jnz	short sysbreak_1
 18979                              <1> 	;
 18980                              <1> 		; bit $1,r1 / is it an odd address
 18981                              <1> 		; beq 2f / no, its even
 18982                              <1> 		; clrb (r1)+ / yes, make it even
 18983                              <1> 	; 2: / clear area between the break point and the stack
 18984                              <1> 		; cmp r1,sp / is it higher or same than the stack
 18985                              <1> 		; bhis 1f / yes, quit
 18986                              <1> 		; clr (r1)+ / clear word
 18987                              <1> 		; br 2b / go back
 18988                              <1> 	;pop	ebx
 18989                              <1> sysbreak_3: ; 1:
 18990                              <1> 	;mov	[u.break], ebx ; virtual address !!!
 18991                              <1> 		; jsr r0,arg; u.break / put the "address" 
 18992                              <1> 			; / in u.break (set new break point)
 18993                              <1> 		; br sysret4 / br sysret
 18994 00004DFB E992EEFFFF          <1> 	jmp	sysret
 18995                              <1> 
 18996                              <1> 
 18997                              <1> maknod: 
 18998                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18999                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 19000                              <1> 	;
 19001                              <1> 	; 'maknod' creates an i-node and makes a directory entry
 19002                              <1> 	; for this i-node in the current directory.
 19003                              <1> 	;
 19004                              <1> 	; INPUTS ->
 19005                              <1> 	;    r1 - contains mode
 19006                              <1> 	;    ii - current directory's i-number	
 19007                              <1> 	;    	
 19008                              <1> 	; OUTPUTS ->
 19009                              <1> 	;    u.dirbuf - contains i-number of free i-node 
 19010                              <1> 	;    i.flgs - flags in new i-node 
 19011                              <1> 	;    i.uid - filled with u.uid
 19012                              <1> 	;    i.nlks - 1 is put in the number of links
 19013                              <1> 	;    i.ctim - creation time				
 19014                              <1> 	;    i.ctim+2 - modification time
 19015                              <1> 	;    imod - set via call to setimod
 19016                              <1> 	;	
 19017                              <1> 	; ((AX = R1)) input
 19018                              <1> 	;
 19019                              <1> 	; (Retro UNIX Prototype : 
 19020                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
 19021                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 19022                              <1> 
 19023                              <1> 	; / r1 contains the mode
 19024 00004E00 80CC80              <1> 	or 	ah, 80h  ; 10000000b
 19025                              <1> 		; bis	$100000,r1 / allocate flag set
 19026 00004E03 6650                <1> 	push	ax
 19027                              <1> 		; mov r1,-(sp) / put mode on stack
 19028                              <1> 	; 31/07/2013
 19029 00004E05 66A1[D06F0000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
 19030                              <1> 		; mov ii,r1 / move current i-number to r1
 19031 00004E0B B201                <1> 	mov	dl, 1 ; owner flag mask
 19032 00004E0D E8AE070000          <1> 	call	access	
 19033                              <1> 		; jsr r0,access; 1 / get its i-node into core
 19034 00004E12 6650                <1> 	push	ax
 19035                              <1> 		; mov r1,-(sp) / put i-number on stack
 19036 00004E14 66B82800            <1> 	mov	ax, 40
 19037                              <1> 		; mov $40.,r1 / r1 = 40
 19038                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
 19039 00004E18 6640                <1> 	inc	ax
 19040                              <1> 		; inc r1 / r1 = r1 + 1
 19041 00004E1A E8E6080000          <1> 	call	imap
 19042                              <1> 		; jsr r0,imap / get byte address and bit position in 
 19043                              <1> 			    ; /	inode map in r2 & m
 19044                              <1>           ; DX (MQ) has a 1 in the calculated bit position
 19045                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
 19046                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
 19047                              <1> 	;	       Inode count must be checked here
 19048                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
 19049 00004E1F 8413                <1> 	test	[ebx], dl
 19050                              <1> 		; bitb mq,(r2) / is the i-node active
 19051 00004E21 75F5                <1> 	jnz	short maknod1
 19052                              <1> 		; bne 1b / yes, try the next one
 19053 00004E23 0813                <1> 	or	[ebx], dl
 19054                              <1> 		; bisb mq,(r2) / no, make it active 
 19055                              <1> 			     ; / (put a 1 in the bit map)
 19056 00004E25 E8AF060000          <1> 	call	iget
 19057                              <1> 		; jsr r0,iget / get i-node into core
 19058 00004E2A 66F705[906C0000]00- <1> 	test	word [i.flgs], 8000h 
 19059 00004E32 80                  <1>
 19060                              <1> 		; tst i.flgs / is i-node already allocated
 19061 00004E33 75E3                <1> 	jnz	short maknod1	
 19062                              <1> 		; blt 1b / yes, look for another one
 19063 00004E35 66A3[30700000]      <1> 	mov	[u.dirbuf], ax
 19064                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
 19065 00004E3B 6658                <1> 	pop	ax
 19066                              <1> 		; mov (sp)+,r1 / get current i-number back
 19067 00004E3D E897060000          <1> 	call	iget
 19068                              <1> 		; jsr r0,iget / get i-node in core
 19069 00004E42 E87BF7FFFF          <1> 	call	mkdir
 19070                              <1> 		; jsr r0,mkdir / make a directory entry 
 19071                              <1> 			     ; / in current directory
 19072 00004E47 66A1[30700000]      <1> 	mov	ax, [u.dirbuf]
 19073                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
 19074 00004E4D E887060000          <1> 	call	iget
 19075                              <1> 		; jsr r0,iget / get it into core
 19076                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
 19077 00004E52 B908000000          <1> 	mov	ecx, 8 
 19078 00004E57 31C0                <1> 	xor	eax, eax ; 0
 19079 00004E59 BF[906C0000]        <1> 	mov	edi, inode 
 19080 00004E5E F3AB                <1> 	rep	stosd
 19081                              <1> 	;
 19082 00004E60 668F05[906C0000]    <1> 	pop	word [i.flgs]
 19083                              <1> 		; mov (sp)+,i.flgs / fill flags
 19084 00004E67 8A0D[4A700000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
 19085 00004E6D 880D[946C0000]      <1> 	mov 	[i.uid], cl
 19086                              <1> 		; movb u.uid,i.uid / user id	
 19087 00004E73 C605[926C0000]01    <1> 	mov     byte [i.nlks], 1
 19088                              <1> 		; movb $1,i.nlks / 1 link
 19089                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
 19090                              <1> 	;mov	eax, [s.time]
 19091                              <1> 	;mov 	[i.ctim], eax
 19092                              <1> 	 	; mov s.time,i.ctim / time created
 19093                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
 19094                              <1> 	; Retro UNIX 8086 v1 modification !
 19095                              <1> 	; i.ctime=0, i.ctime+2=0 and
 19096                              <1>         ; 'setimod' will set ctime of file via 'epoch'
 19097 00004E7A E8ED070000          <1> 	call setimod
 19098                              <1> 		; jsr r0,setimod / set modified flag
 19099 00004E7F C3                  <1> 	retn
 19100                              <1> 		; rts r0 / return
 19101                              <1> 
 19102                              <1> sysseek: ; / moves read write pointer in an fsp entry
 19103                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19104                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 19105                              <1> 	;
 19106                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
 19107                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
 19108                              <1> 	; The file descriptor refers to a file open for reading or
 19109                              <1> 	; writing. The read (or write) pointer is set as follows:
 19110                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
 19111                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
 19112                              <1> 	;	  current location plus offset.
 19113                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
 19114                              <1> 	;	  size of file plus offset.
 19115                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
 19116                              <1> 	;
 19117                              <1> 	; Calling sequence:
 19118                              <1> 	;	sysseek; offset; ptrname
 19119                              <1> 	; Arguments:
 19120                              <1> 	;	offset - number of bytes desired to move 
 19121                              <1> 	;		 the r/w pointer
 19122                              <1> 	;	ptrname - a switch indicated above
 19123                              <1> 	;
 19124                              <1> 	; Inputs: r0 - file descriptor 
 19125                              <1> 	; Outputs: -
 19126                              <1> 	; ...............................................................
 19127                              <1> 	;	
 19128                              <1> 	; Retro UNIX 8086 v1 modification: 
 19129                              <1> 	;       'sysseek' system call has three arguments; so,
 19130                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
 19131                              <1> 	;	* 2nd argument, offset is in CX register
 19132                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
 19133                              <1> 	;	
 19134                              <1> 
 19135 00004E80 E823000000          <1> 	call	seektell
 19136                              <1> 	; AX = u.count
 19137                              <1> 	; BX = *u.fofp
 19138                              <1> 		; jsr r0,seektell / get proper value in u.count
 19139                              <1> 		; add u.base,u.count / add u.base to it
 19140 00004E85 0305[1C700000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
 19141 00004E8B 8903                <1> 	mov	[ebx], eax
 19142                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
 19143 00004E8D E900EEFFFF          <1> 	jmp	sysret
 19144                              <1> 		; br sysret4
 19145                              <1> 
 19146                              <1> systell: ; / get the r/w pointer
 19147                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19148                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 19149                              <1> 	;
 19150                              <1> 	; Retro UNIX 8086 v1 modification:
 19151                              <1> 	; ! 'systell' does not work in original UNIX v1,
 19152                              <1> 	; 	    it returns with error !
 19153                              <1> 	; Inputs: r0 - file descriptor 
 19154                              <1> 	; Outputs: r0 - file r/w pointer
 19155                              <1> 
 19156                              <1> 	;xor	ecx, ecx ; 0
 19157 00004E92 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
 19158                              <1> 	;call 	seektell
 19159 00004E97 E812000000          <1> 	call 	seektell0 ; 05/08/2013
 19160                              <1> 	;mov	ebx, [u.fofp]
 19161 00004E9C 8B03                <1> 	mov	eax, [ebx]
 19162 00004E9E A3[F46F0000]        <1> 	mov	[u.r0], eax
 19163 00004EA3 E9EAEDFFFF          <1> 	jmp	sysret
 19164                              <1> 
 19165                              <1> ; Original unix v1 'systell' system call:
 19166                              <1> 		; jsr r0,seektell
 19167                              <1> 		; br error4
 19168                              <1> 
 19169                              <1> seektell:
 19170                              <1> 	; 03/01/2016
 19171                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19172                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 19173                              <1> 	;
 19174                              <1> 	; 'seektell' puts the arguments from sysseek and systell
 19175                              <1> 	; call in u.base and u.count. It then gets the i-number of
 19176                              <1> 	; the file from the file descriptor in u.r0 and by calling
 19177                              <1> 	; getf. The i-node is brought into core and then u.count
 19178                              <1> 	; is checked to see it is a 0, 1, or 2.
 19179                              <1> 	; If it is 0 - u.count stays the same
 19180                              <1> 	;          1 - u.count = offset (u.fofp)
 19181                              <1> 	;	   2 - u.count = i.size (size of file)
 19182                              <1> 	; 	 		
 19183                              <1> 	; !! Retro UNIX 8086 v1 modification:
 19184                              <1> 	;	Argument 1, file descriptor is in BX;
 19185                              <1> 	;	Argument 2, offset is in CX;
 19186                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
 19187                              <1> 	;
 19188                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
 19189                              <1> 	; call 	arg
 19190                              <1> 	;
 19191                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
 19192                              <1> 	;
 19193 00004EA8 890D[1C700000]      <1> 	mov 	[u.base], ecx ; offset
 19194                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
 19195                              <1> seektell0:
 19196 00004EAE 8915[20700000]      <1> 	mov 	[u.count], edx
 19197                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
 19198                              <1> 	; mov	ax, bx
 19199                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
 19200                              <1> 			     ; / (index in u.fp list)
 19201                              <1> 	; call	getf
 19202                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
 19203                              <1> 	; BX = file descriptor (file number)
 19204 00004EB4 E840FCFFFF          <1> 	call	getf1
 19205 00004EB9 6609C0              <1> 	or	ax, ax ; i-number of the file
 19206                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
 19207                              <1> 		             ; / put it on the stack
 19208                              <1> 	;jz	error
 19209                              <1> 		; beq error4 / if i-number is 0, not active so error
 19210 00004EBC 750F                <1> 	jnz	short seektell1
 19211 00004EBE C705[6A700000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 19212 00004EC6 0000                <1>
 19213 00004EC8 E9A5EDFFFF          <1> 	jmp	error
 19214                              <1> seektell1:
 19215                              <1> 	;push	eax
 19216 00004ECD 80FC80              <1> 	cmp	ah, 80h
 19217 00004ED0 7203                <1> 	jb	short seektell2
 19218                              <1> 		; bgt .+4 / if its positive jump
 19219 00004ED2 66F7D8              <1> 	neg	ax
 19220                              <1> 		; neg r1 / if not make it positive
 19221                              <1> seektell2:
 19222 00004ED5 E8FF050000          <1> 	call	iget
 19223                              <1> 		; jsr r0,iget / get its i-node into core
 19224 00004EDA 8B1D[08700000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
 19225 00004EE0 803D[20700000]01    <1> 	cmp	byte [u.count], 1
 19226                              <1> 		; cmp u.count,$1 / is ptr name =1
 19227 00004EE7 7705                <1> 	ja	short seektell3
 19228                              <1> 		; blt 2f / no its zero
 19229 00004EE9 740A                <1> 	je	short seektell_4
 19230                              <1> 		; beq 1f / yes its 1
 19231 00004EEB 31C0                <1> 	xor	eax, eax
 19232                              <1> 	;jmp	short seektell_5
 19233 00004EED C3                  <1> 	retn
 19234                              <1> seektell3:
 19235                              <1> 	; 03/01/2016
 19236                              <1> 	;movzx	eax, word [i.size]
 19237 00004EEE 66A1[986C0000]      <1>         mov   	ax, [i.size]
 19238                              <1>                 ; mov i.size,u.count /  put number of bytes 
 19239                              <1>                                    ; / in file in u.count
 19240                              <1> 	;jmp	short seektell_5
 19241                              <1> 		; br 2f
 19242 00004EF4 C3                  <1> 	retn
 19243                              <1> seektell_4: ; 1: / ptrname =1
 19244                              <1> 	;mov	ebx, [u.fofp]
 19245 00004EF5 8B03                <1> 	mov	eax, [ebx]
 19246                              <1> 		; mov *u.fofp,u.count / put offset in u.count
 19247                              <1> ;seektell_5: ; 2: / ptrname =0
 19248                              <1> 	;mov	[u.count], eax
 19249                              <1> 	;pop	eax 
 19250                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
 19251 00004EF7 C3                  <1> 	retn
 19252                              <1> 		; rts r0
 19253                              <1> 
 19254                              <1> sysintr: ; / set interrupt handling
 19255                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19256                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 19257                              <1> 	;
 19258                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
 19259                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
 19260                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
 19261                              <1> 	; If one does the interrupt character in the tty buffer is
 19262                              <1> 	; cleared and 'sysret'is called. If one does not exits
 19263                              <1> 	; 'sysret' is just called.	
 19264                              <1> 	;
 19265                              <1> 	; Calling sequence:
 19266                              <1> 	;	sysintr; arg
 19267                              <1> 	; Argument:
 19268                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
 19269                              <1> 	;	    - if 1, intterupts cause their normal result
 19270                              <1> 	;		 i.e force an exit.
 19271                              <1> 	;	    - if arg is a location within the program,
 19272                              <1> 	;		control is passed to that location when
 19273                              <1> 	;		an interrupt occurs.	
 19274                              <1> 	; Inputs: -
 19275                              <1> 	; Outputs: -
 19276                              <1> 	; ...............................................................
 19277                              <1> 	;	
 19278                              <1> 	; Retro UNIX 8086 v1 modification: 
 19279                              <1> 	;       'sysintr' system call sets u.intr to value of BX
 19280                              <1> 	;	then branches into sysquit.
 19281                              <1> 	;
 19282 00004EF8 66891D[44700000]    <1> 	mov	[u.intr], bx
 19283                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
 19284                              <1> 		; br 1f / go into quit routine
 19285 00004EFF E98EEDFFFF          <1> 	jmp	sysret
 19286                              <1> 
 19287                              <1> sysquit:
 19288                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19289                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 19290                              <1> 	;
 19291                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
 19292                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
 19293                              <1> 	; tty exists. If one does the interrupt character in the tty
 19294                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
 19295                              <1> 	; 'sysret' is just called.	
 19296                              <1> 	;
 19297                              <1> 	; Calling sequence:
 19298                              <1> 	;	sysquit; arg
 19299                              <1> 	; Argument:
 19300                              <1> 	;	arg - if 0, this call diables quit signals from the
 19301                              <1> 	;		typewriter (ASCII FS)
 19302                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
 19303                              <1> 	;		cease and a core image to be produced.
 19304                              <1> 	;		 i.e force an exit.
 19305                              <1> 	;	    - if arg is an addres in the program,
 19306                              <1> 	;		a quit causes control to sent to that
 19307                              <1> 	;		location.	
 19308                              <1> 	; Inputs: -
 19309                              <1> 	; Outputs: -
 19310                              <1> 	; ...............................................................
 19311                              <1> 	;	
 19312                              <1> 	; Retro UNIX 8086 v1 modification: 
 19313                              <1> 	;       'sysquit' system call sets u.quit to value of BX
 19314                              <1> 	;	then branches into 'sysret'.
 19315                              <1> 	;
 19316 00004F04 66891D[46700000]    <1> 	mov	[u.quit], bx
 19317 00004F0B E982EDFFFF          <1> 	jmp	sysret
 19318                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
 19319                              <1> 	;1:
 19320                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
 19321                              <1> 			      ; / to r1
 19322                              <1> 		; beq sysret4 / return to user
 19323                              <1> 		; clrb 6(r1) / clear the interrupt character 
 19324                              <1> 			   ; / in the tty buffer
 19325                              <1> 		; br sysret4 / return to user
 19326                              <1> 
 19327                              <1> syssetuid: ; / set process id
 19328                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19329                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 19330                              <1> 	;
 19331                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
 19332                              <1> 	; to the process id in (u.r0). Both the effective user and 
 19333                              <1> 	; u.uid and the real user u.ruid are set to this. 
 19334                              <1> 	; Only the super user can make this call.	
 19335                              <1> 	;
 19336                              <1> 	; Calling sequence:
 19337                              <1> 	;	syssetuid
 19338                              <1> 	; Arguments: -
 19339                              <1> 	;
 19340                              <1> 	; Inputs: (u.r0) - contains the process id.
 19341                              <1> 	; Outputs: -
 19342                              <1> 	; ...............................................................
 19343                              <1> 	;	
 19344                              <1> 	; Retro UNIX 8086 v1 modification: 
 19345                              <1> 	;       BL contains the (new) user ID of the current process
 19346                              <1> 
 19347                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
 19348 00004F10 3A1D[4C700000]      <1> 	cmp	bl, [u.ruid] 
 19349                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
 19350                              <1> 			       ; / id number
 19351 00004F16 741E                <1> 	je	short setuid1
 19352                              <1> 		; beq 1f / yes
 19353 00004F18 803D[4A700000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 19354                              <1> 		; tstb u.uid / no, is current user the super user?
 19355                              <1> 	;ja	error
 19356                              <1> 		; bne error4 / no, error
 19357 00004F1F 760F                <1> 	jna	short setuid0
 19358 00004F21 C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
 19359 00004F29 0000                <1>
 19360                              <1> 				;  'permission denied !' error
 19361 00004F2B E942EDFFFF          <1> 	jmp	error
 19362                              <1> setuid0:
 19363 00004F30 881D[4C700000]      <1> 	mov	[u.ruid], bl
 19364                              <1> setuid1: ; 1:
 19365 00004F36 881D[4A700000]      <1> 	mov	[u.uid], bl ; 02/08/2013
 19366                              <1> 		; movb r1,u.uid / put process id in u.uid
 19367                              <1> 		; movb r1,u.ruid / put process id in u.ruid
 19368 00004F3C E951EDFFFF          <1> 	jmp	sysret
 19369                              <1> 		; br sysret4 / system return
 19370                              <1> 
 19371                              <1> sysgetuid: ; < get user id >
 19372                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19373                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 19374                              <1> 	;
 19375                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
 19376                              <1> 	; The real user ID identifies the person who is logged in,
 19377                              <1> 	; in contradistinction to the effective user ID, which
 19378                              <1> 	; determines his access permission at each moment. It is thus
 19379                              <1> 	; useful to programs which operate using the 'set user ID'
 19380                              <1> 	; mode, to find out who invoked them.	
 19381                              <1> 	;
 19382                              <1> 	; Calling sequence:
 19383                              <1> 	;	syssetuid
 19384                              <1> 	; Arguments: -
 19385                              <1> 	;
 19386                              <1> 	; Inputs: -
 19387                              <1> 	; Outputs: (u.r0) - contains the real user's id.
 19388                              <1> 	; ...............................................................
 19389                              <1> 	;	
 19390                              <1> 	; Retro UNIX 8086 v1 modification: 
 19391                              <1> 	;       AL contains the real user ID at return.
 19392                              <1> 	;
 19393 00004F41 0FB605[4C700000]    <1> 	movzx 	eax, byte [u.ruid]
 19394 00004F48 A3[F46F0000]        <1> 	mov	[u.r0], eax
 19395                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
 19396 00004F4D E940EDFFFF          <1> 	jmp	sysret
 19397                              <1> 		; br sysret4 / systerm return, sysret
 19398                              <1> 
 19399                              <1> anyi: 
 19400                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 19401                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19402                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
 19403                              <1> 	;
 19404                              <1> 	; 'anyi' is called if a file deleted while open.
 19405                              <1> 	; "anyi" checks to see if someone else has opened this file.
 19406                              <1> 	;
 19407                              <1> 	; INPUTS ->
 19408                              <1> 	;    r1 - contains an i-number
 19409                              <1> 	;    fsp - start of table containing open files
 19410                              <1> 	;
 19411                              <1> 	; OUTPUTS ->
 19412                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
 19413                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
 19414                              <1> 	;    if file not found - bit in i-node map is cleared
 19415                              <1> 	;    			 (i-node is freed)
 19416                              <1> 	;               all blocks related to i-node are freed
 19417                              <1> 	;	        all flags in i-node are cleared
 19418                              <1> 	; ((AX = R1)) input
 19419                              <1> 	;
 19420                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 19421                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 19422                              <1> 	;
 19423                              <1> 		; / r1 contains an i-number
 19424 00004F52 BB[906C0000]        <1> 	mov	ebx, fsp
 19425                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
 19426                              <1> anyi_1: ; 1:
 19427 00004F57 663B03              <1> 	cmp	ax, [ebx]
 19428                              <1> 		; cmp r1,(r2) / do i-numbers match?
 19429 00004F5A 7433                <1> 	je	short anyi_3
 19430                              <1> 		; beq 1f / yes, 1f
 19431 00004F5C 66F7D8              <1> 	neg	ax
 19432                              <1> 		; neg r1 / no complement r1
 19433 00004F5F 663B03              <1> 	cmp	ax, [ebx]
 19434                              <1> 		; cmp r1,(r2) / do they match now?
 19435 00004F62 742B                <1> 	je	short anyi_3
 19436                              <1> 		; beq 1f / yes, transfer
 19437                              <1> 		; / i-numbers do not match
 19438 00004F64 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
 19439                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
 19440                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
 19441                              <1> 	; 22/11/2021
 19442 00004F67 81FB[B06F0000]      <1> 	cmp	ebx, fsp + (NFILES*fp.size) ; fsp+(NFILES*16)
 19443                              <1> 	;cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
 19444                              <1> 		; cmp r2,$fsp+[nfiles*8] 
 19445                              <1> 				; / are we at last entry in the table
 19446 00004F6D 72E8                <1> 	jb	short anyi_1
 19447                              <1> 		; blt 1b / no, check next entries i-number
 19448                              <1> 	;cmp	ax, 32768
 19449 00004F6F 80FC80              <1> 	cmp	ah, 80h ; negative number check
 19450                              <1> 		; tst r1 / yes, no match
 19451                              <1> 		; bge .+4
 19452 00004F72 7203                <1> 	jb	short anyi_2
 19453 00004F74 66F7D8              <1> 	neg	ax
 19454                              <1> 		; neg r1 / make i-number positive
 19455                              <1> anyi_2:	
 19456 00004F77 E889070000          <1> 	call	imap
 19457                              <1> 		; jsr r0,imap / get address of allocation bit 
 19458                              <1> 			    ; / in the i-map in r2
 19459                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
 19460                              <1>         ;; eBX (R2) has address of the byte with allocation bit
 19461                              <1>  	; not	dx
 19462 00004F7C F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
 19463                              <1>         ;and	[ebx], dx
 19464 00004F7E 2013                <1> 	and 	[ebx], dl 
 19465                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
 19466 00004F80 E809070000          <1> 	call	itrunc
 19467                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
 19468 00004F85 66C705[906C0000]00- <1>  	mov 	word [i.flgs], 0
 19469 00004F8D 00                  <1>
 19470                              <1> 		; clr i.flgs / clear all flags in the i-node
 19471 00004F8E C3                  <1> 	retn
 19472                              <1> 		;rts	r0 / return
 19473                              <1> anyi_3: ; 1: / i-numbers match
 19474 00004F8F FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
 19475                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
 19476                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
 19477 00004F92 C3                  <1> 	retn
 19478                              <1> 		; rts r0
 19479                                  %include 'u3.s'        ; 10/05/2015
 19480                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS3.INC
 19481                              <1> ; Last Modification: 15/09/2015
 19482                              <1> ; ----------------------------------------------------------------------------
 19483                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 19484                              <1> ; (v0.1 - Beginning: 11/07/2012)
 19485                              <1> ;
 19486                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 19487                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 19488                              <1> ; <Bell Laboratories (17/3/1972)>
 19489                              <1> ; <Preliminary Release of UNIX Implementation Document>
 19490                              <1> ;
 19491                              <1> ; Retro UNIX 8086 v1 - U3.ASM (08/03/2014) //// UNIX v1 -> u3.s
 19492                              <1> ;
 19493                              <1> ; ****************************************************************************
 19494                              <1> 
 19495                              <1> tswitch: ; Retro UNIX 386 v1
 19496                              <1> tswap:
 19497                              <1> 	; 01/09/2015
 19498                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19499                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 19500                              <1> 	; time out swap, called when a user times out.
 19501                              <1> 	; the user is put on the low priority queue.
 19502                              <1> 	; This is done by making a link from the last user
 19503                              <1> 	; on the low priority queue to him via a call to 'putlu'.
 19504                              <1> 	; then he is swapped out.
 19505                              <1> 	;
 19506                              <1> 	; Retro UNIX 386 v1 modification ->
 19507                              <1> 	;       swap (software task switch) is performed by changing
 19508                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 19509                              <1> 	;	as in Retro UNIX 8086 v1.
 19510                              <1> 	;
 19511                              <1> 	; RETRO UNIX 8086 v1 modification ->
 19512                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19513                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19514                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19515                              <1> 	;	compatibles was using 1MB segmented memory 
 19516                              <1> 	;	in 8086/8088 times.
 19517                              <1> 	;
 19518                              <1> 	; INPUTS ->
 19519                              <1> 	;    u.uno - users process number
 19520                              <1> 	;    runq+4 - lowest priority queue
 19521                              <1> 	; OUTPUTS ->
 19522                              <1> 	;    r0 - users process number
 19523                              <1> 	;    r2 - lowest priority queue address
 19524                              <1> 	;
 19525                              <1> 	; ((AX = R0, BX = R2)) output
 19526                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
 19527                              <1> 	;
 19528 00004F93 A0[49700000]        <1> 	mov 	al, [u.uno]
 19529                              <1> 	       	; movb u.uno,r1 / move users process number to r1
 19530                              <1> 		; mov  $runq+4,r2 
 19531                              <1> 			; / move lowest priority queue address to r2
 19532 00004F98 E8CE000000          <1>         call 	putlu
 19533                              <1> 		; jsr r0,putlu / create link from last user on Q to 
 19534                              <1> 		             ; / u.uno's user
 19535                              <1> 
 19536                              <1> switch: ; Retro UNIX 386 v1
 19537                              <1> swap:
 19538                              <1> 	; 02/09/2015
 19539                              <1> 	; 01/09/2015
 19540                              <1> 	; 31/08/2015
 19541                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19542                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19543                              <1> 	; 'swap' is routine that controls the swapping of processes
 19544                              <1> 	; in and out of core.
 19545                              <1> 	;
 19546                              <1> 	; Retro UNIX 386 v1 modification ->
 19547                              <1> 	;       swap (software task switch) is performed by changing
 19548                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 19549                              <1> 	;	as in Retro UNIX 8086 v1.
 19550                              <1> 	;
 19551                              <1> 	; RETRO UNIX 8086 v1 modification ->
 19552                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19553                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19554                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19555                              <1> 	;	compatibles was using 1MB segmented memory 
 19556                              <1> 	;	in 8086/8088 times.
 19557                              <1> 	;
 19558                              <1> 	; INPUTS ->
 19559                              <1> 	;    runq table - contains processes to run.
 19560                              <1> 	;    p.link - contains next process in line to be run.
 19561                              <1> 	;    u.uno - process number of process in core	
 19562                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
 19563                              <1> 	; OUTPUTS ->
 19564                              <1> 	;    (original unix v1 -> present process to its disk block)
 19565                              <1> 	;    (original unix v1 -> new process into core -> 
 19566                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
 19567                              <1> 	;	   for new process)
 19568                              <1> 	;    u.quant = 3 (Time quantum for a process)
 19569                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
 19570                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
 19571                              <1> 	;	 for now, it will swap the process if there is not
 19572                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
 19573                              <1> 	;	 or will count down from 3 to 0 even if there is a
 19574                              <1> 	;        keyboard event locking due to repetitive key strokes.
 19575                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
 19576                              <1> 	;
 19577                              <1> 	;    u.pri -points to highest priority run Q.
 19578                              <1> 	;    r2 - points to the run queue.
 19579                              <1> 	;    r1 - contains new process number
 19580                              <1> 	;    r0 - points to place in routine or process that called
 19581                              <1> 	;	  swap all user parameters
 19582                              <1> 	;				
 19583                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
 19584                              <1> 	;
 19585                              <1> swap_0:
 19586                              <1> 		;mov $300,*$ps / processor priority = 6
 19587 00004F9D BE[E46F0000]        <1> 	mov	esi, runq
 19588                              <1> 		; mov $runq,r2 / r2 points to runq table
 19589                              <1> swap_1: ; 1: / search runq table for highest priority process
 19590 00004FA2 668B06              <1> 	mov	ax, [esi]
 19591 00004FA5 6621C0              <1> 	and 	ax, ax
 19592                              <1>        		; tst (r2)+ / are there any processes to run 
 19593                              <1> 			  ; / in this Q entry
 19594 00004FA8 7507                <1> 	jnz	short swap_2
 19595                              <1>        		; bne 1f / yes, process 1f
 19596                              <1> 		; cmp r2,$runq+6 / if zero compare address 
 19597                              <1> 			       ; / to end of table
 19598                              <1> 		; bne 1b / if not at end, go back
 19599 00004FAA E8E1000000          <1> 	call	idle
 19600                              <1> 		; jsr r0,idle; s.idlet+2 / wait for interrupt; 
 19601                              <1> 				       ; / all queues are empty
 19602 00004FAF EBF1                <1> 	jmp	short swap_1
 19603                              <1> 		; br swap
 19604                              <1> swap_2: ; 1:
 19605 00004FB1 0FB6D8              <1> 	movzx	ebx, al ; 02/09/2015
 19606                              <1> 		; tst -(r2) / restore pointer to right Q entry
 19607                              <1>  		; mov r2,u.pri / set present user to this run queue
 19608                              <1> 	        ; movb (r2)+,r1 / move 1st process in queue to r1
 19609 00004FB4 38E0                <1> 	cmp	al, ah
 19610                              <1> 		; cmpb r1,(r2)+ / is there only 1 process 
 19611                              <1> 			      ; / in this Q to be run
 19612 00004FB6 740A                <1> 	je	short swap_3
 19613                              <1>        		; beq 1f / yes
 19614                              <1> 		; tst -(r2) / no, pt r2 back to this Q entry
 19615                              <1> 	;movzx	ebx, al
 19616 00004FB8 8AA3[4F6D0000]      <1> 	mov	ah, [ebx+p.link-1] 
 19617 00004FBE 8826                <1>        	mov	[esi], ah
 19618                              <1> 		; movb p.link-1(r1),(r2) / move next process 
 19619                              <1> 				       ; / in line into run queue
 19620 00004FC0 EB06                <1> 	jmp	short swap_4
 19621                              <1>        		; br 2f
 19622                              <1> swap_3: ; 1:
 19623 00004FC2 6631D2              <1> 	xor	dx, dx
 19624 00004FC5 668916              <1> 	mov	[esi], dx
 19625                              <1> 		; clr -(r2) / zero the entry; no processes on the Q
 19626                              <1> swap_4: ; / write out core to appropriate disk area and read 
 19627                              <1>       ; / in new process if required
 19628                              <1>        		; clr *$ps / clear processor status
 19629 00004FC8 8A25[49700000]      <1> 	mov 	ah, [u.uno]
 19630 00004FCE 38C4                <1> 	cmp	ah, al
 19631                              <1> 		; cmpb r1,u.uno / is this process the same as 
 19632                              <1> 			      ; / the process in core?
 19633 00004FD0 743B                <1>        	je	short swap_8
 19634                              <1>        		; beq 2f / yes, don't have to swap
 19635                              <1>        		; mov r0,-(sp) / no, write out core; save r0 
 19636                              <1> 			   ; / (address in routine that called swap)
 19637                              <1> 		; mov r1,-(sp) / put r1 (new process #) on the stack
 19638                              <1> 	; 01/09/2015
 19639                              <1> 	;mov	[u.usp], esp
 19640                              <1>        		; mov sp,u.usp / save stack pointer
 19641                              <1> 		; mov $sstack,sp / move swap stack pointer 
 19642                              <1> 			       ; / to the stack pointer
 19643 00004FD2 08E4                <1> 	or	ah, ah
 19644                              <1>        		; tstb u.uno / is the process # = 0
 19645 00004FD4 740D                <1>        	jz	short swap_6 ; 'sysexit'
 19646                              <1> 		; beq  1f / yes, kill process by overwriting
 19647                              <1> 	; 02/09/2015
 19648 00004FD6 8925[F06F0000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
 19649                              <1> 	;
 19650 00004FDC E834000000          <1> 	call	wswap
 19651                              <1> 		;jsr r0,wswap / write out core to disk
 19652                              <1> 	 ; 31/08/2015
 19653                              <1> 	;movzx	ebx, al ; New (running) process number
 19654 00004FE1 EB1C                <1> 	jmp 	short swap_7
 19655                              <1> swap_6:
 19656                              <1> 	; 31/08/2015
 19657                              <1> 	; Deallocate memory pages belong to the process
 19658                              <1> 	; which is being terminated
 19659                              <1> 	; 14/05/2015 ('sysexit')
 19660                              <1>  	; Deallocate memory pages of the process
 19661                              <1> 	; (Retro UNIX 386 v1 modification !)
 19662                              <1> 	;
 19663                              <1> 	; movzx ebx, al
 19664 00004FE3 53                  <1> 	push	ebx
 19665 00004FE4 A1[58700000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
 19666 00004FE9 8B1D[5C700000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
 19667 00004FEF E865E0FFFF          <1> 	call	deallocate_page_dir
 19668 00004FF4 A1[54700000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
 19669 00004FF9 E8F3E0FFFF          <1> 	call	deallocate_page
 19670 00004FFE 5B                  <1> 	pop	ebx
 19671                              <1> swap_7: ;1: 
 19672                              <1> 	; 02/09/2015
 19673                              <1> 	; 31/08/2015
 19674                              <1> 	; 14/05/2015
 19675 00004FFF C0E302              <1> 	shl	bl, 2 ; * 4 
 19676 00005002 8B83[6C6D0000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
 19677                              <1> 	;cli
 19678 00005008 E831000000          <1> 	call	rswap
 19679                              <1>  		; mov (sp)+,r1 / restore r1 to new process number
 19680                              <1> 		; jsr r0,rswap / read new process into core
 19681                              <1>        		; jsr r0,unpack / unpack the users stack from next
 19682                              <1> 			      ; / to his program to its normal
 19683                              <1> 	; 01/09/2015
 19684                              <1> 	;mov	esp, [u.usp]	
 19685                              <1> 		; mov u.usp,sp / location; restore stack pointer to
 19686                              <1> 			     ; / new process stack
 19687                              <1> 		; mov (sp)+,r0 / put address of where the process 
 19688                              <1> 			     ; / that just got swapped in, left off.,
 19689                              <1> 			     ; / i.e., transfer control to new process
 19690                              <1> 	;sti
 19691                              <1> swap_8: ;2:
 19692                              <1> 	; RETRO UNIX 8086 v1 modification !
 19693 0000500D C605[40700000]04    <1> 	mov	byte [u.quant], time_count 
 19694                              <1> 		; movb    $30.,uquant / initialize process time quantum
 19695 00005014 C3                  <1> 	retn
 19696                              <1> 		; rts r0 / return
 19697                              <1> 
 19698                              <1> wswap:  ; < swap out, swap to disk >
 19699                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 19700                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19701                              <1> 	; 'wswap' writes out the process that is in core onto its 
 19702                              <1> 	; appropriate disk area.
 19703                              <1> 	;
 19704                              <1> 	; Retro UNIX 386 v1 modification ->
 19705                              <1> 	;       User (u) structure content and the user's register content
 19706                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
 19707                              <1> 	;	saving 'u' structure and user registers for task switching).
 19708                              <1> 	;	u.usp - points to kernel stack address which contains
 19709                              <1> 	;		user's registers while entering system call.  
 19710                              <1> 	;	u.sp  - points to kernel stack address 
 19711                              <1> 	;		to return from system call -for IRET-.
 19712                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 19713                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 19714                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 19715                              <1> 	;
 19716                              <1> 	; Retro UNIX 8086 v1 modification ->
 19717                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19718                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19719                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19720                              <1> 	;	compatibles was using 1MB segmented memory 
 19721                              <1> 	;	in 8086/8088 times.
 19722                              <1> 	;
 19723                              <1> 	; INPUTS ->
 19724                              <1> 	;    u.break - points to end of program
 19725                              <1> 	;    u.usp - stack pointer at the moment of swap
 19726                              <1> 	;    core - beginning of process program		
 19727                              <1> 	;    ecore - end of core 	
 19728                              <1> 	;    user - start of user parameter area		
 19729                              <1> 	;    u.uno - user process number	
 19730                              <1> 	;    p.dska - holds block number of process	
 19731                              <1> 	; OUTPUTS ->
 19732                              <1> 	;    swp I/O queue
 19733                              <1> 	;    p.break - negative word count of process 
 19734                              <1> 	;    r1 - process disk address	
 19735                              <1> 	;    r2 - negative word count
 19736                              <1> 	;
 19737                              <1> 	; RETRO UNIX 8086 v1 input/output:
 19738                              <1> 	;
 19739                              <1> 	; INPUTS ->
 19740                              <1> 	;    u.uno - process number (to be swapped out)
 19741                              <1> 	; OUTPUTS ->
 19742                              <1> 	;    none
 19743                              <1> 	;
 19744                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
 19745                              <1> 	;
 19746 00005015 8B3D[54700000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
 19747 0000501B B94B000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 19748 00005020 BE[EC6F0000]        <1> 	mov	esi, user ; active user (u) structure	
 19749 00005025 F3A5                <1> 	rep	movsd
 19750                              <1> 	;
 19751 00005027 8B35[F06F0000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
 19752                              <1> 			     ;      points to user registers)
 19753 0000502D 8B0D[EC6F0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 19754                              <1> 			     ; (for IRET)
 19755                              <1> 			     ; [u.sp] -> EIP (user)
 19756                              <1> 			     ; [u.sp+4]-> CS (user)
 19757                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 19758                              <1> 			     ; [u.sp+12] -> ESP (user)
 19759                              <1> 			     ; [u.sp+16] -> SS (user)	
 19760 00005033 29F1                <1> 	sub	ecx, esi     ; required space for user registers
 19761 00005035 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 19762                              <1> 			     ; (for IRET) 	
 19763 00005038 C1E902              <1> 	shr	ecx, 2	     		
 19764 0000503B F3A5                <1> 	rep	movsd
 19765 0000503D C3                  <1> 	retn
 19766                              <1> 
 19767                              <1> 	; Original UNIX v1 'wswap' routine:
 19768                              <1> 	; wswap:
 19769                              <1> 		; mov *$30,u.emt / determines handling of emts
 19770                              <1>         	; mov *$10,u.ilgins / determines handling of 
 19771                              <1> 				; / illegal instructions
 19772                              <1> 		; mov u.break,r2 / put process program break address in r2
 19773                              <1> 		; inc r2 / add 1 to it 
 19774                              <1> 		; bic $1,r2 / make it even
 19775                              <1> 		; mov r2,u.break / set break to an even location
 19776                              <1> 		; mov u.usp,r3 / put users stack pointer 
 19777                              <1> 			     ; / at moment of swap in r3
 19778                              <1> 		; cmp r2,$core / is u.break less than $core
 19779                              <1> 		; blos 2f / yes
 19780                              <1> 		; cmp r2,r3 / no, is (u.break) greater than stack ptr.
 19781                              <1>        		; bhis 2f / yes
 19782                              <1> 	; 1:
 19783                              <1>        		; mov (r3)+,(r2)+ / no, pack stack next to users program
 19784                              <1> 		; cmp r3,$ecore / has stack reached end of core
 19785                              <1> 		; bne 1b / no, keep packing
 19786                              <1> 	 	; br 1f / yes
 19787                              <1> 	; 2:
 19788                              <1>        		; mov $ecore,r2 / put end of core in r2 
 19789                              <1> 	; 1:
 19790                              <1>        		; sub  $user,r2 / get number of bytes to write out 
 19791                              <1> 			   ; / (user up to end of stack gets written out)
 19792                              <1> 		; neg r2 / make it negative
 19793                              <1> 		; asr r2 / change bytes to words (divide by 2)
 19794                              <1> 		; mov r2,swp+4 / word count
 19795                              <1> 		; movb u.uno,r1 / move user process number to r1
 19796                              <1> 		; asl r1 / x2 for index
 19797                              <1>       		; mov r2,p.break-2(r1) / put negative of word count 
 19798                              <1> 				     ; / into the p.break table
 19799                              <1>        		; mov p.dska-2(r1),r1 / move disk address of swap area 
 19800                              <1> 				    ; /	for process to r1
 19801                              <1>        		; mov r1,swp+2 / put processes dska address in swp+2 
 19802                              <1> 			     ; / (block number)
 19803                              <1> 		; bis $1000,swp / set it up to write (set bit 9)
 19804                              <1>        		; jsr r0,ppoke / write process out on swap area of disk
 19805                              <1> 	; 1:
 19806                              <1>        		; tstb swp+1 / is lt done writing?
 19807                              <1>        		; bne 1b / no, wait
 19808                              <1> 		; rts r0 / yes, return to swap
 19809                              <1> 
 19810                              <1> rswap:  ; < swap in, swap from disk >
 19811                              <1> 	; 15/09/2015
 19812                              <1> 	; 28/08/2015
 19813                              <1> 	; 14/05/2015
 19814                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 19815                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19816                              <1> 	; 'rswap' reads a process whose number is in r1, 
 19817                              <1> 	; from disk into core.
 19818                              <1> 	;
 19819                              <1> 	; Retro UNIX 386 v1 modification ->
 19820                              <1> 	;       User (u) structure content and the user's register content
 19821                              <1> 	;	will be restored from process's/user's UPAGE (a page for
 19822                              <1> 	;	saving 'u' structure and user registers for task switching).
 19823                              <1> 	;	u.usp - points to kernel stack address which contains
 19824                              <1> 	;		user's registers while entering system call.  
 19825                              <1> 	;	u.sp  - points to kernel stack address 
 19826                              <1> 	;		to return from system call -for IRET-.
 19827                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 19828                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 19829                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 19830                              <1> 	;
 19831                              <1> 	; RETRO UNIX 8086 v1 modification ->
 19832                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19833                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19834                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19835                              <1> 	;	compatibles was using 1MB segmented memory 
 19836                              <1> 	;	in 8086/8088 times.
 19837                              <1> 	;
 19838                              <1> 	; INPUTS ->
 19839                              <1> 	;    r1 - process number of process to be read in
 19840                              <1> 	;    p.break - negative of word count of process 
 19841                              <1> 	;    p.dska - disk address of the process		
 19842                              <1> 	;    u.emt - determines handling of emt's 	
 19843                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 19844                              <1> 	; OUTPUTS ->
 19845                              <1> 	;    8 = (u.ilgins)
 19846                              <1> 	;    24 = (u.emt)
 19847                              <1> 	;    swp - bit 10 is set to indicate read 
 19848                              <1> 	;		(bit 15=0 when reading is done)	
 19849                              <1> 	;    swp+2 - disk block address
 19850                              <1> 	;    swp+4 - negative word count 	
 19851                              <1> 	;      ((swp+6 - address of user structure)) 
 19852                              <1> 	;
 19853                              <1> 	; RETRO UNIX 8086 v1 input/output:
 19854                              <1> 	;
 19855                              <1> 	; INPUTS ->
 19856                              <1> 	;    AL	- new process number (to be swapped in)	 
 19857                              <1> 	; OUTPUTS ->
 19858                              <1> 	;    none
 19859                              <1> 	;
 19860                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
 19861                              <1> 	;
 19862                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
 19863 0000503E 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
 19864 00005040 B94B000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 19865 00005045 BF[EC6F0000]        <1> 	mov	edi, user ; active user (u) structure	
 19866 0000504A F3A5                <1> 	rep	movsd
 19867 0000504C 58                  <1> 	pop	eax ; 15/09/2015, 'rswap' return address 
 19868 0000504D 8B3D[F06F0000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
 19869                              <1> 			     ;      points to user registers)
 19870 00005053 8B0D[EC6F0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 19871                              <1> 			     ; (for IRET)
 19872                              <1> 			     ; [u.sp] -> EIP (user)
 19873                              <1> 			     ; [u.sp+4]-> CS (user)
 19874                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 19875                              <1> 			     ; [u.sp+12] -> ESP (user)
 19876                              <1> 			     ; [u.sp+16] -> SS (user)		
 19877                              <1> 	; 28/08/2015
 19878 00005059 29F9                <1> 	sub	ecx, edi     ; required space for user registers
 19879 0000505B 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 19880                              <1> 			     ; (for IRET) 	
 19881 0000505E C1E902              <1> 	shr	ecx, 2	       		
 19882 00005061 F3A5                <1> 	rep	movsd
 19883 00005063 8B25[F06F0000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
 19884 00005069 50                  <1> 	push	eax ; 15/09/2015 'rswap' return address
 19885 0000506A C3                  <1> 	retn
 19886                              <1> 
 19887                              <1> 	; Original UNIX v1 'rswap'  and 'unpack' routines:
 19888                              <1> 	;rswap:
 19889                              <1>        		; asl r1 / process number x2 for index
 19890                              <1>        		; mov p.break-2(r1), swp+4 / word count
 19891                              <1>        		; mov p.dska-2(r1),swp+2 / disk address
 19892                              <1>        		; bis $2000,swp / read
 19893                              <1>        		; jsr r0,ppoke / read it in 
 19894                              <1> 	; 1:
 19895                              <1>        		; tstb swp+1 / done
 19896                              <1>        		; bne 1b / no, wait for bit 15 to clear (inhibit bit)
 19897                              <1>        		; mov u.emt,*$30 / yes move these
 19898                              <1>        		; mov u.ilgins,*$10 / back
 19899                              <1>        		; rts r0 / return
 19900                              <1> 
 19901                              <1> 	;unpack: ; / move stack back to its normal place
 19902                              <1> 		; mov u.break,r2 / r2 points to end of user program
 19903                              <1>        		; cmp r2,$core / at beginning of user program yet?
 19904                              <1> 		; blos 2f / yes, return
 19905                              <1> 		; cmp r2,u.usp / is break_above the stack pointer 
 19906                              <1> 			     ; / before swapping
 19907                              <1> 		; bhis 2f / yes, return
 19908                              <1> 		; mov $ecore,r3 / r3 points to end of core
 19909                              <1> 		; add r3,r2
 19910                              <1> 		; sub u.usp,r2 / end of users stack is in r2
 19911                              <1> 	; 1:
 19912                              <1> 		; mov -(r2),-(r3) / move stack back to its normal place
 19913                              <1> 		; cmp r2,u.break / in core
 19914                              <1> 		; bne 1b
 19915                              <1> 	; 2:
 19916                              <1>        		; rts r0
 19917                              <1> 
 19918                              <1> putlu: 
 19919                              <1> 	; 12/09/2015
 19920                              <1> 	; 02/09/2015
 19921                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19922                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 19923                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
 19924                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
 19925                              <1> 	; the last process on the queue to process in r1 by putting
 19926                              <1> 	; the process number in r1 into the last process's link.
 19927                              <1> 	;
 19928                              <1> 	; INPUTS ->
 19929                              <1> 	;    r1 - user process number
 19930                              <1> 	;    r2 - points to lowest priority queue 
 19931                              <1> 	;    p.dska - disk address of the process		
 19932                              <1> 	;    u.emt - determines handling of emt's 	
 19933                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 19934                              <1> 	; OUTPUTS ->
 19935                              <1> 	;    r3 - process number of last process on the queue upon
 19936                              <1> 	;	  entering putlu
 19937                              <1> 	;    p.link-1 + r3 - process number in r1
 19938                              <1> 	;    r2 - points to lowest priority queue
 19939                              <1> 	;
 19940                              <1> 	; ((Modified registers: EDX, EBX)) 
 19941                              <1> 	;
 19942                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
 19943                              <1> 
 19944                              <1> 	; eBX = r2
 19945                              <1> 	; eAX = r1 (AL=r1b)
 19946                              <1> 
 19947 0000506B BB[E46F0000]        <1> 	mov	ebx, runq
 19948 00005070 0FB613              <1> 	movzx  	edx, byte [ebx]
 19949 00005073 43                  <1> 	inc	ebx
 19950 00005074 20D2                <1> 	and	dl, dl
 19951                              <1> 		; tstb (r2)+ / is queue empty?
 19952 00005076 740A                <1>        	jz	short putlu_1
 19953                              <1> 		; beq 1f / yes, branch
 19954 00005078 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
 19955                              <1> 		; movb (r2),r3 / no, save the "last user" process number
 19956                              <1> 			     ; / in r3
 19957 0000507A 8882[4F6D0000]      <1>        	mov	[edx+p.link-1], al
 19958                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
 19959                              <1> 			     ; / "last users" link
 19960 00005080 EB03                <1> 	jmp	short putlu_2
 19961                              <1> 		; br 2f /
 19962                              <1> putlu_1: ; 1:
 19963 00005082 8843FF              <1> 	mov	[ebx-1], al
 19964                              <1>        		; movb r1,-1(r2) / user is only user; 
 19965                              <1> 			    ; / put process no. at beginning and at end
 19966                              <1> putlu_2: ; 2: 
 19967 00005085 8803                <1> 	mov	[ebx], al
 19968                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
 19969                              <1> 			     ; / on the queue
 19970 00005087 88C2                <1> 	mov	dl, al
 19971 00005089 88B2[4F6D0000]      <1>         mov     [edx+p.link-1], dh ; 0
 19972                              <1> 		; dec r2 / restore r2
 19973 0000508F C3                  <1>         retn
 19974                              <1> 		; rts r0
 19975                              <1> 
 19976                              <1> ;copyz:
 19977                              <1> ;       mov     r1,-(sp) / put r1 on stack
 19978                              <1> ;       mov     r2,-(sp) / put r2 on stack
 19979                              <1> ;       mov     (r0)+,r1
 19980                              <1> ;       mov     (r0)+,r2
 19981                              <1> ;1:
 19982                              <1> ;       clr     (r1)+ / clear all locations between r1 and r2
 19983                              <1> ;       cmp     r1,r2 
 19984                              <1> ;       blo     1b
 19985                              <1> ;       mov     (sp)+,r2 / restore r2
 19986                              <1> ;       mov     (sp)+,r1 / restore r1
 19987                              <1> ;       rts     r0 
 19988                              <1> 
 19989                              <1> idle:
 19990                              <1> 	; 01/09/2015
 19991                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19992                              <1> 	; 10/04/2013 - 23/10/2013 (Retro UNIX 8086 v1)
 19993                              <1> 	; (idle & wait loop)
 19994                              <1> 	; Retro Unix 8086 v1 modification on original UNIX v1
 19995                              <1> 	; idle procedure!
 19996                              <1>       	;
 19997                              <1>   	; 01/09/2015
 19998 00005090 FB                  <1> 	sti
 19999                              <1>       	; 29/07/2013
 20000 00005091 F4                  <1>       	hlt
 20001 00005092 90                  <1>       	nop ; 10/10/2013
 20002 00005093 90                  <1>       	nop
 20003 00005094 90                  <1>       	nop
 20004                              <1>       	; 23/10/2013
 20005 00005095 90                  <1>       	nop
 20006 00005096 90                  <1>       	nop
 20007 00005097 90                  <1>       	nop
 20008 00005098 90                  <1>       	nop
 20009 00005099 C3                  <1>       	retn      
 20010                              <1> 
 20011                              <1> 	;mov *$ps,-(sp) / save ps on stack
 20012                              <1> 	;clr *$ps / clear ps
 20013                              <1> 	;mov clockp,-(sp) / save clockp on stack
 20014                              <1> 	;mov (r0)+,clockp / arg to idle in clockp
 20015                              <1> 	;1 / wait for interrupt
 20016                              <1> 	;mov (sp)+,clockp / restore clockp, ps
 20017                              <1> 	;mov (sp)+,*$ps
 20018                              <1> 	;rts r0
 20019                              <1> 
 20020                              <1> clear:
 20021                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 20022                              <1> 	; 09/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 20023                              <1> 	; 'clear' zero's out of a block (whose block number is in r1)
 20024                              <1> 	; on the current device (cdev)
 20025                              <1> 	;	
 20026                              <1> 	; INPUTS ->
 20027                              <1> 	;    r1 - block number of block to be zeroed
 20028                              <1> 	;    cdev - current device number 
 20029                              <1> 	; OUTPUTS ->
 20030                              <1> 	;    a zeroed I/O buffer onto the current device
 20031                              <1> 	;    r1 - points to last entry in the I/O buffer
 20032                              <1> 	;
 20033                              <1> 	; ((AX = R1)) input/output
 20034                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 14/11/2012, UNIXCOPY.ASM)
 20035                              <1>         ;    ((Modified registers: EDX, ECX, EBX, ESI, EDI, EBP))  
 20036                              <1> 
 20037 0000509A E826100000          <1> 	call 	wslot
 20038                              <1> 		; jsr r0,wslot / get an I/O buffer set bits 9 and 15 in first
 20039                              <1>                    ; / word of I/O queue r5 points to first data word in buffer
 20040 0000509F 89DF                <1> 	mov	edi, ebx ; r5
 20041 000050A1 89C2                <1> 	mov	edx, eax
 20042 000050A3 B980000000          <1> 	mov	ecx, 128
 20043                              <1> 		; mov $256.,r3
 20044 000050A8 31C0                <1> 	xor	eax, eax
 20045 000050AA F3AB                <1> 	rep	stosd
 20046 000050AC 89D0                <1> 	mov	eax, edx
 20047                              <1> ; 1: 
 20048                              <1>        		; clr (r5)+ / zero data word in buffer
 20049                              <1>        		; dec r3
 20050                              <1>        		; bgt 1b / branch until all data words in buffer are zero
 20051 000050AE E82E100000          <1> 	call	dskwr
 20052                              <1> 		; jsr r0,dskwr / write zeroed buffer area out onto physical
 20053                              <1>                              ; / block specified in r1
 20054                              <1> 	; eAX (r1) = block number
 20055 000050B3 C3                  <1> 	retn
 20056                              <1> 		; rts r0
 20057                                  %include 'u4.s'        ; 15/04/2015
 20058                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 20059                              <1> ; (re-write kernel for test by using previous version without a major defect)
 20060                              <1> ; ****************************************************************************
 20061                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS4.INC
 20062                              <1> ; Last Modification: 30/11/2021
 20063                              <1> ; ----------------------------------------------------------------------------
 20064                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 20065                              <1> ; (v0.1 - Beginning: 11/07/2012)
 20066                              <1> ;
 20067                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 20068                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 20069                              <1> ; <Bell Laboratories (17/3/1972)>
 20070                              <1> ; <Preliminary Release of UNIX Implementation Document>
 20071                              <1> ;
 20072                              <1> ; Retro UNIX 8086 v1 - U4.ASM (04/07/2014) //// UNIX v1 -> u4.s
 20073                              <1> ;
 20074                              <1> ; ****************************************************************************
 20075                              <1> 
 20076                              <1> ;setisp:
 20077                              <1>        ;mov     r1,-(sp)
 20078                              <1>        ;mov     r2,-(sp)
 20079                              <1>        ;mov     r3,-(sp)
 20080                              <1>        ;mov     clockp,-(sp)
 20081                              <1>        ;mov     $s.syst+2,clockp
 20082                              <1>        ;jmp     (r0)
 20083                              <1> 
 20084                              <1> clock: ; / interrupt from 60 cycle clock
 20085                              <1> 	
 20086                              <1> 	; 14/10/2015
 20087                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 20088                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
 20089                              <1> 
 20090                              <1>        ;mov     r0,-(sp) / save r0
 20091                              <1>        ;tst     *$lks / restart clock?
 20092                              <1>        ;mov     $s.time+2,r0 / increment the time of day
 20093                              <1>        ;inc     (r0)
 20094                              <1>        ;bne     1f
 20095                              <1>        ;inc     -(r0)
 20096                              <1> ;1:
 20097                              <1>        ;mov     clockp,r0 / increment appropriate time category
 20098                              <1>        ;inc     (r0)
 20099                              <1>        ;bne     1f
 20100                              <1>        ;inc     -(r0)
 20101                              <1> ;1:
 20102                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 20103                              <1> 
 20104 000050B4 803D[40700000]00    <1> 	cmp	byte [u.quant], 0
 20105 000050BB 772C                <1> 	ja	short clk_1
 20106                              <1> 	;
 20107 000050BD 803D[E96F0000]FF    <1>         cmp     byte [sysflg], 0FFh ; user or system space ?
 20108 000050C4 7529                <1> 	jne	short clk_2 ; system space (sysflg <> 0FFh)
 20109 000050C6 803D[49700000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ?
 20110 000050CD 761A                <1> 	jna	short clk_1 ; yes, do not swap out
 20111 000050CF 66833D[44700000]00  <1> 	cmp	word [u.intr], 0
 20112 000050D7 7616                <1> 	jna	short clk_2
 20113                              <1> clk_0:
 20114                              <1> 	; 14/10/2015
 20115 000050D9 FE05[E96F0000]      <1> 	inc	byte [sysflg] ; Now, we are in system space
 20116 000050DF 58                  <1> 	pop	eax ; return address to the timer interrupt
 20117                              <1> 	;
 20118 000050E0 B020                <1> 	MOV	AL,EOI			; GET END OF INTERRUPT MASK
 20119                              <1> 	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
 20120 000050E2 E620                <1> 	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
 20121                              <1> 	;
 20122 000050E4 E903ECFFFF          <1> 	jmp     sysrelease ; 'sys release' by clock/timer
 20123                              <1> clk_1:
 20124 000050E9 FE0D[40700000]      <1> 	dec	byte [u.quant]
 20125                              <1> clk_2:
 20126 000050EF C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
 20127                              <1> 
 20128                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
 20129                              <1> 
 20130                              <1>        ;mov     $uquant,r0 / decrement user time quantum
 20131                              <1>        ;decb    (r0)
 20132                              <1>        ;bge     1f / if less than 0
 20133                              <1>        ;clrb    (r0) / make it 0
 20134                              <1> ;1: / decrement time out counts return now if priority was not 0
 20135                              <1>        ;cmp     4(sp),$200 / ps greater than or equal to 200
 20136                              <1>        ;bge     2f / yes, check time outs
 20137                              <1>        ;tstb    (r0) / no, user timed out?
 20138                              <1>        ;bne     1f / no
 20139                              <1>        ;cmpb    sysflg,$-1 / yes, are we outside the system?
 20140                              <1>        ;bne     1f / no, 1f
 20141                              <1>        ;mov     (sp)+,r0 / yes, put users r0 in r0
 20142                              <1>        ;sys     0 / sysrele
 20143                              <1>        ;rti
 20144                              <1> ;2: / priority is high so just decrement time out counts
 20145                              <1>        ;mov     $toutt,r0 / r0 points to beginning of time out table
 20146                              <1> ;2:
 20147                              <1>        ;tstb    (r0) / is the time out?
 20148                              <1>        ;beq     3f / yes, 3f (get next entry)
 20149                              <1>        ;decb    (r0) / no, decrement the time
 20150                              <1>        ;bne     3f / isit zero now?
 20151                              <1>        ;incb    (r0) / yes, increment the time
 20152                              <1> ;3:
 20153                              <1>        ;inc     r0 / next entry
 20154                              <1>        ;cmp     r0,$touts / end of toutt table?
 20155                              <1>        ;blo     2b / no, check this entry
 20156                              <1>        ;mov     (sp)+,r0 / yes, restore r0
 20157                              <1>        ;rti / return from interrupt
 20158                              <1> ;1: / decrement time out counts; if 0 call subroutine
 20159                              <1>        ;mov     (sp)+,r0 / restore r0
 20160                              <1>        ;mov     $240,*$ps / set processor priority to 5
 20161                              <1>        ;jsr     r0,setisp / save registers
 20162                              <1>        ;mov     $touts-toutt-1,r0 / set up r0 as index to decrement thru
 20163                              <1>                                ;  / the table
 20164                              <1> ;1:
 20165                              <1>        ;tstb    toutt(r0) / is the time out for this entry
 20166                              <1>        ;beq     2f / yes
 20167                              <1>        ;decb    toutt(r0) / no, decrement the time
 20168                              <1>        ;bne     2f / is the time 0, now
 20169                              <1>        ;asl     r0 / yes, 2 x r0 to get word index for tout entry
 20170                              <1>        ;jsr     r0,*touts(r0) / go to appropriate routine specified in this
 20171                              <1>        ;asr     r0 / touts entry; set r0 back to toutt index
 20172                              <1> ;2:
 20173                              <1>        ;dec     r0 / set up r0 for next entry
 20174                              <1>        ;bge     1b / finished? , no, go back
 20175                              <1>        ;br      retisp / yes, restore registers and do a rti
 20176                              <1> 
 20177                              <1> ;retisp:
 20178                              <1>        ;mov     (sp)+,clockp / pop values before interrupt off the stack
 20179                              <1>        ;mov     (sp)+,r3
 20180                              <1>        ;mov     (sp)+,r2
 20181                              <1>        ;mov     (sp)+,r1
 20182                              <1>        ;mov     (sp)+,r0
 20183                              <1>        ;rti     / return from interrupt
 20184                              <1> 
 20185                              <1> 
 20186                              <1> wakeup: ; / wakeup processes waiting for an event 
 20187                              <1> 	; / by linking them to the queue
 20188                              <1> 	;
 20189                              <1> 	; 15/09/2015
 20190                              <1> 	; 29/06/2015
 20191                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 20192                              <1> 	;
 20193                              <1> 	; 15/05/2013 - 02/06/2014
 20194                              <1> 	; Retro UNIX 8086 v1 modification !
 20195                              <1> 	; (Process/task switching routine by using
 20196                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.)
 20197                              <1> 	;
 20198                              <1> 	; In original UNIX v1, 'wakeup' is called to wake the process
 20199                              <1> 	; sleeping in the specified wait channel by creating a link 
 20200                              <1> 	; to it from the last user process on the run queue.
 20201                              <1> 	; If there is no process to wake up, nothing happens.
 20202                              <1> 	;
 20203                              <1> 	; In Retro UNIX 8086 v1, Int 09h keyboard interrupt will set
 20204                              <1> 	; 'switching' status of the current process (owns current tty)
 20205                              <1> 	; (via alt + function keys) to a process which has highest
 20206                              <1> 	; priority (on run queue) on the requested tty (0 to 7, except
 20207                              <1> 	; 8 and 9 which are tty identifiers of COM1, COM2 serial ports)
 20208                              <1> 	; as it's console tty. (NOTE: 'p.ttyc' is used to set console
 20209                              <1> 	; tty for tty switching by keyboard.)	 
 20210                              <1> 	; 
 20211                              <1> 	; INPUT -> 
 20212                              <1> 	;	   AL = wait channel (r3) ('tty number' for now)
 20213                              <1> 	;	   ;;EBX = Run queue (r2) offset
 20214                              <1> 	;
 20215                              <1> 	; ((modified registers: EAX, EBX))
 20216                              <1> 	;
 20217 000050F0 0FB6D8              <1> 	movzx	ebx, al ; 29/06/2015
 20218 000050F3 81C3[586F0000]      <1> 	add	ebx, wlist
 20219 000050F9 8A03                <1> 	mov	al, [ebx] ; waiting list (waiting process number)
 20220 000050FB 20C0                <1> 	and	al, al
 20221 000050FD 7424                <1> 	jz	short wa0 ; nothing to wakeup
 20222                              <1> 	;
 20223 000050FF 30E4                <1> 	xor	ah, ah
 20224 00005101 8825[40700000]      <1> 	mov 	[u.quant], ah ; 0 ; time quantum = 0	
 20225 00005107 8823                <1> 	mov	[ebx], ah ; 0 ; zero wait channel entry
 20226                              <1> 	; 15/09/2015
 20227 00005109 0FB6D8              <1> 	movzx	ebx, al
 20228 0000510C 88A3[3F6D0000]      <1> 	mov	[ebx+p.waitc-1], ah ; 0
 20229 00005112 FEC4                <1> 	inc	ah
 20230 00005114 88A3[5F6D0000]      <1> 	mov	byte [ebx+p.stat-1], ah ; 1 ; SRUN
 20231                              <1> 	;
 20232 0000511A 57                  <1> 	push	edi
 20233 0000511B 52                  <1> 	push	edx
 20234 0000511C E84AFFFFFF          <1> 	call	putlu
 20235 00005121 5A                  <1> 	pop	edx
 20236 00005122 5F                  <1> 	pop	edi
 20237                              <1> wa0:
 20238 00005123 C3                  <1> 	retn
 20239                              <1> 
 20240                              <1> 	; 30/11/2021 - Retro UNIX 386 v1.2
 20241                              <1> sleep: 
 20242                              <1> 	; 15/09/2015
 20243                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 20244                              <1> 	;
 20245                              <1> 	; 09/05/2013 - 20/03/2014
 20246                              <1> 	;
 20247                              <1> 	; Retro UNIX 8086 v1 modification !
 20248                              <1> 	; (Process/task switching and quit routine by using
 20249                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 20250                              <1> 	;
 20251                              <1> 	; In original UNIX v1, 'sleep' is called to wait for
 20252                              <1> 	; tty and tape output or input becomes available
 20253                              <1> 	; and process is put on waiting channel and swapped out,
 20254                              <1> 	; then -when the tty or tape is ready to write or read-
 20255                              <1> 	; 'wakeup' gets process back to active swapped-in status.)
 20256                              <1> 	;
 20257                              <1> 	; In Retro UNIX 8086 v1, Int 1Bh ctrl+brk interrupt and
 20258                              <1> 	; Int 09h keyboard interrupt will set 'quit' or 'switching'		
 20259                              <1> 	; status of the current process also INT 1Ch will count down
 20260                              <1> 	; 'uquant' value and INT 09h will redirect scancode of keystroke
 20261                              <1> 	; to tty buffer of the current process and kernel will get
 20262                              <1> 	; user input by using tty buffer of the current process
 20263                              <1> 	; (instead of standard INT 16h interrupt).
 20264                              <1> 	; TTY output will be redirected to related video page of text mode
 20265                              <1> 	; (INT 10h will be called with different video page depending
 20266                              <1> 	; on tty assignment of the active process: 0 to 7 for
 20267                              <1> 	; pseudo screens.)
 20268                              <1> 	;
 20269                              <1> 	; In Retro UNIX 8086 v1, 'sleep' will be called to wait for
 20270                              <1> 	; a keystroke from keyboard or wait for reading or writing
 20271                              <1> 	; characters/data on serial port(s).
 20272                              <1> 	;
 20273                              <1> 	; Character/Terminal input/output through COM1 and COM2 will be
 20274                              <1> 	; performed by related routines in addition to pseudo TTY routines.
 20275                              <1> 	; 
 20276                              <1> 	; R1 = AH = wait channel (0-9 for TTYs) ; 05/10/2013 (22/09/2013)
 20277                              <1> 	;
 20278                              <1> 	;; 05/10/2013
 20279                              <1>         ;10/12/2013
 20280                              <1> 	;cmp   byte [u.uno], 1
 20281                              <1>         ;ja    short sleep0
 20282                              <1> 	;retn
 20283                              <1> 
 20284                              <1> 	; 20/03/2014
 20285                              <1> 	;mov	bx, [runq]
 20286                              <1> 	;cmp	bl, bh
 20287                              <1> 	;jne	short sleep0	
 20288                              <1> 	; 25/02/2014
 20289                              <1> 	;cmp word ptr [runq], 0
 20290                              <1> 	;ja short sleep0	
 20291                              <1> 	;retn
 20292                              <1> sleep0:
 20293                              <1> 	;
 20294 00005124 E854000000          <1> 	call	isintr
 20295 00005129 0F8563EBFFFF        <1> 	jnz	sysret
 20296                              <1> 		; / wait for event
 20297                              <1>        		; jsr r0,isintr / check to see if interrupt 
 20298                              <1> 			      ; / or quit from user
 20299                              <1>                		; br 2f / something happened
 20300                              <1> 			      ; / yes, his interrupt so return
 20301                              <1>                      	      ;	/ to user
 20302                              <1> 
 20303                              <1> 	; 30/06/2015
 20304 0000512F 0FB6DC              <1>     	movzx	ebx, ah ; 30/06/2015
 20305 00005132 81C3[586F0000]      <1> 	add	ebx, wlist
 20306 00005138 8A03                <1> 	mov	al, [ebx]
 20307 0000513A 20C0                <1> 	and	al, al
 20308 0000513C 7407                <1> 	jz	short sleep1
 20309 0000513E 53                  <1> 	push	ebx
 20310 0000513F E827FFFFFF          <1> 	call	putlu
 20311 00005144 5B                  <1> 	pop	ebx
 20312                              <1> sleep1:
 20313 00005145 A0[49700000]        <1> 	mov	al, [u.uno]    
 20314 0000514A 8803                <1>   	mov	[ebx], al 	; put the process number
 20315                              <1> 				; in the wait channel
 20316                              <1> 		; mov (r0)+,r1 / put number of wait channel in r1
 20317                              <1> 		; movb wlist(r1),-(sp) / put old process number in there,
 20318                              <1> 				     ; / on the stack
 20319                              <1>        		; movb u.uno,wlist(r1) / put process number of process
 20320                              <1> 				     ; / to put to sleep in there
 20321                              <1> 	; 30/11/2021
 20322 0000514C 31DB                <1> 	xor	ebx, ebx
 20323 0000514E 8A1D[D56F0000]      <1> 	mov	bl, [cdev]
 20324 00005154 53                  <1> 	push	ebx
 20325                              <1>         ; 15/09/2015
 20326                              <1> 	;movzx	ebx, al
 20327 00005155 88C3                <1> 	mov	bl, al
 20328 00005157 C683[5F6D0000]04    <1>         mov     byte [ebx+p.stat-1], 4 ; SSLEEP
 20329 0000515E FEC4                <1> 	inc	ah
 20330 00005160 88A3[3F6D0000]      <1> 	mov	[ebx+p.waitc-1], ah ; wait channel + 1
 20331                              <1> 	;
 20332                              <1> 	;push    word [cdev]
 20333                              <1> 	;	; mov cdev,-(sp) / nothing happened in isintr so
 20334 00005166 E832FEFFFF          <1> 	call	swap
 20335                              <1>        		; jsr r0,swap / swap out process that needs to sleep
 20336                              <1>         ;pop     word [cdev]
 20337                              <1> 	;	; mov (sp)+,cdev / restore device
 20338                              <1> 	; 30/11/2021
 20339 0000516B 58                  <1> 	pop	eax
 20340 0000516C A2[D56F0000]        <1> 	mov	[cdev], al
 20341 00005171 E807000000          <1> 	call	isintr
 20342                              <1> 	; 22/09/2013
 20343 00005176 0F8516EBFFFF        <1> 	jnz	sysret         
 20344                              <1> 		; jsr r0,isintr / check for interrupt of new process
 20345                              <1>                		; br 2f / yes, return to new user
 20346                              <1> 		; movb (sp)+,r1 / no, r1 = old process number that was 
 20347                              <1> 				; / originally on the wait channel
 20348                              <1>        		; beq 1f / if 0 branch
 20349                              <1>   		; mov $runq+4,r2 / r2 points to lowest priority queue
 20350                              <1>        		; mov $300,*$ps / processor priority = 6
 20351                              <1> 		; jsr r0,putlu / create link to old process number
 20352                              <1>        		; clr *$ps / clear the status; process priority = 0
 20353                              <1>      ;1:
 20354 0000517C C3                  <1> 	retn
 20355                              <1> 		; rts r0 / return
 20356                              <1>      ;2:
 20357                              <1>         ;;jmp	sysret
 20358                              <1> 		; jmp sysret / return to user
 20359                              <1> 
 20360                              <1> isintr:
 20361                              <1> 	; 30/11/2021	
 20362                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 20363                              <1> 	;
 20364                              <1> 	; 09/05/2013 - 30/05/2014
 20365                              <1> 	;
 20366                              <1> 	; Retro UNIX 8086 v1 modification !
 20367                              <1> 	; (Process/task switching and quit routine by using
 20368                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 20369                              <1> 	;
 20370                              <1> 	; Retro UNIX 8086 v1 modification:
 20371                              <1> 	; 'isintr' checks if user interrupt request is enabled
 20372                              <1> 	;  and there is a 'quit' request by user;
 20373                              <1> 	;  otherwise, 'isintr' will return with zf=1 that means
 20374                              <1> 	;  "nothing to do". (20/10/2013)
 20375                              <1> 	;
 20376                              <1> 	; 20/10/2013
 20377 0000517D 66833D[2E700000]00  <1> 	cmp 	word [u.ttyp], 0 ; has process got a tty ?
 20378 00005185 761F                <1> 	jna	short isintr2 ; retn
 20379                              <1> 	; 03/09/2013
 20380                              <1> 	; (nothing to do)
 20381                              <1> 	;retn
 20382                              <1> 	; 22/09/2013
 20383 00005187 66833D[44700000]00  <1> 	cmp	word [u.intr], 0
 20384 0000518F 7615                <1> 	jna	short isintr2 ; retn
 20385                              <1> 	; 30/05/2014
 20386 00005191 50                  <1> 	push	eax ; 30/11/2021 
 20387 00005192 66A1[46700000]      <1> 	mov	ax, [u.quit]
 20388 00005198 6609C0              <1> 	or	ax, ax ; 0 ?
 20389 0000519B 7408                <1> 	jz	short isintr1 ; zf = 1
 20390 0000519D 6683F8FE            <1> 	cmp	ax, 0FFFEh  ; 'ctrl + brk' check
 20391 000051A1 7702                <1> 	ja	short isintr1 ; 0FFFFh, zf = 0
 20392                              <1> 	;xor	ax, ax ; zf = 1
 20393                              <1> 	; 30/11/2021
 20394 000051A3 31C0                <1> 	xor	eax, eax
 20395                              <1> isintr1:
 20396                              <1> 	;pop	ax
 20397                              <1> 	; 30/11/2021
 20398 000051A5 58                  <1> 	pop	eax
 20399                              <1> isintr2: ; 22/09/2013
 20400                              <1> 	; zf=1 -> nothing to do
 20401 000051A6 C3                  <1> 	retn
 20402                              <1> 
 20403                              <1> 	; UNIX v1 original 'isintr' routine... 
 20404                              <1>        	;mov     r1,-(sp) / put number of wait channel on the stack
 20405                              <1>        	;mov     r2,-(sp) / save r2
 20406                              <1>        	;mov     u.ttyp,r1 / r1 = pointer to buffer of process control
 20407                              <1>         ;                 / typewriter
 20408                              <1>        	;beq     1f / if 0, do nothing except skip return
 20409                              <1>        	;movb    6(r1),r1 / put interrupt char in the tty buffer in r1
 20410                              <1>        	;beq     1f / if its 0 do nothing except skip return
 20411                              <1>        	;cmp     r1,$177 / is interrupt char = delete?
 20412                              <1>        	;bne     3f / no, so it must be a quit (fs)
 20413                              <1>        	;tst     u.intr / yes, value of u.intr determines handling
 20414                              <1>         ;              / of interrupts
 20415                              <1>        	;bne     2f / if not 0, 2f. If zero do nothing.
 20416                              <1>      ;1:
 20417                              <1>        	;tst     (r0)+ / bump r0 past system return (skip)
 20418                              <1>      ;4:
 20419                              <1>        	;mov     (sp)+,r2 / restore r1 and r2
 20420                              <1>        	;mov     (sp)+,r1
 20421                              <1>        	;rts     r0
 20422                              <1>      ;3: / interrupt char = quit (fs)
 20423                              <1>        	;tst     u.quit / value of u.quit determines handling of quits
 20424                              <1>        	;beq     1b / u.quit = 0 means do nothing
 20425                              <1>      ;2: / get here because either u.intr <> 0 or u.qult <> O
 20426                              <1>        	;mov     $tty+6,r1 / move pointer to tty block into r1
 20427                              <1>      ;1: / find process control tty entry in tty block
 20428                              <1>        	;cmp     (r1),u.ttyp / is this the process control tty buffer?
 20429                              <1>        	;beq     1f / block found go to 1f
 20430                              <1>        	;add     $8,r1 / look at next tty block
 20431                              <1>        	;cmp     r1,$tty+[ntty*8]+6 / are we at end of tty blocks
 20432                              <1>        	;blo     1b / no
 20433                              <1>        	;br      4b / no process control tty found so go to 4b
 20434                              <1>      ;1:
 20435                              <1>        	;mov     $240,*$ps / set processor priority to 5
 20436                              <1>        	;movb    -3(r1),0f / load getc call argument; character llst
 20437                              <1>         ;                  / identifier
 20438                              <1>        	;inc     0f / increment
 20439                              <1>      ;1:
 20440                              <1>        	;jsr     r0,getc; 0:.. / erase output char list for control
 20441                              <1>         ;        br 4b / process tty. This prevents a line of stuff
 20442                              <1>         ;             / being typed out after you hit the interrupt
 20443                              <1>         ;             / key
 20444                              <1>        	;br      1b
 20445                                  %include 'u5.s'        ; 03/06/2015
 20446                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 20447                              <1> ; (re-write kernel for test by using previous version without a major defect)
 20448                              <1> ; ****************************************************************************
 20449                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS5.INC
 20450                              <1> ; Last Modification: 30/11/2021
 20451                              <1> ; ----------------------------------------------------------------------------
 20452                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 20453                              <1> ; (v0.1 - Beginning: 11/07/2012)
 20454                              <1> ;
 20455                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 20456                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 20457                              <1> ; <Bell Laboratories (17/3/1972)>
 20458                              <1> ; <Preliminary Release of UNIX Implementation Document>
 20459                              <1> ;
 20460                              <1> ; Retro UNIX 8086 v1 - U5.AS M (07/08/2013) //// UNIX v1 -> u5.s
 20461                              <1> ;
 20462                              <1> ; ****************************************************************************
 20463                              <1> 
 20464                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 20465                              <1> mget_w:
 20466                              <1> 	; 28/10/2021
 20467                              <1> 	; 22/08/2021
 20468                              <1> 	; 20/08/2021
 20469                              <1> 	; 25/05/2020
 20470                              <1> 	; 24/05/2020 - Retro UNIX 386 v2	
 20471 000051A7 C605[2E710000]01    <1> 	mov	byte [mget_rw], 1 ; write access
 20472 000051AE EB07                <1> 	jmp	short mget
 20473                              <1> mget_r:
 20474                              <1> 	; 28/10/2021
 20475                              <1> 	; 22/08/2021
 20476                              <1> 	; 25/05/2020
 20477                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
 20478 000051B0 C605[2E710000]00    <1> 	mov	byte [mget_rw], 0 ; read access	
 20479                              <1> mget:
 20480                              <1> 	; 28/11/2021
 20481                              <1> 	; 22/11/2021
 20482                              <1> 	; 28/10/2021 - temporary (simplified code)
 20483                              <1> 	; 22/08/2021
 20484                              <1> 	; 20/08/2021
 20485                              <1> 	; 25/05/2020
 20486                              <1> 	; 24/05/2020
 20487                              <1> 	; 05/05/2020
 20488                              <1> 	; 02/05/2020, 03/05/2020
 20489                              <1> 	; 29/04/2020 - Retro UNIX 386 v2
 20490                              <1> 	; New inode model/format (Modified UNIX v7 inode model)
 20491                              <1> 	;	
 20492                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20493                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 20494                              <1> 	;
 20495                              <1> 	; Get existing or (allocate) a new disk block for file
 20496                              <1> 	; 
 20497                              <1> 	; INPUTS ->
 20498                              <1> 	;    u.fofp (file offset pointer)
 20499                              <1> 	;    inode 
 20500                              <1> 	;    u.off (file offset)
 20501                              <1> 	; OUTPUTS ->
 20502                              <1> 	;    r1 (physical block number)
 20503                              <1> 	;    r2, r3, r5 (internal)
 20504                              <1> 	;
 20505                              <1> 	; ((AX = R1)) output
 20506                              <1> 	;    (Retro UNIX Prototype : 05/03/2013 - 14/11/2012, UNIXCOPY.ASM)
 20507                              <1> 	;
 20508                              <1> 	; Modified registers: eax, edx, ebx, ecx, esi, edi, ebp
 20509                              <1> 
 20510                              <1> 	; Retro UNIX 386 v2 'mget' procedure
 20511                              <1> 	; source code reference:
 20512                              <1> 	; 'mget' procedure in UNIXHDCP.ASM (25/01/2020) by Erdogan Tan
 20513                              <1> 
 20514                              <1> 	; Get sector/block address for current file pointer
 20515                              <1> 	; (If file pointer points to a number greater than current file
 20516                              <1> 	; size, a new -empty- sector/block will be created/written.)
 20517                              <1> 
 20518                              <1> 	; Note: 'mget' procedure will be used for only RUNIX v2 FS.
 20519                              <1> 	;	(installable file system drivers will not use 'mget')
 20520                              <1> 	;	 !!! 512 bytes per sector !!!  ; 02/05/2020
 20521                              <1> 
 20522                              <1> 	; ! 64 bit fofp ! but Retro UNIX 386 v2 kernel will use 32 bit
 20523                              <1> 	; file offset for regular files and directories.
 20524                              <1> 	; ('mget' procedure will be called for regular files & directories)
 20525                              <1> 
 20526                              <1> 	; 28/10/2021
 20527                              <1> 	; Note: 'mget' uses only current inode ([ii], 'inode:')
 20528                              <1> 	; (inode must be loaded at 'inode:' addr by 'iget' before 'mget')  
 20529                              <1> 
 20530                              <1> 		; mov *u.fofp,mq / file offset in mq
 20531                              <1> 		; clr ac / later to be high sig
 20532                              <1> 		; mov $-8,lsh   / divide ac/mq by 256.
 20533                              <1> 		; mov mq,r2
 20534                              <1> 		; bit $10000,i.flgs / lg/sm is this a large or small file
 20535                              <1> 		; bne 4f / branch for large file
 20536                              <1> mget_0:	
 20537 000051B7 8B35[08700000]      <1>         mov     esi, [u.fofp]
 20538 000051BD 8B1E                <1> 	mov	ebx, [esi]
 20539                              <1>         ; ebx = file offset
 20540                              <1> 
 20541                              <1> 	; 20/08/2021
 20542 000051BF C1EB09              <1> 	shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
 20543                              <1> 
 20544 000051C2 F605[916C0000]10    <1> 	test	byte [i.flgs+1], 10h ; is this a large or small file addr?
 20545                              <1> 	;jz	short mget_1 ; small file addressing
 20546                              <1> 	;jmp	mget_5	; large file addressing
 20547 000051C9 7566                <1> 	jnz	short mget_5 ; 03/05/2020
 20548                              <1> mget_1:
 20549                              <1> 	; If large file flag is clear -not set- RUNIX v2 FS inode
 20550                              <1> 	; will contain 10 direct disk block/sector dword pointers.
 20551                              <1> 
 20552                              <1> 	; 05/05/2020
 20553                              <1> 	;shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
 20554                              <1> 
 20555 000051CB 83FB0A              <1> 	cmp	ebx, 10	; block 10
 20556 000051CE 7324                <1> 	jnb	short mget_3 ; file offset >= 5120
 20557                              <1> 
 20558                              <1> 	; 05/05/2020
 20559                              <1> 	;cmp	ebx, 5120
 20560                              <1> 	;jnb	short mget_3 ; file offset >= 5120
 20561                              <1> 
 20562                              <1> 	;mov	bl, bh
 20563                              <1> 	;and	bl, 1Eh ; clear all bits but bits 1,2,3,4 ; 0,2,..,18
 20564                              <1> 	;	; max. value = 12h = 10010b = 18 (because ebx <= 5119) 
 20565                              <1> 	;shl	bl, 1	; * 2 ; max. value = 24h = 100100b = 36
 20566                              <1> 	;xor	bh, bh  ; clear bh
 20567                              <1> 		; RUNIX v2 (RUFS 2) file system bytes per sector value
 20568                              <1> 		; is always 512.
 20569                              <1> 		; ebx = 4*(ebx/512)  = 0 to 36
 20570                              <1> 
 20571                              <1> 	; 05/05/2020
 20572 000051D0 C0E302              <1> 	shl	bl, 2 ; * 4
 20573                              <1> 		 ; ebx = 0 to 36
 20574                              <1> 
 20575 000051D3 8B83[9C6C0000]      <1> 	mov	eax, [ebx+i.dskp] ; disk sector addr ptr 0 to 9 for file
 20576                              <1> 	; 22/08/2021
 20577 000051D9 89DE                <1> 	mov	esi, ebx
 20578 000051DB 31DB                <1> 	xor	ebx, ebx ; 0
 20579                              <1> 
 20580 000051DD 09C0                <1> 	or	eax, eax
 20581 000051DF 7512                <1> 	jnz	short mget_2 ; existing block/sector
 20582                              <1> 
 20583 000051E1 56                  <1> 	push	esi ; * ; 22/08/2021
 20584 000051E2 E846010000          <1> 	call	alloc_m ; 24/05/2020	
 20585                              <1> 	;call	alloc	; allocate a new sector/block for this file	
 20586                              <1> 			; eax = sector/block number
 20587                              <1> 			; ebx = buffer header address
 20588 000051E7 5E                  <1> 	pop	esi ; * ; 22/08/2021
 20589                              <1> 	; 28/11/2021
 20590                              <1> 	;jc	short mget_2 
 20591                              <1> 			; cf = 1 -> eax = 'no free block' error
 20592                              <1> 	; 22/08/2021
 20593 000051E8 8986[9C6C0000]      <1> 	mov	[esi+i.dskp], eax  ; logical sector/block address
 20594                              <1> 
 20595                              <1> 	;call	setimod	; set inode modification flag
 20596                              <1> 			; and set modification time
 20597                              <1> 	; 24/05/2020
 20598                              <1> 	;retn
 20599 000051EE E979040000          <1> 	jmp	setimod
 20600                              <1> 
 20601                              <1> 	; eax = logical sector/block number
 20602                              <1> 	; ([idev] = logical drive number)
 20603                              <1> 	; 28/10/2021
 20604                              <1> 	; [cdev] = logical drive number (0 or 1)
 20605                              <1> 	;	(0 = root fs, 1 = mounted fs)
 20606                              <1> mget_2:
 20607 000051F3 C3                  <1> 	retn
 20608                              <1> 		; rts r0
 20609                              <1> mget_3: ; 3: / adding on block which changes small file to a large file
 20610                              <1> 	; 22/11/2021
 20611 000051F4 E834010000          <1> 	call	alloc_m ; 24/05/2020
 20612                              <1> 	;call	alloc	; allocate a new sector/block for this file
 20613                              <1> 			; eax = sector/block number
 20614                              <1> 			; ebx = buffer header  ; 24/05/2020
 20615                              <1> 	; 28/11/2021
 20616                              <1> 	;jc	short mget_2 ; error code in eax
 20617                              <1>         ; EAX (r1) = Physical block number
 20618 000051F9 E8C70E0000          <1> 	call 	wslot
 20619                              <1> 		; jsr r0,wslot / set up I/O buffer for write, r5 points to 
 20620                              <1> 			     ; / first data word in buffer
 20621                              <1>         ; EAX (r1) = Physical block number
 20622                              <1> 	; 28/11/2021
 20623                              <1> 	; ebx = buffer (data) address
 20624                              <1> 	; 22/11/2021
 20625 000051FE 31C9                <1> 	xor	ecx, ecx
 20626 00005200 B10A                <1> 	mov 	cl, 10	; r3, transfer old physical block pointers
 20627                              <1> 			; into new indirect block area for the new
 20628                              <1> 			; large file		
 20629 00005202 89DF                <1> 	mov 	edi, ebx ; r5
 20630 00005204 BE[9C6C0000]        <1> 	mov	esi, i.dskp  ; current inode's direct disk addr ptrs
 20631 00005209 89C2                <1> 	mov	edx, eax
 20632 0000520B 31C0                <1> 	xor	eax, eax
 20633                              <1> mget_4:
 20634 0000520D A5                  <1> 	movsd 	
 20635 0000520E 8946FC              <1> 	mov	[esi-4], eax ; 0
 20636 00005211 E2FA                <1> 	loop	mget_4
 20637                              <1> 
 20638                              <1> 	; 22/11/2021
 20639 00005213 B176                <1> 	mov 	cl, 128-10 ; clear rest of data buffer
 20640                              <1> ;mget_4: ; 1
 20641 00005215 F3AB                <1> 	rep 	stosd
 20642                              <1> 		; clr (r5)+
 20643                              <1> 		; dec r3
 20644                              <1> 		; bgt 1b
 20645 00005217 89D0                <1> 	mov	eax, edx
 20646                              <1>         ; EAX (r1) = Physical block number
 20647 00005219 E8C30E0000          <1> 	call	dskwr
 20648                              <1> 		; jsr r0,dskwr / write new indirect block on disk
 20649                              <1>         ; EAX (r1) = Physical block number
 20650 0000521E A3[9C6C0000]        <1> 	mov 	[i.dskp], eax ; 22/11/2021 
 20651                              <1> 		; mov r1,i.dskp / put pointer to indirect block in i-node
 20652 00005223 800D[916C0000]10    <1> 	or	byte [i.flgs+1], 10000b ; 10h ; 16  ; large file flag
 20653                              <1> 		; bis $10000,i.flgs / set large file bit 
 20654                              <1> 				  ; / in i.flgs word of i-node
 20655 0000522A E83D040000          <1> 	call	setimod
 20656                              <1> 		; jsr r0,setimod / set i-node modified flag
 20657                              <1> 
 20658 0000522F EB86                <1> 	jmp	short mget_0 
 20659                              <1> 		; br mget
 20660                              <1> 
 20661                              <1> mget_5:  ; 4 ; large file
 20662                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 20663                              <1> 	;
 20664                              <1> 	; Retro UNIX 386 v2 disk inode contains..
 20665                              <1> 	; (if large file flag is set)
 20666                              <1> 	; 8 indirect disk block/sector dword pointers
 20667                              <1> 	; +1 double indirect disk block/sector dword pointers
 20668                              <1> 	; +1 triple indirect disk block/sector dword pointers
 20669                              <1> 
 20670                              <1> 	; check indirect pointers limit (as file offset)
 20671                              <1> 	; 8*128 = 1024 blocks (or sectors) or 512 KB
 20672                              <1> 	; check dx (file offset hw) value
 20673                              <1> 	
 20674                              <1> 	; 03/05/2020
 20675                              <1> 	;cmp	ebx, 524288  ; is file offset >= 524288 ?
 20676                              <1> 	;jnb	short mget_6 ; yes, check double indirect limit
 20677                              <1> 
 20678                              <1> 	; 05/05/2020
 20679 00005231 81FB00040000        <1> 	cmp	ebx, 1024    ; block 1024 (byte 524288)	
 20680 00005237 7321                <1> 	jnb	short mget_6 ; check double indirect limit
 20681                              <1> 
 20682 00005239 C605[30710000]01    <1> 	mov	byte [level], 1 ; levels, 1 = indirect blocks
 20683                              <1> 
 20684                              <1> 	; 05/05/2020
 20685                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 20686                              <1> 
 20687 00005240 88D9                <1> 	mov	cl, bl
 20688 00005242 80E17F              <1> 	and	cl, 127
 20689 00005245 880D[31710000]      <1> 	mov	[level+1], cl ; level 1, direct block ptr index (0 to 127)
 20690 0000524B 66C1EB07            <1> 	shr	bx, 7 ; bl = level 0, indirect block pointer index (0 to 7)
 20691                              <1> 	;mov	[level+2], bl
 20692                              <1> 
 20693 0000524F C0E302              <1> 	shl	bl, 2 ; * 4 to convert index number to offset
 20694                              <1> 
 20695                              <1> 	;mov	esi, i.dskp
 20696                              <1> 	;add	esi, ebx
 20697                              <1> 
 20698 00005252 8DB3[9C6C0000]      <1> 	lea	esi, [ebx+i.dskp]
 20699                              <1> 
 20700 00005258 EB66                <1> 	jmp	short mget_8
 20701                              <1> 
 20702                              <1> mget_6:
 20703                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 20704                              <1> 	; 03/05/2020
 20705                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 20706                              <1> 	; check double indirect pointer limit (as file offset)
 20707                              <1> 	; (128*128)+1024 = 16384+1024 blocks or 8 MB + 512 KB
 20708                              <1> 	; check dx (file offset hw) value
 20709                              <1> 	
 20710                              <1> 	;cmp	ebx, 8912896 ; >= 17408 sectors (16384+1024) ?	
 20711                              <1> 	;jnb	short mget_7 ; yes, use triple indirect pointer (block)
 20712                              <1> 
 20713                              <1> 	; 05/05/2020
 20714 0000525A 81FB00440000        <1> 	cmp	ebx, 17408   ; block 17408 (byte 8912896)	
 20715 00005260 7329                <1> 	jnb	short mget_7 ; use triple indirect pointer (block)
 20716                              <1> 
 20717 00005262 C605[30710000]02    <1> 	mov	byte [level], 2  ; levels, 2 = double indirect blocks
 20718                              <1> 	
 20719                              <1> 	;sub	ebx, 524288 ; 1024 sectors
 20720                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 20721                              <1> 			; (from sector 1024)
 20722                              <1> 	; 05/05/2020
 20723 00005269 81EB00040000        <1> 	sub	ebx, 1024 ; offset from sector 1024
 20724                              <1> 	
 20725 0000526F 88D9                <1> 	mov	cl, bl
 20726 00005271 80E17F              <1> 	and	cl, 127
 20727 00005274 880D[31710000]      <1> 	mov	[level+1], cl
 20728                              <1> 			; level 2, direct block ptr index (0 to 127)	
 20729 0000527A 66C1EB07            <1> 	shr	bx, 7
 20730 0000527E 881D[32710000]      <1> 	mov	[level+2], bl
 20731                              <1> 			; level 1, indirect block ptr index (0 to 127)
 20732                              <1> 
 20733 00005284 BE[BC6C0000]        <1> 	mov	esi, i.dskp + 32 ; 8*4
 20734                              <1> 			; level 0, double indirect block pointer
 20735 00005289 EB35                <1> 	jmp	short mget_8
 20736                              <1> 
 20737                              <1> mget_7:
 20738                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 20739                              <1> 	; 03/05/2020
 20740                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 20741                              <1> 	; triple indirect pointer ; 8912896 to 1082654720 bytes
 20742                              <1> 	;mov	esi, i.dskp + 36 ; 9*4
 20743                              <1> 
 20744 0000528B C605[30710000]03    <1> 	mov	byte [level], 3  ; levels, 3 = triple indirect blocks
 20745                              <1> 
 20746                              <1> 	;sub	ebx, 8912896 ; 17408 sectors (16384+1024)
 20747                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 20748                              <1> 			; (from sector 17408)
 20749                              <1> 	; 05/05/2020
 20750 00005292 81EB00440000        <1> 	sub	ebx, 17408 ; offset from sector 17408	
 20751                              <1> 
 20752 00005298 88D9                <1> 	mov	cl, bl
 20753 0000529A 80E17F              <1> 	and	cl, 127
 20754 0000529D 880D[31710000]      <1> 	mov	[level+1], cl  
 20755                              <1> 			; level 3, direct block ptr index (0 to 127)	
 20756 000052A3 C1EB07              <1> 	shr	ebx, 7	
 20757 000052A6 88D9                <1> 	mov	cl, bl
 20758 000052A8 80E17F              <1> 	and	cl, 127
 20759 000052AB 880D[32710000]      <1> 	mov	[level+2], cl
 20760                              <1> 			; level 2, indirect block ptr index (0 to 127)
 20761 000052B1 66C1EB07            <1> 	shr	bx, 7
 20762 000052B5 881D[33710000]      <1> 	mov	[level+3], bl
 20763                              <1> 			; level 1, double indir blk ptr index (0 to 127)
 20764                              <1> 
 20765 000052BB BE[C06C0000]        <1> 	mov	esi, i.dskp + 36 ; 9*4
 20766                              <1> 			; level 0, triple indirect block pointer
 20767                              <1> mget_8:
 20768                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibiliy modification
 20769 000052C0 8B06                <1> 	mov	eax, [esi]
 20770 000052C2 09C0                <1> 	or 	eax, eax ; R1
 20771 000052C4 7515                <1> 	jnz 	short mget_10 ; 2f
 20772                              <1> 		; bne 2f / if no indirect block exists
 20773 000052C6 56                  <1> 	push	esi	; * ; 24/05/2020
 20774                              <1> 
 20775 000052C7 E861000000          <1> 	call	alloc_m ; 24/05/2020
 20776                              <1> 	;call	alloc	; allocate a new block for this file	
 20777                              <1> 			; eax = block number
 20778                              <1> 			; ebx = buffer header address
 20779                              <1> 			; [pdn] = physical drive number ; 25/05/2020
 20780                              <1> 	;jc	mget_2	; cf -> 1 & eax = 0 -> no free block
 20781                              <1> 
 20782 000052CC 5E                  <1> 	pop	esi	; * ; 24/05/2020
 20783                              <1> 	;jc	short mget_9
 20784                              <1> 
 20785 000052CD 8906                <1> 	mov	[esi], eax ; record sector/block address on i.dskp area
 20786                              <1> 
 20787 000052CF E898030000          <1> 	call 	setimod
 20788                              <1> 		; jsr r0,setimod / set i-node modified byte
 20789                              <1> 	; EAX = new block number
 20790 000052D4 E8C1FDFFFF          <1> 	call 	clear
 20791                              <1> 		; jsr r0,clear / clear new block
 20792                              <1> 	; 22/11/2021
 20793 000052D9 EB05                <1> 	jmp	short mget_11
 20794                              <1> ;mget_9:
 20795                              <1> ;	retn
 20796                              <1> mget_10: ;2
 20797                              <1> 	; 05/03/2013
 20798                              <1> 	; EAX = r1, physical block number (of indirect block)
 20799 000052DB E8850D0000          <1> 	call 	dskrd ; read indirect block
 20800                              <1> 		; jsr r0,dskrd / read in indirect block
 20801                              <1> 	;jc	short mget_9
 20802                              <1> mget_11:
 20803                              <1> 	; 22/11/2021
 20804                              <1> 	; eax = physical block/sector address
 20805                              <1> 	; ebx = buffer address
 20806                              <1> 
 20807 000052E0 89C2                <1> 	mov	edx, eax ; *  ; save sector number in edx
 20808                              <1> 
 20809 000052E2 0FB605[30710000]    <1> 	movzx	eax, byte [level]
 20810 000052E9 8A80[30710000]      <1> 	mov	al, [eax+level] ; get sector pointer offset
 20811 000052EF 66C1E002            <1> 	shl	ax, 2 ; * 4
 20812                              <1> 
 20813 000052F3 01C3                <1> 	add	ebx, eax
 20814                              <1> 
 20815 000052F5 8B03                <1> 	mov 	eax, [ebx] ; put physical block no of block
 20816                              <1> 			   ; in file sought in R1 (EAX)
 20817                              <1> 		; mov (r2),r1 / put physical block no of block in file
 20818                              <1> 	               	    ; / sought in r1
 20819                              <1> 
 20820 000052F7 21C0                <1> 	and	eax, eax  ; if logical sector/block number is zero
 20821                              <1> 			  ; then we need a new block for file
 20822 000052F9 740B                <1> 	jz	short mget_12
 20823                              <1> 
 20824 000052FB FE0D[30710000]      <1> 	dec	byte [level]
 20825 00005301 75D8                <1> 	jnz	short mget_10
 20826                              <1> 
 20827 00005303 29DB                <1> 	sub	ebx, ebx ; ebx = 0 ; existing sector
 20828                              <1> 
 20829 00005305 C3                  <1> 	retn
 20830                              <1> 
 20831                              <1> mget_12:
 20832                              <1> 	; 22/11/2021
 20833 00005306 52                  <1> 	push	edx ; *
 20834 00005307 53                  <1> 	push	ebx ; **	 ; buffer data position
 20835 00005308 E820000000          <1> 	call	alloc_m
 20836                              <1> 	;call	alloc	 ; allocate a new block for this file	
 20837                              <1> 			 ; eax = block number (logical)
 20838                              <1> 			 ; ebx = buffer header address
 20839 0000530D 5E                  <1> 	pop	esi ; **
 20840 0000530E 5A                  <1> 	pop	edx ; *
 20841                              <1> 	;jc	short mget_9 ; cf -> 1 & eax = 0 -> no free block
 20842                              <1> 
 20843 0000530F 8906                <1> 	mov	[esi], eax ; record/save block number (logical)
 20844                              <1> 
 20845                              <1> 	; 22/11/2021
 20846 00005311 870424              <1> 	xchg	eax, [esp] ; *
 20847                              <1> 
 20848                              <1> 	; eax (r1) = physical block number (of indirect block)
 20849 00005314 E8AC0D0000          <1> 	call 	wslot
 20850                              <1> 		; jsr r0,wslot
 20851                              <1>         ; eax (r1) = physical block number
 20852                              <1> 	; ebx (r5) = pointer to buffer (indirect block)
 20853 00005319 E8C30D0000          <1> 	call 	dskwr
 20854                              <1> 	; eax = r1 = physical block number (of indirect block)
 20855                              <1> 		; jsr r0,dskwr / write newly modified indirect block 
 20856                              <1> 			     ; / back out on disk
 20857 0000531E 58                  <1> 	pop	eax ; *  ; 31/07/2013
 20858                              <1> 		; mov (sp),r1 / restore block number of new block	
 20859                              <1> 	; eax (r1) = physical block number of new block
 20860 0000531F E876FDFFFF          <1> 	call 	clear
 20861                              <1> 		; jsr r0,clear / clear new block
 20862                              <1> 
 20863 00005324 FE0D[30710000]      <1> 	dec	byte [level]
 20864 0000532A 75B4                <1> 	jnz	short mget_11
 20865                              <1> 	
 20866                              <1> 	; 22/11/2021
 20867                              <1> 	; ebx = buffer address
 20868                              <1> mget_13: ; 2
 20869                              <1> 	; eax (r1) = Block number of new block
 20870 0000532C C3                  <1> 	retn
 20871                              <1> 		; rts r0
 20872                              <1> 
 20873                              <1> 	; 26/11/2021
 20874                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 20875                              <1> alloc_m:
 20876                              <1> 	; 27/11/2021
 20877                              <1> 	; 28/10/2021
 20878                              <1> 	; 07/05/2021
 20879                              <1> 	; 26/05/2020
 20880                              <1> 	; 25/05/2020
 20881                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
 20882                              <1> 	; 'alloc' call in 'mget'
 20883                              <1> 	;
 20884                              <1> 	; (('mget_r' will be returned with error))
 20885                              <1> 	; (('mget_w' will continue to 'alloc'))
 20886                              <1> 
 20887                              <1> 	; Note: 'sysread' will return with cf = 0, eax = 0
 20888                              <1> 	; if [fofp] >= file size (eax = 0 --> EOF)
 20889                              <1> 	; So, if we are here, that means [fofp] < file size
 20890                              <1> 	;     but disk address is 0. 
 20891                              <1> 	
 20892 0000532D 803D[2E710000]01    <1> 	cmp	byte [mget_rw], 1 ; write access ? (mget_w) 
 20893 00005334 730F                <1> 	jnb	short alloc ; yes (this is a call from 'mget_w')
 20894                              <1> 	; ((cf = 1))	
 20895                              <1> 	; no (this is a call from 'mget_r') !
 20896                              <1> 	;mov	eax, ERR_FILE_SIZE ; file size error (inode error!)
 20897                              <1> 		; [User may change this empty/invalid inode (disk) sector
 20898                              <1> 		; pointer with a new valid inode (disk) sector pointer 
 20899                              <1> 		; by writing new clear (zero) sector to same file position
 20900                              <1> 		; in order to correct file size -inode parm/content- error.
 20901                              <1> 		; It may be useful for recovering lost data if other sector
 20902                              <1> 		; pointers are not empty.]	
 20903                              <1> 	;retn
 20904                              <1> 	; 27/11/2021
 20905 00005336 C705[6A700000]1400- <1> 	mov	dword [u.error], ERR_FILE_SIZE 
 20906 0000533E 0000                <1>
 20907                              <1> 			; file size error (inode error!)
 20908 00005340 E92DE9FFFF          <1> 	jmp	error
 20909                              <1> alloc:
 20910                              <1> 	; 27/11/2021
 20911                              <1> 	; 26/11/2021 - Major modification for Runix v2 file system
 20912                              <1> 	;	(I have called this kernel version as v1.2, it is a
 20913                              <1> 	;	 debug/test version just before Retro UNIX 386 v2 kernel)
 20914                              <1> 	;	((there were running problems on new version, 
 20915                              <1> 	;	  so i am developing an intermediate version with minimum
 20916                              <1> 	;	  modification on v1.1 code which is successfuly running))
 20917                              <1> 	;	 ; /// Erdogan Tan - Istanbul, 26/11/2021 /// 
 20918                              <1> 	;	 
 20919                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20920                              <1> 	; 01/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20921                              <1> 	;
 20922                              <1> 	; get a free block and 
 20923                              <1> 	; set the corresponding bit in the free storage map
 20924                              <1> 	; 
 20925                              <1> 	; INPUTS ->
 20926                              <1> 	;    cdev (current device)
 20927                              <1> 	;    r2 
 20928                              <1> 	;    r3
 20929                              <1> 	; OUTPUTS ->
 20930                              <1> 	;    r1 (physical block number of block assigned)
 20931                              <1> 	;    smod, mmod, systm (super block), mount (mountable super block)	
 20932                              <1> 	;
 20933                              <1> 	; ((AX = R1)) output
 20934                              <1> 	;    (Retro UNIX Prototype : 14/11/2012 - 21/07/2012, UNIXCOPY.ASM)
 20935                              <1>         ;    ((Modified registers: edx, ecx)) 
 20936                              <1> 
 20937                              <1> 	; 26/11/2021
 20938                              <1> 	; INPUT:
 20939                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
 20940                              <1> 	; OUTPUT:
 20941                              <1> 	;	eax = disk block/sector number/address (physical)
 20942                              <1> 	;	(ebx = disk buffer address for sector/block in eax)
 20943                              <1> 	;
 20944                              <1> 	;    Note:	
 20945                              <1> 	;	Free blocks map will be modified and written to it's disk.
 20946                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
 20947                              <1> 	;	modification flag will be set; but the superblock 
 20948                              <1> 	;	will not be written to it's disk in this 'alloc' procedure)
 20949                              <1> 	;
 20950                              <1> 	; Modified registers: eax, ebx, ecx, edx, esi, edi, ebp 
 20951                              <1> 
 20952                              <1> 	; 26/11/2021
 20953 00005345 BB[687D0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
 20954                              <1> 		; mov $systm,r2 / start of inode and free storage map for drum
 20955 0000534A F605[D56F0000]01    <1> 	test	byte [cdev], 1
 20956                              <1> 		; tst cdev
 20957 00005351 7405                <1> 	jz	short alloc_1
 20958                              <1> 		; beq 1f / drum is device
 20959 00005353 BB[707F0000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
 20960                              <1> 		; mov $mount,r2 / disk or tape is device, start of inode and
 20961                              <1> 			      ; / free storage map
 20962                              <1> alloc_1: ; 1
 20963                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 20964                              <1> 	;test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
 20965                              <1> 	;jnz	short alloc_2  ; 'read only file system' error
 20966                              <1> 	;
 20967 00005358 8B4B38              <1> 	mov	ecx, [ebx+SB.FreeBlocks] ; count of free blocks/sectors
 20968 0000535B 21C9                <1> 	and	ecx, ecx
 20969 0000535D 750F                <1> 	jnz	short alloc_3
 20970                              <1> alloc_2:
 20971                              <1> 	; 'no free blocks on disk !' error
 20972 0000535F C705[6A700000]2100- <1> 	mov	dword [u.error], ERR_ALLOC
 20973 00005367 0000                <1>
 20974 00005369 E904E9FFFF          <1> 	jmp	error
 20975                              <1> alloc_3:
 20976                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 20977 0000536E 31C0                <1> 	xor	eax, eax
 20978                              <1> 	; 23/07/2021
 20979 00005370 8B4B3C              <1> 	mov	ecx, [ebx+SB.FirstFreeBlk] ; 1st free sector number
 20980                              <1> 					 ; (as logical sector number)
 20981 00005373 09C9                <1> 	or	ecx, ecx
 20982 00005375 7415                <1> 	jz	short alloc_5 ; 0 = initial/reset value or 'not valid'
 20983 00005377 41                  <1> 	inc	ecx ; 0FFFFFFFFh -> 0
 20984 00005378 7412                <1> 	jz	short alloc_5 ; 'not valid' or 'not calculated'
 20985 0000537A 49                  <1> 	dec	ecx ; restore first free block value
 20986 0000537B 89C8                <1> 	mov	eax, ecx
 20987                              <1> 	; 1 allocation byte (in fbm) is for 8 sectors
 20988 0000537D C1E903              <1> 	shr	ecx, 3 ; first free block number / 8
 20989 00005380 80E1FC              <1> 	and	cl, ~3  ; dword alignment (to backward)
 20990                              <1> 	; 27/11/2021
 20991 00005383 890D[70810000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm
 20992                              <1> alloc_4:
 20993 00005389 C1E80C              <1> 	shr	eax, 12 ; 1 fbm sector for 4096 sectors
 20994                              <1> alloc_5:
 20995                              <1> 	; 26/11/2021
 20996 0000538C 53                  <1> 	push	ebx ; ** ; superblock buffer address 
 20997                              <1> 	; eax = fbm sector index
 20998 0000538D A3[74810000]        <1> 	mov	[free_map_index], eax
 20999 00005392 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
 21000                              <1> 			; free blocks map start sector addr
 21001                              <1> 	;add	eax, [ebx+SB.BootSectAddr] 
 21002                              <1> 	;		; + Hidden Sectors
 21003                              <1> 	; eax = physical sector number
 21004 00005395 E8CB0C0000          <1> 	call	dskrd
 21005                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 21006                              <1> 	; eax = physical sector number
 21007                              <1> 	; ebx = buffer data address
 21008                              <1> 	; 27/11/2021
 21009 0000539A 8B15[70810000]      <1> 	mov	edx, [free_map_offset] ; byte position on fbm
 21010 000053A0 A3[78810000]        <1> 	mov	[free_map_sector], eax ; physical sector number
 21011 000053A5 B9FF010000          <1> 	mov	ecx, 511
 21012                              <1> 	;and	edx, 511
 21013 000053AA 21CA                <1> 	and 	edx, ecx ; fbm byte offset in fbm buffer
 21014 000053AC 41                  <1> 	inc	ecx ; 512
 21015 000053AD 01D9                <1> 	add	ecx, ebx
 21016 000053AF 01DA                <1> 	add	edx, ebx ; + buffer address
 21017 000053B1 5B                  <1> 	pop	ebx ; ** ; superblock buffer address 
 21018                              <1> 	;
 21019                              <1> 	; ebx = superblock buffer address
 21020                              <1> 	; edx = superblock buffer address + byte offset (dword aligned)
 21021                              <1> 	; ecx = superblock buffer address + 512
 21022                              <1> alloc_6:
 21023                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 21024                              <1> 	;		for Retro UNIX 386 v1.2
 21025                              <1> 	; 25/05/2020 - Retro UNIX 386 v2 code
 21026                              <1> 	; (dword scan) ((1 dword = 32 sectors, 1 byte = 8 sectors))
 21027                              <1> 	; ((Note: Logical drive size must be multiplies of 32 sectors))
 21028                              <1> 	; 19/05/2020
 21029                              <1> 	; edx = free blocks map byte address 
 21030 000053B2 0FBC02              <1> 	bsf	eax, [edx] ; Scans source operand for first bit set (1).
 21031                              <1> 			  ; Clear ZF if a bit is found set (1) and 
 21032                              <1> 			  ; loads the destination with an index to
 21033                              <1> 			  ; first set bit. (0 -> 31) 
 21034                              <1> 			  ; Sets ZF to 1 if no bits are found set.
 21035 000053B5 752A                <1> 	jnz	short alloc_8 ; ZF = 0 -> a free block has been found
 21036                              <1> 
 21037 000053B7 A1[70810000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
 21038 000053BC 83C004              <1> 	add	eax, 4 ; next dword
 21039 000053BF 3B431C              <1> 	cmp	eax, [ebx+SB.FreeMapSize] ; fbm size in bytes
 21040 000053C2 7209                <1> 	jb	short alloc_7
 21041                              <1> 	; invalidate superblock's first free block field
 21042 000053C4 C7433CFFFFFFFF      <1> 	mov	dword [ebx+SB.FirstFreeBlk], 0FFFFFFFFh
 21043                              <1> 	; 'no free blocks on disk !' error
 21044 000053CB EB92                <1> 	jmp	alloc_2
 21045                              <1> alloc_7:
 21046                              <1> 		; 26/05/2020
 21047                              <1> 		; NOTE: If ldrv size is not multiplies of 32 sectors,
 21048                              <1> 		; mod (ldrv size / 32) sectors (at the end of ldrv)
 21049                              <1> 		; can not be allocated (for regular files or dirs)! 
 21050                              <1> 		; (Kernel or runix fs installation program can use
 21051                              <1> 		;  this fact to save/duplicate critical sectors/data 
 21052                              <1> 		;  onto end sectors of that logical drive's runix fs.)
 21053                              <1> 
 21054                              <1> 	; 26/11/2021
 21055 000053CD A3[70810000]        <1> 	mov	[free_map_offset], eax
 21056                              <1> 	; 28/07/2021
 21057                              <1> 	; set next first free block value for search
 21058 000053D2 C1E003              <1> 	shl	eax, 3 ; * 8 ; first free block
 21059                              <1>  	; 26/11/2021
 21060 000053D5 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
 21061                              <1> 	; search (scan) for next free block map dword (in buffer)
 21062 000053D8 83C204              <1> 	add	edx, 4 ; next dword
 21063 000053DB 39CA                <1> 	cmp	edx, ecx
 21064 000053DD 72D3                <1> 	jb	short alloc_6
 21065                              <1> 	; 27/11/2021
 21066 000053DF EBA8                <1> 	jmp	short alloc_4
 21067                              <1> 
 21068                              <1> alloc_8:
 21069                              <1> 	; 26/11/2021
 21070                              <1> 	; convert bit index to xor value
 21071                              <1> 	; and then set allocated flag for corresponding fbm bit 
 21072 000053E1 89C1                <1> 	mov	ecx, eax
 21073                              <1> 	;mov	cl, al 
 21074                              <1> 	;sub	eax, eax
 21075                              <1> 	;inc	al ; eax = 1
 21076 000053E3 B001                <1> 	mov	al, 1
 21077 000053E5 D3E0                <1> 	shl	eax, cl
 21078 000053E7 3102                <1> 	xor	[edx], eax  ; clear allocated block's bit in the fbm
 21079                              <1> 	; zero bit means allocated disk block (1 means free disk block) 
 21080                              <1> 
 21081 000053E9 A1[70810000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
 21082                              <1> 		; note: eax is dword aligned (0,4,8,12..) !
 21083 000053EE C1E003              <1> 	shl	eax, 3 ; * 8 ; free block number base
 21084 000053F1 01C8                <1> 	add	eax, ecx ; add allocation bit index (0 to 31)	
 21085 000053F3 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax ; current free block
 21086                              <1> 				; (which is being allocated here)
 21087                              <1> 
 21088                              <1> 	;mov	eax, [ebx+SB.FreeMapAddr] 
 21089                              <1> 	;		; free blocks map start sector addr
 21090                              <1> 	;add	eax, [free_map_index]
 21091                              <1> 	
 21092                              <1> 	;;add	eax, [ebx+SB.BootSectAddr] 
 21093                              <1> 	;		; + Hidden Sectors
 21094                              <1> 	; eax = physical sector number
 21095                              <1> 	
 21096                              <1> 	; 27/11/2021
 21097 000053F6 A1[78810000]        <1> 	mov	eax, [free_map_sector] ; physical sector number
 21098                              <1> 	
 21099 000053FB E8C50C0000          <1> 	call	wslot
 21100                              <1> 	; ebx = buffer data address (write operation bit is set)
 21101                              <1> 	; eax = physical sector number
 21102                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
 21103                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 21104                              <1> 
 21105                              <1> 	; 27/11/2021
 21106                              <1> 	;mov	[free_map_buffer], ebx ; save free map buffer address
 21107                              <1> 
 21108 00005400 E8DC0C0000          <1> 	call	dskwr ; writes the 1st buffer to sector
 21109                              <1> 		      ; (at the beginning/head of the buffer chain)
 21110                              <1> 
 21111                              <1> 	; if we are here, buffer has been written to disk successfully 
 21112                              <1> 	; (otherwise cpu would jump to 'error' address)
 21113                              <1> 
 21114                              <1> 	; set superblock modified flag
 21115 00005405 BA[E76F0000]        <1> 	mov	edx, smod
 21116 0000540A BB[687D0000]        <1> 	mov	ebx, systm
 21117 0000540F F605[D56F0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 21118 00005416 7406                <1> 	jz	short alloc_9  ; no, root device
 21119                              <1> 	; yes, mounted device
 21120 00005418 BB[707F0000]        <1> 	mov	ebx, mount
 21121                              <1> 	;mov	edx, mmod
 21122 0000541D 42                  <1> 	inc	edx ; edx = offset mmod
 21123                              <1> alloc_9: 
 21124 0000541E FE02                <1> 	inc	byte [edx] ; superblock modified !
 21125                              <1> 	
 21126                              <1> 	; Allocating a new sector/block (for file) has been completed here.
 21127 00005420 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
 21128 00005423 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0 
 21129 00005424 7405                <1> 	jz	short alloc_10 ; not valid (not set)
 21130 00005426 48                  <1> 	dec	eax ; Free Blocks
 21131 00005427 48                  <1> 	dec	eax ; Free Blocks = Free Blocks - 1
 21132 00005428 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax
 21133                              <1> alloc_10:
 21134 0000542B E8680D0000          <1> 	call	get_system_time
 21135                              <1> 		; eax = current time (as unix epoch time)
 21136                              <1> 	; 30/07/2021
 21137 00005430 89435C              <1> 	mov	[ebx+SB.ModifTime], eax
 21138                              <1> 
 21139 00005433 8B433C              <1> 	mov	eax, [ebx+SB.FirstFreeBlk] ; allocated block address
 21140 00005436 FF433C              <1> 	inc	dword [ebx+SB.FirstFreeBlk] 
 21141                              <1> 				; +1, new value of first free block
 21142                              <1> 				; (new search will be started from here)
 21143                              <1> 				; ((it may not be free, no problem))
 21144                              <1> 
 21145                              <1> 	; put free map buffer address in ebx
 21146                              <1> 	; 27/11/2021
 21147                              <1> 	;mov	ebx, [free_map_buffer]
 21148                              <1> 
 21149 00005439 C3                  <1> 	retn	
 21150                              <1> 
 21151                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 21152                              <1> free:
 21153                              <1> 	; 05/11/2021
 21154                              <1> 	; 29/10/2021 - temporary (simplified code)
 21155                              <1> 	; 14/08/2021
 21156                              <1> 	; 12/06/2021
 21157                              <1> 	; 07/06/2020
 21158                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 21159                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21160                              <1> 	; 07/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 21161                              <1> 	;
 21162                              <1> 	; calculates byte address and bit position for given block number
 21163                              <1> 	; then sets the corresponding bit in the free storage map
 21164                              <1> 	; 
 21165                              <1> 	; INPUTS ->
 21166                              <1> 	;    r1 - block number for a block structured device
 21167                              <1> 	;    cdev - current device 
 21168                              <1> 	; OUTPUTS ->
 21169                              <1> 	;    free storage map is updated
 21170                              <1> 	;    smod is incremented if cdev is root device (fixed disk)
 21171                              <1> 	;    mmod is incremented if cdev is a removable disk 	
 21172                              <1> 	;
 21173                              <1> 	;  (Retro UNIX Prototype : 01/12/2012, UNIXCOPY.ASM)
 21174                              <1>         ;  ((Modified registers: DX, CX))  
 21175                              <1> 
 21176                              <1> 	; 27/11/2021
 21177                              <1> 	; INPUT:
 21178                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
 21179                              <1> 	;	eax = disk block/sector number/address (logical)
 21180                              <1> 	; OUTPUT:
 21181                              <1> 	;	ebx = superblock buffer address
 21182                              <1> 	;
 21183                              <1> 	;    Note:	
 21184                              <1> 	;	Free blocks map will be modified and written to it's disk.
 21185                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
 21186                              <1> 	;	modification flag will be set; but the superblock 
 21187                              <1> 	;	will not be written to it's disk in this 'free' procedure)
 21188                              <1> 	;
 21189                              <1> 	; Modified registers: ebx, ecx, edx, esi, edi, ebp 
 21190                              <1> 
 21191                              <1> 	; 27/11/2021
 21192 0000543A BB[687D0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
 21193 0000543F F605[D56F0000]01    <1> 	test	byte [cdev], 1
 21194 00005446 7405                <1> 	jz	short free_1
 21195 00005448 BB[707F0000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
 21196                              <1> free_1: ; 1
 21197                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 file system compatibility code
 21198                              <1> 	;test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
 21199                              <1> 	;jz	short free_2 
 21200                              <1> 	; 'read only file system' error
 21201 0000544D C705[6A700000]1E00- <1> 	mov	dword [u.error], ERR_READ_ONLY_FS
 21202 00005455 0000                <1>
 21203 00005457 E916E8FFFF          <1> 	jmp	error
 21204                              <1> free_2:
 21205 0000545C 89C1                <1> 	mov	ecx, eax ; logical sector/block number
 21206 0000545E A3[78810000]        <1> 	mov	[free_map_sector], eax
 21207 00005463 C1E903              <1> 	shr	ecx, 3	; convert to fbmap byte offset
 21208 00005466 C1E80C              <1> 	shr	eax, 12 ; convert to fbmap sector index 
 21209                              <1> 			; (1 fb sector for 4096 sectors)
 21210                              <1> 	;and	cl, ~3	; dword alignment (to backward)
 21211 00005469 890D[70810000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm
 21212                              <1> 	; 27/11/2021
 21213                              <1> 	; eax = fbm sector index
 21214 0000546F 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
 21215                              <1> 			; free blocks map start sector address
 21216                              <1> 	;add	eax, [ebx+SB.BootSectAddr]
 21217                              <1> 	;		; + Hidden Sectors
 21218                              <1> 	; ebx = superblock address
 21219                              <1> 	; eax = physical sector number
 21220 00005472 E8EE0B0000          <1> 	call	dskrd
 21221                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 21222                              <1> 	; eax = physical sector number
 21223                              <1> 	; ebx = buffer data address
 21224                              <1> 	; 27/11/2021
 21225 00005477 A3[74810000]        <1> 	mov	[free_map_index], eax  ; save physical sector address
 21226 0000547C 8B15[70810000]      <1> 	mov	edx, [free_map_offset] ; byte position on fbm
 21227                              <1> 	;
 21228 00005482 29C0                <1> 	sub	eax, eax
 21229 00005484 A0[78810000]        <1> 	mov	al, [free_map_sector] ; logical sector number
 21230 00005489 2407                <1> 	and	al, 7
 21231                              <1> 
 21232                              <1> 	; al = bit offset in fbm allocation byte
 21233                              <1> 	; edx = buffer address (start+offset)
 21234                              <1> 	; [free_map_offset] = byte position on fbm
 21235                              <1> 	; 27/11/2021
 21236 0000548B 0FAB02              <1> 	bts	[edx], eax  ; copy value of bit position in eax to cf
 21237                              <1> 			    ; then set same bit position at [edx]
 21238 0000548E 7305                <1> 	jnc	short free_3 ; it was allocated sector
 21239                              <1> 
 21240                              <1> 	; already free sector !? 
 21241                              <1> 	; (nonsence or defective fs)
 21242                              <1> 
 21243 00005490 30C0                <1> 	xor	al, al ; 0  ; eax = 0
 21244 00005492 48                  <1> 	dec	eax ; 0FFFFFFFFh
 21245                              <1> 	;mov	[ebx+SB.FreeBlocks], eax 
 21246                              <1> 		; invalidate free blocks count
 21247 00005493 EB18                <1> 	jmp	short free_5
 21248                              <1> free_3:
 21249                              <1> 	; 27/11/2021
 21250 00005495 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
 21251 00005498 40                  <1> 	inc	eax
 21252 00005499 7401                <1> 	jz	short free_4 ; 0FFFFFFFFh -> 0 (invalid!)
 21253 0000549B 48                  <1> 	dec	eax  ; 0 -> 0FFFFFFFFh (invalid!)
 21254                              <1> free_4: 
 21255 0000549C 50                  <1> 	push	eax ; * ; number of free blocks 
 21256                              <1> 	;mov	eax, [free_map_index] ; fbm sector index
 21257                              <1> 	;add	eax, [ebx+SB.FreeMapAddr] 
 21258                              <1> 			; free blocks map start sector address
 21259                              <1> 	;add	eax, [ebx+SB.BootSectAddr]
 21260                              <1> 	;		; + Hidden Sectors
 21261 0000549D A1[74810000]        <1> 	mov	eax, [free_map_index] ; restore physical sector address
 21262                              <1> 	; eax = physical sector number
 21263 000054A2 E81E0C0000          <1> 	call	wslot
 21264                              <1> 	; ebx = buffer data address (write operation bit is set)
 21265                              <1> 	; eax = physical sector number
 21266                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
 21267                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 21268                              <1> 
 21269 000054A7 E8350C0000          <1> 	call	dskwr ; writes the 1st buffer to sector
 21270                              <1> 		      ; (at the beginning/head of the buffer chain)
 21271                              <1> 
 21272                              <1> 	; if we are here, buffer has been written to disk successfully 
 21273                              <1> 	; (otherwise cpu would jump to 'error' address)
 21274 000054AC 58                  <1> 	pop	eax ; *  ; number of free blocks 
 21275                              <1> free_5:
 21276                              <1> 	; eax = number of free blocks 
 21277                              <1> 	;
 21278                              <1> 	; set superblock modified flag
 21279 000054AD BA[E76F0000]        <1> 	mov	edx, smod
 21280 000054B2 BB[687D0000]        <1> 	mov	ebx, systm
 21281 000054B7 F605[D56F0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 21282 000054BE 7406                <1> 	jz	short free_6 ; no, root device
 21283                              <1> 	; yes, mounted device
 21284 000054C0 BB[707F0000]        <1> 	mov	ebx, mount
 21285                              <1> 	;mov	edx, mmod
 21286 000054C5 42                  <1> 	inc	edx ; edx = offset mmod
 21287                              <1> free_6: 
 21288 000054C6 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax 
 21289                              <1> 
 21290 000054C9 A1[78810000]        <1> 	mov	eax, [free_map_sector] ; logical sector number
 21291 000054CE 3B433C              <1> 	cmp	eax, [ebx+SB.FirstFreeBlk]
 21292 000054D1 7303                <1> 	jnb	short free_7
 21293 000054D3 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
 21294                              <1> free_7:
 21295 000054D6 FE02                <1> 	inc	byte [edx] ; superblock modified !
 21296 000054D8 C3                  <1> 	retn
 21297                              <1> 	
 21298                              <1> iget:
 21299                              <1> 	; 30/11/2021
 21300                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 21301                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21302                              <1> 	; 07/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 21303                              <1> 	;
 21304                              <1> 	; get a new i-node whose i-number in r1 and whose device is in cdev
 21305                              <1> 	;
 21306                              <1> 	; ('iget' returns current i-number in r1, if input value of r1 is 0)
 21307                              <1> 	; 
 21308                              <1> 	; INPUTS ->
 21309                              <1> 	;    ii - current i-number, rootdir
 21310                              <1> 	;    cdev - new i-node device
 21311                              <1> 	;    idev - current i-node device
 21312                              <1> 	;    imod - current i-node modified flag
 21313                              <1> 	;    mnti - cross device file i-number
 21314                              <1> 	;    r1 - i-numbe rof new i-node
 21315                              <1> 	;    mntd - mountable device number		
 21316                              <1> 	; 	 
 21317                              <1> 	; OUTPUTS ->
 21318                              <1> 	;    cdev, idev, imod, ii, r1
 21319                              <1> 	;
 21320                              <1> 	; ((AX = R1)) input/output
 21321                              <1> 	;
 21322                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 21323                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 21324                              <1> 
 21325                              <1> 	; 22/11/2021
 21326                              <1> 	;;mov	dl, [cdev] ; 18/07/2013
 21327                              <1> 	;;mov	dh, [idev] ; 07/08/2013
 21328                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
 21329                              <1> 	;mov	dh, [cdev]
 21330                              <1> 	;mov	dl, [idev]
 21331 000054D9 668B15[D46F0000]    <1> 	mov	dx, [idev] ; [idev] in dl, [cdev] in dh
 21332                              <1> 	;
 21333                              <1> 	; 22/11/2021
 21334 000054E0 25FFFF0000          <1> 	and	eax, 0FFFFh
 21335 000054E5 3B05[D06F0000]      <1> 	cmp 	eax, [ii]
 21336                              <1> 		; cmp r1,ii / r1 = i-number of current file
 21337 000054EB 7504                <1> 	jne 	short iget_1
 21338                              <1> 		; bne 1f
 21339 000054ED 38F2                <1> 	cmp	dl, dh
 21340                              <1> 		; cmp idev,cdev
 21341                              <1> 			  ; / is device number of i-node = current device
 21342 000054EF 746C                <1>         je	short iget_5
 21343                              <1> 	;	; beq 2f
 21344                              <1> 	; 14/08/2021
 21345                              <1> iget_1: ; 1:
 21346 000054F1 30DB                <1> 	xor	bl, bl
 21347 000054F3 381D[E66F0000]      <1> 	cmp	[imod], bl ; 0	
 21348                              <1> 		; tstb imod / has i-node of current file
 21349                              <1> 			  ; / been modified i.e., imod set
 21350 000054F9 7628                <1> 	jna	short iget_2
 21351                              <1> 		; beq 1f
 21352 000054FB 881D[E66F0000]      <1> 	mov	[imod], bl ; 0
 21353                              <1> 		;  clrb	imod / if it has, 
 21354                              <1> 			   ; / we must write the new i-node out on disk
 21355                              <1> 	; 22/11/2021 (32 bit push-pop)
 21356 00005501 50                  <1> 	push	eax ; *
 21357                              <1> 		; mov r1,-(sp)
 21358 00005502 52                  <1> 	push	edx ; **
 21359                              <1> 		; mov cdev,-(sp)
 21360 00005503 A1[D06F0000]        <1> 	mov	eax, [ii]
 21361                              <1> 		; mov ii,r1
 21362                              <1> 	;mov	dh, [idev]
 21363 00005508 8835[D56F0000]      <1> 	mov	[cdev], dh
 21364                              <1> 		; mov idev,cdev
 21365 0000550E FEC3                <1> 	inc	bl ; 1
 21366                              <1> 	; 31/07/2013
 21367 00005510 881D[2C710000]      <1> 	mov     [rw], bl ; 1 == write 
 21368                              <1> 	;;28/07/2013 rw -> u.rw
 21369                              <1>         ;;mov   [u.rw], bl ; 1 == write
 21370 00005516 E843000000          <1> 	call	icalc
 21371                              <1> 		; jsr r0,icalc; 1
 21372 0000551B 5A                  <1> 	pop	edx ; **
 21373 0000551C 8835[D56F0000]      <1> 	mov	[cdev], dh ; 22/11/2021
 21374                              <1> 		; mov (sp)+,cdev
 21375 00005522 58                  <1> 	pop	eax ; *
 21376                              <1> 		; mov (sp)+,r1
 21377                              <1> iget_2: ; 1:
 21378                              <1> 	;and	ax, ax
 21379 00005523 21C0                <1> 	and	eax, eax ; 22/11/2021 (32 bit inode number)
 21380                              <1> 		; tst r1 / is new i-number non zero
 21381 00005525 7431                <1> 	jz	short iget_4 ; 2f
 21382                              <1> 		; beq 2f / branch if r1=0
 21383                              <1> 
 21384                              <1> 	;mov 	dh, [cdev]
 21385 00005527 08F6                <1> 	or	dh, dh ; 22/11/2021
 21386                              <1> 		; tst cdev / is the current device number non zero
 21387                              <1> 			 ; / (i.e., device =/ drum)
 21388 00005529 7515                <1> 	jnz	short iget_3 ;  1f
 21389                              <1> 		; bne 1f / branch 1f cdev =/ 0  ;; (cdev != 0)
 21390                              <1> 	; 22/11/2021
 21391 0000552B 3B05[E06F0000]      <1> 	cmp	eax, [mnti]
 21392                              <1> 	;cmp	ax, [mnti]			
 21393                              <1> 		; cmp r1,mnti / mnti is the i-number of the cross device
 21394                              <1> 			    ; / file (root directory of mounted device)
 21395 00005531 750D                <1> 	jne	short iget_3 ; 1f
 21396                              <1> 		; bne 1f
 21397                              <1>         ;mov    bl, [mntd]
 21398 00005533 FEC6                <1> 	inc	dh ; mov dh, 1 ; 22/11/2021
 21399 00005535 8835[D56F0000]      <1>         mov	[cdev], dh ; 22/11/2021
 21400                              <1> 		; mov mntd,cdev / make mounted device the current device
 21401                              <1> 	; 22/11/2021
 21402 0000553B A1[DC6F0000]        <1> 	mov	eax, [rootdir] ; rootdir = 1 (for runix v2 file system)
 21403                              <1> 	;mov	ax, [rootdir]
 21404                              <1> 		; mov rootdir,r1
 21405                              <1> iget_3: ; 1:
 21406                              <1> 	; 22/11/2021
 21407 00005540 A3[D06F0000]        <1> 	mov	[ii], eax ; 32 bit inode number
 21408                              <1> 	;mov	[ii], ax
 21409                              <1> 		; mov r1,ii
 21410                              <1> 	; 30/11/2021
 21411 00005545 8835[D46F0000]      <1> 	mov	[idev], dh ; cdev 
 21412                              <1> 	;mov	[idev], dl ; cdev
 21413                              <1> 		; mov cdev,idev
 21414 0000554B 30DB                <1> 	xor	bl, bl
 21415                              <1>         ; 31/07/2013
 21416 0000554D 881D[2C710000]      <1> 	mov     [rw], bl ; 0 == read 
 21417                              <1> 	;;28/07/2013 rw -> u.rw       
 21418                              <1>         ;;mov   [u.rw], bl ; 0 = read
 21419 00005553 E806000000          <1> 	call	icalc
 21420                              <1> 		; jsr r0,icalc; 0 / read in i-node ii
 21421                              <1> iget_4: ; 2:
 21422                              <1> 	; 22/11/2021
 21423 00005558 A1[D06F0000]        <1> 	mov	eax, [ii]
 21424                              <1> 	;mov	ax, [ii]
 21425                              <1> 		; mov ii,r1
 21426                              <1> iget_5:
 21427 0000555D C3                  <1> 	retn
 21428                              <1> 		; rts r0
 21429                              <1> 
 21430                              <1> icalc:
 21431                              <1> 	; 28/11/2021
 21432                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification 
 21433                              <1> 	; 02/07/2015
 21434                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21435                              <1> 	; 07/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 21436                              <1> 	;
 21437                              <1> 	; calculate physical block number from i-number then
 21438                              <1> 	; read or write that block
 21439                              <1> 	;
 21440                              <1> 	; 'icalc' is called from 'iget'
 21441                              <1> 	;
 21442                              <1> 	; for original unix v1:
 21443                              <1> 	; / i-node i is located in block (i+31.)/16. and begins 32.*
 21444                              <1>        	; / (i+31.) mod 16. bytes from its start
 21445                              <1> 	;
 21446                              <1> 	; for retro unix 8086 v1:
 21447                              <1> 	;  i-node is located in block (i+47)/16 and
 21448                              <1> 	;  begins 32*(i+47) mod 16 bytes from its start
 21449                              <1> 	;
 21450                              <1> 	; INPUTS ->
 21451                              <1> 	;    r1 - i-number of i-node
 21452                              <1> 	; 	 
 21453                              <1> 	; OUTPUTS ->
 21454                              <1> 	;    inode r/w
 21455                              <1> 	;
 21456                              <1> 	; ((AX = R1)) input
 21457                              <1> 	;
 21458                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 21459                              <1>         ;  ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))  
 21460                              <1> 	;
 21461                              <1> 
 21462                              <1> 	; 28/11/2021
 21463                              <1> 	;cmp	byte [idev], 0 ; [cdev] = [idev]
 21464 0000555E 803D[D56F0000]00    <1> 	cmp	byte [cdev], 0
 21465 00005565 7607                <1> 	jna	short icalc_0r
 21466 00005567 BD[707F0000]        <1> 	mov	ebp, mount  ; mounted file system's superblock 
 21467 0000556C EB05                <1> 	jmp	short icalc_0m
 21468                              <1> icalc_0r:
 21469                              <1> 	; 28/11/2021
 21470 0000556E BD[687D0000]        <1> 	mov	ebp, systm  ; root file system's superblock 
 21471                              <1> icalc_0m:
 21472                              <1> 	; 22/11/2021
 21473                              <1> 	;mov	edx, eax
 21474 00005573 8B15[D06F0000]      <1> 	mov	edx, [ii] ; 32 bit inode number
 21475 00005579 8B4528              <1> 	mov	eax, [ebp+SB.InodeTblAddr] ; inode table base address
 21476                              <1> 	;
 21477 0000557C 4A                  <1> 	dec	edx ; 0 based inode number 
 21478                              <1> 		    ; (inode index in inode table)
 21479 0000557D 52                  <1> 	push	edx ; *
 21480 0000557E C1EA03              <1> 	shr	edx, 3
 21481 00005581 7402                <1> 	jz	short icalc_0t ; 0 for inodes 1 to 8
 21482 00005583 01D0                <1> 	add	eax, edx
 21483                              <1> icalc_0t:
 21484                              <1> 	;add	eax, [ebp+SB.BootSectAddr]
 21485 00005585 E8DB0A0000          <1> 	call	dskrd
 21486                              <1> 		; jsr r0,dskrd / read in block containing i-node i.
 21487                              <1> 	; 31/07/2013
 21488 0000558A 803D[2C710000]00    <1>         cmp     byte [rw], 0 ; Retro Unix 8086 v1 feature !
 21489                              <1> 	;; 28/07/2013 rw -> u.rw
 21490                              <1>         ;;cmp	byte [u.rw], 0 ; Retro Unix 8086 v1 feature !
 21491                              <1> 		; tst (r0)
 21492 00005591 7605                <1> 	jna	short icalc_1
 21493                              <1> 		; beq 1f / branch to wslot when argument
 21494                              <1> 		       ; / in icalc call = 1
 21495                              <1> 	; eAX = r1  = block number
 21496 00005593 E82D0B0000          <1> 	call	wslot
 21497                              <1> 		; jsr r0,wslot / set up data buffer for write
 21498                              <1> 			     ; / (will be same buffer as dskrd got)
 21499                              <1> 	; EBX = r5 points to first word in data area for this block
 21500                              <1> icalc_1: ; 1:
 21501 00005598 5A                  <1> 	pop	edx ; *
 21502                              <1> 	; 22/11/2021
 21503 00005599 83E207              <1> 	and 	edx, 07h ; 8 inodes per inode table sector
 21504 0000559C C1E206              <1> 	shl 	edx, 6 ; * 64 (inode size)
 21505                              <1> 	; edx = 64 * (mod(inodenumber-1)/8)
 21506 0000559F 89DE                <1> 	mov	esi, ebx  ; ebx points 1st word of the buffer
 21507 000055A1 01D6                <1> 	add	esi, edx  ; edx is inode offset in the buffer
 21508                              <1>           	; eSI (r5) points to first word in i-node i.	
 21509                              <1> 		; mov (sp)+,mq / calculate offset in data buffer; 
 21510                              <1> 			     ; / 32.*(i+31.)mod16
 21511                              <1> 		; mov $5,lsh / for i-node i.
 21512                              <1> 		; add mq,r5 / r5 points to first word in i-node i.
 21513 000055A3 BF[906C0000]        <1> 	mov	edi, inode
 21514                              <1> 		; mov $inode,r1 / inode is address of first word 
 21515                              <1> 			      ; / of current i-node
 21516                              <1> 	;mov 	ecx, 8 ; 02/07/2015 (32 bit modification)
 21517                              <1> 	;	; mov $16.,r3
 21518                              <1> 	; 28/11/2021
 21519 000055A8 29C9                <1> 	sub	ecx, ecx
 21520 000055AA B110                <1> 	mov	cl, 16 ; Retro UNIX 386 v2 inode size = 64 bytes
 21521                              <1> 	; 31/07/2013
 21522 000055AC 382D[2C710000]      <1>   	cmp     [rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 21523                              <1>        ;;28/07/2013 rw -> u.rw                 
 21524                              <1>        ;;cmp    [u.rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 21525                              <1> 		; tst (r0)+ / branch to 2f when argument in icalc call = 0
 21526 000055B2 7609                <1> 	jna	short icalc_3
 21527                              <1> 		; beq 2f / r0 now contains proper return address 
 21528                              <1> 		       ; / for rts r0
 21529                              <1> icalc_2: ; 1:
 21530 000055B4 87F7                <1> 	xchg 	esi, edi
 21531                              <1> 	; overwrite old i-node (in buffer to be written)
 21532 000055B6 F3A5                <1> 	rep 	movsd
 21533                              <1> 		; mov (r1)+,(r5)+ / over write old i-node
 21534                              <1> 		; dec r3
 21535                              <1> 		; bgt 1b
 21536                              <1> 	;call	dskwr
 21537                              <1> 	;	; jsr r0,dskwr / write inode out on device
 21538                              <1> 	;retn
 21539                              <1> 	;	; rts r0
 21540                              <1> 	; 28/11/2021
 21541 000055B8 E9240B0000          <1> 	jmp	dskwr
 21542                              <1> icalc_3: ; 2:
 21543                              <1> 	; copy new i-node into inode area of (core) memory
 21544 000055BD F3A5                <1> 	rep 	movsd
 21545                              <1> 		; mov (r5)+,(r1)+ / read new i-node into 
 21546                              <1> 		                ; / "inode" area of core
 21547                              <1> 		; dec r3
 21548                              <1> 		; bgt 2b
 21549 000055BF C3                  <1> 	retn
 21550                              <1> 		; rts r0
 21551                              <1> 
 21552                              <1> access:
 21553                              <1> 	; 28/11/2021
 21554                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 21555                              <1> 	; 31/10/2021 - temporary (simplified code)
 21556                              <1> 	; 14/06/2021
 21557                              <1> 	; 02/05/2021
 21558                              <1> 	; 27/03/2021
 21559                              <1> 	; 26/03/2021
 21560                              <1> 	; 25/03/2021
 21561                              <1> 	; 23/03/2021 (Retro UNIX 386 v2 - Beginning)
 21562                              <1> 	;	((ref: unix v7 source - fio.c))
 21563                              <1> 	; ref: INODE STRUCTURE of Retro UNIX v2 file system
 21564                              <1> 	;	07/02/2020, 'RETRO UNIX v2 Inodes.pdf'
 21565                              <1> 	;	 
 21566                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21567                              <1> 	; 24/04/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 21568                              <1> 	;
 21569                              <1> 	; check whether user is owner of file or user has read or write
 21570                              <1> 	; permission (based on i.flgs).
 21571                              <1> 	;
 21572                              <1> 	; INPUTS ->
 21573                              <1> 	;    r1 - i-number of file
 21574                              <1> 	;    u.uid
 21575                              <1> 	; arg0 -> (owner flag mask)	 		
 21576                              <1> 	;     Retro UNIX 8086 v1 feature -> owner flag mask in DL (DX) 	 
 21577                              <1> 	; OUTPUTS ->
 21578                              <1> 	;    inode (or jump to error)
 21579                              <1> 	;
 21580                              <1> 	; ((AX = R1)) input/output
 21581                              <1> 	;
 21582                              <1> 	;  ((Modified registers: eCX, eBX, eDX, eSI, eDI, eBP))
 21583                              <1> 
 21584                              <1> 	; 26/03/2021
 21585                              <1> 	; INPUT:
 21586                              <1> 	;	eax = inode number (ax)
 21587                              <1> 	;	 dx = mode (IEXEC, IREAD or IWRITE) 
 21588                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
 21589                              <1> 	;	
 21590                              <1> 	; OUTPUT:
 21591                              <1> 	;	inode (or jump to error)
 21592                              <1> 	;	eax (ax) = [ii] = inode number
 21593                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
 21594                              <1> 	;
 21595                              <1> 	; Modified registers: (eax), ebx, ecx, edx, esi, edi, ebp
 21596                              <1> 	;
 21597                              <1> 	; IREAD	 equ 100h ; read permission flag, owner
 21598                              <1> 	; IWRITE equ 80h  ; write permission flag, owner
 21599                              <1> 	; IEXEC	 equ 40h  ; execute permission flag, owner	 
 21600                              <1> 		
 21601                              <1> 	; 23/03/2021
 21602 000055C0 52                  <1> 	push	edx ; save flag (DX)
 21603                              <1> 	;push	dx  ; save flag (DL)
 21604 000055C1 E813FFFFFF          <1> 	call	iget
 21605                              <1> 		; jsr r0,iget / read in i-node for current directory
 21606                              <1> 			    ; / (i-number passed in r1)
 21607                              <1> 	;;mov	cl, [i.flgs]
 21608                              <1> 	;;	; mov i.flgs,r2
 21609                              <1> 	; 23/03/2021
 21610                              <1> 	;mov	cx, [i.iflgs]	
 21611                              <1> 
 21612                              <1> 	;;pop	dx  ; restore flag (DL)
 21613                              <1> 	; 23/03/2021
 21614 000055C6 5A                  <1> 	pop	edx ; restore flag (DX)
 21615                              <1> 
 21616                              <1> 	; 28/11/2021 (iget will not return here if there is an error)
 21617                              <1> 	; 31/10/2021
 21618                              <1> 	;jc	short access_5
 21619                              <1> 
 21620                              <1> 	; 31/10/2021
 21621                              <1> 	; Note: If eax input is same with [mnti], 'iget' will change
 21622                              <1> 	; [cdev] to 1 and eax will be 1 (root dir of mounted fs) 
 21623                              <1> 
 21624                              <1> 	; 27/03/2021
 21625                              <1> 	; 23/03/2021
 21626                              <1> 	; (check if it is write permission flag)
 21627 000055C7 6681FA8000          <1> 	cmp	dx, 80h ; IWRITE
 21628 000055CC 7755                <1> 	ja	short access_r	; IREAD = 100h (owner)
 21629 000055CE 7222                <1> 	jb	short access_x	; IEXEC = 40h (owner)
 21630                              <1> 	; IWRITE (80h)
 21631                              <1> access_w:
 21632                              <1> 	; 23/03/2021
 21633                              <1> 	; ((ref: Retro UNIX 386 v2, 'ux.s', 'ldrv' structure))
 21634                              <1> 	;mov	bl, [idev]
 21635                              <1> 	;call	getfs
 21636                              <1>  	;movzx	ebx, byte [idev]  ; logical drive number
 21637                              <1> 	;shl	bx, 6 ; * 64	  ; of current inode	
 21638                              <1> 	;add	ebx, ldrvtable	
 21639                              <1> 	;;test	byte [ebx+ldrv.pflags], 01h ; read only fs flag
 21640                              <1> 	;;jz	short access_0
 21641                              <1> 	;; 14/06/2021
 21642                              <1> 	; 14/06/2021
 21643                              <1> 	; check block device (fs) if it is read only fs or not ? 
 21644                              <1> 	;mov	edi, [ebx+ldrv.superblk]
 21645                              <1> 	;test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
 21646                              <1> 	;jz	short access_0
 21647                              <1> 	; 31/10/2021
 21648 000055D0 803D[D56F0000]01    <1> 	cmp	byte [cdev], 1
 21649 000055D7 7207                <1> 	jb	short access_7 ; [cdev] = 0
 21650                              <1> 	; [cdev] = 1
 21651                              <1> 	; 28/11/2021
 21652 000055D9 BF[707F0000]        <1> 	mov	edi, mount ; mounted file system's superblock buffer
 21653 000055DE EB05                <1> 	jmp	short access_8
 21654                              <1> access_7:
 21655                              <1> 	; 28/11/2021
 21656 000055E0 BF[687D0000]        <1> 	mov	edi, systm ; root file system's superblock buffer
 21657                              <1> access_8:
 21658 000055E5 F6476A01            <1> 	test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
 21659 000055E9 7438                <1> 	jz	short access_0
 21660                              <1> 
 21661                              <1> 	; 23/03/2021
 21662                              <1> 	;mov	dword [u.error], ERR_READ_ONLY_FS
 21663                              <1> 	;		; 'read only file system !' error
 21664                              <1> 	;jmp	error
 21665                              <1> 
 21666                              <1> 	; 31/10/2021
 21667 000055EB B81E000000          <1> 	mov	eax, ERR_READ_ONLY_FS
 21668                              <1> 			; 'read only file system !' error
 21669                              <1> 	; 27/03/2021
 21670 000055F0 EB27                <1> 	jmp	short access_5
 21671                              <1> 
 21672                              <1> 	; check block device (fs) if it is read only fs or not ? 
 21673                              <1> 
 21674                              <1> 	;mov	dh, [u.uid]
 21675                              <1> 	;cmp	dh, [i.uid]
 21676                              <1> 	;	; cmpb i.uid,u.uid / is user same as owner of file
 21677                              <1> 	;jne	short access_1
 21678                              <1> 		; bne 1f / no, then branch
 21679                              <1> access_x:
 21680                              <1> 	; IEXEC (40h)
 21681                              <1> 	; 27/03/2021
 21682 000055F2 668B1D[906C0000]    <1> 	mov	bx, [i.flgs]
 21683 000055F9 F6C780              <1> 	test	bh, 80h ; regular file ?
 21684 000055FC 7416                <1> 	jz	short access_4 ; not executable file !
 21685 000055FE F6C740              <1> 	test	bh, 40h	; directory ?
 21686 00005601 7511                <1> 	jnz	short access_4 ; not executable file !
 21687 00005603 668B0D[4A700000]    <1> 	mov	cx, [u.uid]
 21688 0000560A 6609C9              <1> 	or	cx, cx
 21689 0000560D 7520                <1> 	jnz	short access_3 ; (restricted user)
 21690                              <1> 	; (super user)
 21691                              <1> 	;test	[i.flgs], dl ; execute permission for owner
 21692                              <1> 	;test	byte [i.flgs], 49h ; for owner, group, others
 21693 0000560F F6C349              <1> 	test	bl, 49h ; exec perm for owner, group, others
 21694 00005612 7557                <1> 	jnz	short access_2
 21695                              <1> access_4:
 21696                              <1> 	; 31/10/2021
 21697 00005614 B816000000          <1> 	mov	eax, ERR_NOT_EXECUTABLE
 21698                              <1> 			; 'not executable file !' error
 21699                              <1> 	; 26/03/2021
 21700                              <1> ;;sysexec_not_exf:
 21701                              <1> ;	mov	dword [u.error], ERR_NOT_EXECUTABLE
 21702                              <1> ;			; 'not executable file !' error
 21703                              <1> ;access_5:
 21704                              <1> ;	jmp	error
 21705                              <1> 	
 21706                              <1> 	; 31/10/2021
 21707                              <1> access_5:
 21708 00005619 A3[6A700000]        <1> 	mov	[u.error], eax
 21709 0000561E E94FE6FFFF          <1> 	jmp	error
 21710                              <1> 
 21711                              <1> access_r:
 21712                              <1> 	; 27/03/2021
 21713                              <1> access_0:
 21714                              <1> 	; 23/03/2021
 21715 00005623 668B0D[4A700000]    <1> 	mov	cx, [u.uid]
 21716 0000562A 6609C9              <1> 	or	cx, cx ; 0 ; root ?
 21717 0000562D 743C                <1> 	jz	short access_2 ; yes
 21718                              <1> access_3:
 21719                              <1> 	; owner ?
 21720 0000562F 8A1D[966C0000]      <1> 	mov	bl, [i.gid]
 21721 00005635 663B0D[946C0000]    <1> 	cmp	cx, [i.uid]
 21722                              <1> 	;je	short access_1
 21723                              <1> 	; 02/05/2021
 21724 0000563C 750E                <1> 	jne	short access_6
 21725                              <1> 	; check owner's group number/ID
 21726 0000563E 3A1D[4E700000]      <1> 	cmp	bl, [u.gid] ; same group number/ID ?
 21727 00005644 7415                <1> 	je	short access_1 ; yes, owner
 21728                              <1> 	; one of others
 21729 00005646 66C1EA06            <1> 	shr	dx, 6
 21730 0000564A EB0F                <1> 	jmp	short access_1 ; others
 21731                              <1> access_6:
 21732                              <1> 	;shr	cl, 2
 21733                              <1> 	;	; asrb r2 / shift owner read write bits into non owner
 21734                              <1> 	;	;       ; / read/write bits
 21735                              <1> 	;	; asrb r2
 21736                              <1> 
 21737                              <1> 	; 23/03/2021
 21738                              <1> 	; same group ?
 21739 0000564C 66C1EA03            <1> 	shr	dx, 3
 21740                              <1> 	;mov	cl, [u.gid]
 21741                              <1> 	;cmp	cl, [i.gid]
 21742                              <1> 	;je	short access_1
 21743                              <1> 	; 02/05/2021
 21744 00005650 3A1D[4E700000]      <1> 	cmp	bl, [u.gid]
 21745 00005656 7403                <1> 	je	short access_1 ; same group, different owner
 21746                              <1> 
 21747                              <1> 	; others
 21748                              <1> 	;shr	dx, 3
 21749 00005658 C0EA03              <1> 	shr	dl, 3
 21750                              <1> 	;jmp	short access_1	
 21751                              <1> 
 21752                              <1> ;access_1: ; 1:
 21753                              <1> 	;and	cl, dl
 21754                              <1> 	;	; bit r2,(r0)+ / test read-write flags against argument
 21755                              <1> 	;		     ; / in access call
 21756                              <1> 	;jnz	short access_2
 21757                              <1> 	;	; bne 1f
 21758                              <1> 	
 21759                              <1> 	;or	dh, dh	; super user (root) ?
 21760                              <1> 	;	; tstb u.uid
 21761                              <1> 	;jz	short access_2 ; yes, super user
 21762                              <1> 	;;jnz	error
 21763                              <1> 	;	; beq 1f
 21764                              <1> 	;	; jmp error
 21765                              <1> 	
 21766                              <1> 	;mov	dword [u.error], ERR_FILE_ACCESS 
 21767                              <1> 	;		; 'permission denied !' error
 21768                              <1> 	;jmp	error
 21769                              <1> 
 21770                              <1> access_1:
 21771                              <1> 	; 23/03/2021
 21772 0000565B 668515[906C0000]    <1> 	test	dx, [i.flgs]
 21773 00005662 7507                <1> 	jnz	short access_2
 21774                              <1> 
 21775                              <1> 	;; r/w permission error
 21776                              <1> 	;mov	dword [u.error], ERR_FILE_ACCESS 
 21777                              <1> 	;		; 'permission denied !' error
 21778                              <1> 	;;jmp	error
 21779                              <1> 
 21780                              <1> 	; 31/10/2021
 21781 00005664 B80B000000          <1> 	mov	eax, ERR_FILE_ACCESS 
 21782                              <1> 			; 'permission denied !' error
 21783                              <1> 	; 27/03/2021
 21784 00005669 EBAE                <1> 	jmp	short access_5
 21785                              <1> 
 21786                              <1> access_2: ; 1:
 21787                              <1> 	;; DL = flags
 21788                              <1> 	;retn
 21789                              <1> 	;	; rts r0
 21790                              <1> 	; 27/03/2021
 21791                              <1> 	; DX = flag (100h-20h-04h or 80h-10h-02h or 40h-08h-01h)
 21792 0000566B C3                  <1> 	retn
 21793                              <1> 
 21794                              <1> setimod:
 21795                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21796                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 21797                              <1> 	;
 21798                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
 21799                              <1> 	; the inode has been modified. Also puts the time of modification
 21800                              <1> 	; into the inode.
 21801                              <1> 	;
 21802                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
 21803                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
 21804                              <1> 	;
 21805                              <1> 	
 21806                              <1> 	; push 	edx
 21807 0000566C 50                  <1> 	push	eax
 21808                              <1> 
 21809 0000566D C605[E66F0000]01    <1> 	mov 	byte [imod], 1
 21810                              <1> 		; movb $1,imod / set current i-node modified bytes
 21811                              <1> 	; Erdogan Tan 14-7-2012
 21812 00005674 E835E1FFFF          <1> 	call 	epoch
 21813                              <1> 		 ; mov s.time,i.mtim 
 21814                              <1> 			    ; / put present time into file modified time
 21815                              <1> 		 ; mov s.time+2,i.mtim+2
 21816                              <1> 
 21817 00005679 A3[C86C0000]        <1> 	mov 	[i.mtim], eax
 21818                              <1> 	
 21819                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
 21820                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
 21821 0000567E 833D[CC6C0000]00    <1> 	cmp	dword [i.ctim], 0
 21822 00005685 7505                <1> 	jnz	short setimod_ok
 21823                              <1> 
 21824 00005687 A3[CC6C0000]        <1> 	mov 	[i.ctim], eax
 21825                              <1> 
 21826                              <1> setimod_ok: ; 31/07/2013
 21827 0000568C 58                  <1> 	pop	eax
 21828                              <1> 	;pop	edx
 21829                              <1> 	
 21830 0000568D C3                  <1> 	retn
 21831                              <1> 		; rts r0
 21832                              <1> 
 21833                              <1> itrunc:
 21834                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21835                              <1> 	; 23/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 21836                              <1> 	;
 21837                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
 21838                              <1> 	;  to zero length.
 21839                              <1> 	;
 21840                              <1> 	; INPUTS ->
 21841                              <1> 	;    r1 - i-number of i-node
 21842                              <1> 	;    i.dskp - pointer to contents or indirect block in an i-node
 21843                              <1> 	;    i.flgs - large file flag		
 21844                              <1> 	;    i.size - size of file	
 21845                              <1> 	; 	 
 21846                              <1> 	; OUTPUTS ->
 21847                              <1> 	;    i.flgs - large file flag is cleared
 21848                              <1> 	;    i.size - set to 0	
 21849                              <1> 	;    i.dskp .. i.dskp+16 - entire list is cleared
 21850                              <1> 	;    setimod - set to indicate i-node has been modified
 21851                              <1> 	;    r1 - i-number of i-node  					
 21852                              <1> 	;
 21853                              <1> 	; ((AX = R1)) input/output
 21854                              <1> 	;
 21855                              <1> 	;  (Retro UNIX Prototype : 01/12/2012 - 10/03/2013, UNIXCOPY.ASM)
 21856                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 21857                              <1> 
 21858 0000568E E846FEFFFF          <1> 	call	iget
 21859                              <1> 		; jsr r0,iget
 21860 00005693 BE[9C6C0000]        <1> 	mov	esi, i.dskp
 21861                              <1> 		; mov $i.dskp,r2 / address of block pointers in r2
 21862 00005698 31C0                <1> 	xor	eax, eax
 21863                              <1> itrunc_1: ; 1:
 21864 0000569A 66AD                <1> 	lodsw
 21865                              <1> 		; mov (r2)+,r1 / move physical block number into r1
 21866 0000569C 6609C0              <1> 	or 	ax, ax
 21867 0000569F 743B                <1> 	jz	short itrunc_5
 21868                              <1> 		; beq 5f
 21869 000056A1 56                  <1> 	push	esi
 21870                              <1> 		; mov r2,-(sp)
 21871 000056A2 66F705[906C0000]00- <1> 	test    word [i.flgs], 1000h    
 21872 000056AA 10                  <1>
 21873                              <1> 		; bit $10000,i.flgs / test large file bit?
 21874 000056AB 7429                <1> 	jz	short itrunc_4
 21875                              <1> 		; beq 4f / if clear, branch
 21876 000056AD 50                  <1> 	push	eax
 21877                              <1> 		; mov r1,-(sp) / save block number of indirect block
 21878 000056AE E8B2090000          <1> 	call	dskrd
 21879                              <1> 		; jsr r0,dskrd / read in block, 1st data word 
 21880                              <1> 			     ; / pointed to by r5
 21881                              <1> 	; eBX = r5 = Buffer data address (the 1st word)
 21882 000056B3 B900010000          <1> 	mov	ecx, 256
 21883                              <1> 		; mov $256.,r3 / move word count into r3
 21884 000056B8 89DE                <1> 	mov	esi, ebx
 21885                              <1> itrunc_2: ; 2:
 21886 000056BA 66AD                <1> 	lodsw
 21887                              <1> 		; mov (r5)+,r1 / put 1st data word in r1; 
 21888                              <1> 			     ; / physical block number
 21889 000056BC 6621C0              <1> 	and	ax, ax
 21890 000056BF 7409                <1> 	jz	short itrunc_3
 21891                              <1> 		; beq 3f / branch if zero
 21892                              <1> 	;push	ecx
 21893 000056C1 6651                <1> 	push	cx
 21894                              <1> 		; mov r3,-(sp) / save r3, r5 on stack
 21895                              <1> 	;push	esi
 21896                              <1> 		; mov r5,-(sp)
 21897 000056C3 E872FDFFFF          <1> 	call	free
 21898                              <1> 		; jsr r0,free / free block in free storage map
 21899                              <1> 	;pop	esi
 21900                              <1> 		; mov(sp)+,r5
 21901 000056C8 6659                <1> 	pop	cx
 21902                              <1> 	;pop	ecx
 21903                              <1> 		; mov (sp)+,r3
 21904                              <1> itrunc_3: ; 3:
 21905 000056CA E2EE                <1> 	loop	itrunc_2
 21906                              <1> 		; dec r3 / decrement word count
 21907                              <1> 		; bgt 2b / branch if positive
 21908 000056CC 58                  <1> 	pop	eax
 21909                              <1> 		; mov (sp)+,r1 / put physical block number of 
 21910                              <1> 			     ; / indirect block
 21911                              <1> 	; 01/08/2013
 21912 000056CD 668125[906C0000]FF- <1>         and     word [i.flgs], 0EFFFh ; 1110111111111111b
 21913 000056D5 EF                  <1>
 21914                              <1> itrunc_4: ; 4:
 21915 000056D6 E85FFDFFFF          <1> 	call	free
 21916                              <1> 		; jsr r0,free / free indirect block
 21917 000056DB 5E                  <1> 	pop	esi
 21918                              <1> 		; mov (sp)+,r2
 21919                              <1> itrunc_5: ; 5:
 21920 000056DC 81FE[AC6C0000]      <1> 	cmp	esi, i.dskp+16
 21921                              <1> 		; cmp r2,$i.dskp+16.
 21922 000056E2 72B6                <1> 	jb	short itrunc_1	
 21923                              <1> 		; bne 1b / branch until all i.dskp entries check
 21924                              <1> 	; 01/08/2013
 21925                              <1> 	;and     word [i.flgs], 0EFFFh ; 1110111111111111b
 21926                              <1> 		; bic $10000,i.flgs / clear large file bit
 21927 000056E4 BF[9C6C0000]        <1> 	mov	edi, i.dskp
 21928 000056E9 66B90800            <1> 	mov	cx, 8
 21929 000056ED 6631C0              <1> 	xor 	ax, ax
 21930 000056F0 66A3[986C0000]      <1> 	mov	[i.size], ax ; 0
 21931                              <1> 		; clr i.size / zero file size
 21932 000056F6 F366AB              <1> 	rep	stosw
 21933                              <1> 		; jsr r0,copyz; i.dskp; i.dskp+16. 
 21934                              <1> 			   ; / zero block pointers
 21935 000056F9 E86EFFFFFF          <1> 	call	setimod
 21936                              <1> 		; jsr r0,setimod / set i-node modified flag
 21937 000056FE 66A1[D06F0000]      <1> 	mov	ax, [ii]
 21938                              <1> 		; mov ii,r1
 21939 00005704 C3                  <1> 	retn
 21940                              <1> 		; rts r0
 21941                              <1> 
 21942                              <1> imap:
 21943                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21944                              <1> 	; 26/04/2013 (Retro UNIX 8086 v1)
 21945                              <1> 	;
 21946                              <1> 	; 'imap' finds the byte in core (superblock) containing
 21947                              <1> 	; allocation bit for an i-node whose number in r1.
 21948                              <1> 	;
 21949                              <1> 	; INPUTS ->
 21950                              <1> 	;    r1 - contains an i-number
 21951                              <1> 	;    fsp - start of table containing open files
 21952                              <1> 	;
 21953                              <1> 	; OUTPUTS ->
 21954                              <1> 	;    r2 - byte address of byte with the allocation bit
 21955                              <1> 	;    mq - a mask to locate the bit position.	
 21956                              <1> 	;	  (a 1 is in calculated bit posisiton)
 21957                              <1> 	;
 21958                              <1> 	; ((AX = R1)) input/output
 21959                              <1> 	; ((DL/DX = MQ)) output
 21960                              <1> 	; ((BX = R2)) output
 21961                              <1> 	;
 21962                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 21963                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI))  
 21964                              <1> 	;
 21965                              <1> 		; / get the byte that has the allocation bit for 
 21966                              <1> 		; / the i-number contained in r1
 21967                              <1> 	;mov	dx, 1
 21968 00005705 B201                <1> 	mov	dl, 1
 21969                              <1> 		; mov $1,mq / put 1 in the mq
 21970 00005707 0FB7D8              <1> 	movzx	ebx, ax
 21971                              <1> 		; mov r1,r2 / r2 now has i-number whose byte
 21972                              <1>  		          ; / in the map we must find
 21973 0000570A 6683EB29            <1> 	sub	bx, 41
 21974                              <1> 		; sub $41.,r2 / r2 has i-41
 21975 0000570E 88D9                <1> 	mov	cl, bl
 21976                              <1> 		; mov r2,r3 / r3 has i-41
 21977 00005710 80E107              <1> 	and	cl, 7
 21978                              <1> 		; bic $!7,r3 / r3 has (i-41) mod 8 to get 
 21979                              <1> 			   ; / the bit position
 21980 00005713 7402                <1> 	jz	short imap1
 21981                              <1> 	;shl	dx, cl
 21982 00005715 D2E2                <1> 	shl	dl, cl
 21983                              <1> 		; mov r3,lsh / move the 1 over (i-41) mod 8 positions
 21984                              <1> imap1:			   ; / to the left to mask the correct bit
 21985 00005717 66C1EB03            <1> 	shr	bx, 3
 21986                              <1> 		; asr r2
 21987                              <1> 		; asr r2
 21988                              <1> 		; asr r2 / r2 has (i-41) base 8 of the byte number
 21989                              <1> 		       ; / from the start of the map
 21990                              <1> 		; mov r2,-(sp) / put (i-41) base 8 on the stack
 21991 0000571B BE[687D0000]        <1> 	mov	esi, systm
 21992                              <1> 		; mov $systm,r2 / r2 points to the in-core image of
 21993                              <1> 				; / the super block for drum
 21994                              <1> 	;cmp	word [cdev], 0
 21995 00005720 803D[D56F0000]00    <1> 	cmp	byte [cdev], 0
 21996                              <1> 		; tst cdev / is the device the disk
 21997 00005727 7606                <1> 	jna	short imap2
 21998                              <1> 		; beq 1f / yes
 21999 00005729 81C608020000        <1> 	add	esi, mount - systm
 22000                              <1> 		; add $mount-systm,r2 / for mounted device,
 22001                              <1> 			; / r2 points to 1st word of its super block
 22002                              <1> imap2: ; 1:
 22003 0000572F 66031E              <1> 	add	bx, [esi] ;; add free map size to si
 22004                              <1> 		; add (r2)+,(sp) / get byte address of allocation bit
 22005 00005732 6683C304            <1> 	add	bx, 4
 22006 00005736 01F3                <1> 	add	ebx, esi
 22007                              <1>         	; add (sp)+,r2 / ?
 22008                              <1> 	;add	ebx, 4 ;; inode map offset in superblock
 22009                              <1> 		      ;; (2 + free map size + 2)
 22010                              <1> 		; add $2,r2 / ?
 22011                              <1>  	; DL/DX (MQ) has a 1 in the calculated bit position
 22012                              <1>         ; BX (R2) has byte address of the byte with allocation bit
 22013 00005738 C3                  <1> 	retn
 22014                              <1> 		; rts r0
 22015                                  %include 'u6.s'        ; 31/05/2015
 22016                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 22017                              <1> ; (re-write kernel for test by using previous version without a major defect)
 22018                              <1> ; ****************************************************************************
 22019                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS6.INC
 22020                              <1> ; Last Modification: 30/11/2021
 22021                              <1> ; ----------------------------------------------------------------------------
 22022                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 22023                              <1> ; (v0.1 - Beginning: 11/07/2012)
 22024                              <1> ;
 22025                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 22026                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 22027                              <1> ; <Bell Laboratories (17/3/1972)>
 22028                              <1> ; <Preliminary Release of UNIX Implementation Document>
 22029                              <1> ;
 22030                              <1> ; Retro UNIX 8086 v1 - U6.ASM (23/07/2014) //// UNIX v1 -> u6.s
 22031                              <1> ;
 22032                              <1> ; ****************************************************************************
 22033                              <1> 
 22034                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22035                              <1> readi:
 22036                              <1> 	; 20/05/2015
 22037                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22038                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 22039                              <1> 	;
 22040                              <1> 	; Reads from an inode whose number in R1
 22041                              <1> 	; 
 22042                              <1> 	; INPUTS ->
 22043                              <1> 	;    r1 - inode number
 22044                              <1> 	;    u.count - byte count user desires
 22045                              <1> 	;    u.base - points to user buffer
 22046                              <1> 	;    u.fofp - points to word with current file offset
 22047                              <1> 	; OUTPUTS ->
 22048                              <1> 	;    u.count - cleared
 22049                              <1> 	;    u.nread - accumulates total bytes passed back
 22050                              <1> 	;
 22051                              <1> 	; ((AX = R1)) input/output
 22052                              <1> 	;    (Retro UNIX Prototype : 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
 22053                              <1>         ;    ((Modified registers: edx, ebx, ecx, esi, esi, ebp))  
 22054                              <1> 
 22055 00005739 31D2                <1> 	xor	edx, edx ; 0
 22056 0000573B 8915[24700000]      <1> 	mov 	[u.nread], edx ; 0
 22057                              <1> 		; clr u.nread / accumulates number of bytes transmitted
 22058 00005741 668915[64700000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
 22059 00005748 3915[20700000]      <1> 	cmp 	[u.count], edx ; 0
 22060                              <1> 		; tst u.count / is number of bytes to be read greater than 0
 22061 0000574E 7701                <1> 	ja 	short readi_1 ; 1f
 22062                              <1> 		; bgt 1f / yes, branch
 22063 00005750 C3                  <1> 	retn
 22064                              <1> 		; rts r0 / no, nothing to read; return to caller
 22065                              <1> readi_1: ; 1:
 22066                              <1> 	;	; mov r1,-(sp) / save i-number on stack
 22067                              <1> 	;cmp	ax, 40
 22068                              <1> 	;	; cmp r1,$40. / want to read a special file 
 22069                              <1> 	;	;             / (i-nodes 1,...,40 are for special files)
 22070                              <1>         ;ja	dskr 
 22071                              <1> 	;	; ble 1f / yes, branch
 22072                              <1> 	;	; jmp dskr / no, jmp to dskr; 
 22073                              <1> 	;	;         / read file with i-node number (r1)
 22074                              <1> 	;	;    / starting at byte ((u.fofp)), read in u.count bytes
 22075                              <1> 	
 22076                              <1> 	; 28/11/2021
 22077 00005751 F605[68700000]FF    <1> 	test	byte [u.kcall], 0FFh
 22078 00005758 7505                <1> 	jnz	short readi_2  ; 'readi' called by 'namei'
 22079                              <1> 
 22080                              <1> 	; eax = inode number
 22081                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 22082 0000575A E87AFDFFFF          <1> 	call	iget
 22083                              <1> readi_2:
 22084                              <1> 	; 28/11/2021
 22085                              <1> 	; eax = inode number
 22086                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 22087 0000575F E884040000          <1> 	call	is_regular_file
 22088 00005764 0F84E6000000        <1> 	jz	dskr ; regular file 
 22089                              <1> 
 22090                              <1> 	; (20/05/2015)
 22091 0000576A 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 22092                              <1> 
 22093                              <1> 	; 28/11/2021	
 22094                              <1> 	; device file
 22095 0000576B BB[85570000]        <1> 	mov	ebx, readi_4
 22096 00005770 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 22097 00005773 720E                <1> 	jb	short readi_3
 22098 00005775 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 22099 00005778 7709                <1> 	ja	short readi_3	
 22100                              <1> 	
 22101                              <1> 	; convert v2 inode number to v1 device inode number
 22102 0000577A 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 22103 0000577C 89C1                <1> 	mov	ecx, eax
 22104 0000577E C0E102              <1> 	shl	cl, 2 ; * 4
 22105 00005781 01CB                <1> 	add	ebx, ecx
 22106                              <1> readi_3:
 22107 00005783 FF23                <1> 	jmp	dword [ebx]	
 22108                              <1> 		 ; jmp *1f-2(r1)
 22109                              <1> readi_4: ; 1:
 22110 00005785 [D5570000]          <1> 	dd	null ; 28/11/2021
 22111 00005789 [D9570000]          <1> 	dd	rtty ; tty, AX = 1 (runix)
 22112                              <1> 		 ;rtty / tty; r1=2
 22113                              <1> 		 ;rppt / ppt; r1=4
 22114 0000578D [2C580000]          <1> 	dd	rmem ; mem, AX = 2 (runix)
 22115                              <1> 		 ;rmem / mem; r1=6
 22116                              <1> 		 ;rrf0 / rf0
 22117                              <1> 		 ;rrk0 / rk0
 22118                              <1> 		 ;rtap / tap0
 22119                              <1> 		 ;rtap / tap1
 22120                              <1> 		 ;rtap / tap2
 22121                              <1> 		 ;rtap / tap3
 22122                              <1> 		 ;rtap / tap4
 22123                              <1> 		 ;rtap / tap5
 22124                              <1> 		 ;rtap / tap6
 22125                              <1> 		 ;rtap / tap7
 22126 00005791 [0B5F0000]          <1> 	dd	rfd ; fd0, AX = 3 (runix only)
 22127 00005795 [0B5F0000]          <1> 	dd	rfd ; fd1, AX = 4 (runix only)
 22128 00005799 [0B5F0000]          <1> 	dd	rhd ; hd0, AX = 5 (runix only)
 22129 0000579D [0B5F0000]          <1> 	dd	rhd ; hd1, AX = 6 (runix only)	
 22130 000057A1 [0B5F0000]          <1> 	dd	rhd ; hd2, AX = 7 (runix only)
 22131 000057A5 [0B5F0000]          <1> 	dd	rhd ; hd3, AX = 8 (runix only)	
 22132 000057A9 [41580000]          <1> 	dd	rlpr ; lpr, AX = 9 (invalid, write only device !?)
 22133 000057AD [28580000]          <1> 	dd	rcvt ; tty0, AX = 10 (runix)	  
 22134                              <1> 		 ;rcvt / tty0
 22135 000057B1 [28580000]          <1> 	dd	rcvt ; tty1, AX = 11 (runix)	  
 22136                              <1> 		 ;rcvt / tty1
 22137 000057B5 [28580000]          <1> 	dd	rcvt ; tty2, AX = 12 (runix)	  
 22138                              <1> 		 ;rcvt / tty2
 22139 000057B9 [28580000]          <1> 	dd	rcvt ; tty3, AX = 13 (runix)	  
 22140                              <1> 		 ;rcvt / tty3
 22141 000057BD [28580000]          <1> 	dd	rcvt ; tty4, AX = 14 (runix)	  
 22142                              <1> 		 ;rcvt / tty4
 22143 000057C1 [28580000]          <1> 	dd	rcvt ; tty5, AX = 15 (runix)	  
 22144                              <1> 		 ;rcvt / tty5
 22145 000057C5 [28580000]          <1> 	dd	rcvt ; tty6, AX = 16 (runix)	  
 22146                              <1> 		 ;rcvt / tty6
 22147 000057C9 [28580000]          <1> 	dd	rcvt ; tty7, AX = 17 (runix)	  
 22148                              <1> 		 ;rcvt / tty7
 22149 000057CD [28580000]          <1> 	dd	rcvt ; COM1, AX = 18 (runix only)	  
 22150                              <1> 		 ;rcrd / crd
 22151 000057D1 [28580000]          <1> 	dd	rcvt ; COM2, AX = 19 (runix only)
 22152                              <1> 
 22153                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22154                              <1> null:
 22155 000057D5 31C0                <1> 	xor	eax, eax
 22156 000057D7 58                  <1> 	pop	eax
 22157 000057D8 C3                  <1> 	retn
 22158                              <1> 
 22159                              <1> rtty: ; / read from console tty
 22160                              <1> 	; 17/10/2015 - 16/07/2015 (Retro UNIX 8086 v1)
 22161                              <1> 	; 	     (Only 1 byte is read, by ignoring byte count!)
 22162                              <1> 	;  	     WHAT FOR: Every character from Keyboard input 
 22163                              <1> 	;	     must be written immediate on video page (screen)
 22164                              <1> 	;	     when it is required.	
 22165                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22166                              <1> 	; 11/03/2013 - 19/06/2014 (Retro UNIX 8086 v1)
 22167                              <1> 	;
 22168                              <1> 	; Console tty buffer is PC keyboard buffer
 22169                              <1> 	; and keyboard-keystroke handling is different than original
 22170                              <1> 	; unix (PDP-11) here. TTY/Keyboard procedures here are changed
 22171                              <1> 	; according to IBM PC compatible ROM BIOS keyboard functions. 
 22172                              <1> 	;
 22173                              <1> 	; 06/12/2013
 22174 000057D9 0FB61D[49700000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 22175 000057E0 8A83[2F6D0000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 22176                              <1> rttys:
 22177                              <1> 		; mov tty+[8*ntty]-8+6,r5 / r5 is the address of the 4th word of
 22178                              <1> 	               ; / of the control and status block
 22179                              <1> 		; tst 2(r5) / for the console tty; this word points to the console
 22180                              <1> 		       ; / tty buffer
 22181                              <1> 	; 28/07/2013
 22182 000057E6 A2[2D700000]        <1> 	mov 	[u.ttyn], al
 22183                              <1> 	; 13/01/2014
 22184 000057EB FEC0                <1> 	inc	al
 22185 000057ED A2[2E700000]        <1> 	mov	[u.ttyp], al ; tty number + 1
 22186                              <1> rtty_nc: ; 01/02/2014
 22187                              <1> 	; 29/09/2013
 22188 000057F2 B90A000000          <1> 	mov	ecx, 10
 22189                              <1> rtty_1: 	; 01/02/2014
 22190 000057F7 6651                <1> 	push 	cx ; 29/09/2013
 22191                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
 22192 000057F9 B001                <1> 	mov 	al, 1
 22193 000057FB E86D0B0000          <1> 	call 	getc
 22194 00005800 6659                <1> 	pop 	cx ; 29/09/2013	
 22195 00005802 7516                <1> 	jnz	short rtty_2
 22196                              <1> 		; bne 1f / 2nd word of console tty buffer contains number
 22197                              <1> 	               ; / of chars. Is this number non-zero?
 22198 00005804 E20D                <1> 	loop	rtty_idle ; 01/02/2014
 22199                              <1> 	; 05/10/2013
 22200 00005806 8A25[2D700000]      <1> 	mov	ah, [u.ttyn]
 22201                              <1> 	; 29/09/2013
 22202 0000580C E813F9FFFF          <1> 	call	sleep
 22203                              <1> 		; jsr r0,canon; ttych / if 0, call 'canon' to get a line
 22204                              <1>                 ;           / (120 chars.)
 22205                              <1> 	;byte [u.ttyn] = tty number (0 to 9) 
 22206 00005811 EBDF                <1> 	jmp	short rtty_nc ; 01/02/2014
 22207                              <1> 
 22208                              <1> rtty_idle:
 22209                              <1> 	; 29/07/2013
 22210 00005813 E878F8FFFF          <1> 	call 	idle
 22211 00005818 EBDD                <1> 	jmp	short rtty_1 ; 01/02/2014
 22212                              <1> 	;1:
 22213                              <1> 		; tst 2(r5) / is the number of characters zero
 22214                              <1> 		; beq ret1 / yes, return to caller via 'ret1'
 22215                              <1> 		; movb *4(r5),r1 / no, put character in r1
 22216                              <1> 		; inc 4(r5) / 3rd word of console tty buffer points to byte which
 22217                              <1> 		          ; / contains the next char.
 22218                              <1> 		; dec 2(r5) / decrement the character count
 22219                              <1> rtty_2:
 22220 0000581A 30C0                <1> 	xor 	al, al
 22221 0000581C E84C0B0000          <1> 	call 	getc
 22222 00005821 E891000000          <1> 	call	passc
 22223                              <1> 		; jsr r0,passc / move the character to core (user)
 22224                              <1> 	;; 17/10/2015 - 16/07/2015
 22225                              <1> 	; 19/06/2014
 22226                              <1> 	;;jnz	short rtty_nc
 22227 00005826 58                  <1> 	pop	eax  ; (20/05/2015)
 22228 00005827 C3                  <1> 	retn 
 22229                              <1> ;ret1:
 22230                              <1> 		; jmp ret / return to caller via 'ret'
 22231                              <1> 
 22232                              <1> rcvt:   ; < receive/read character from tty >
 22233                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22234                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 22235                              <1> 	;
 22236                              <1> 	; Retro UNIX 8086 v1 modification !
 22237                              <1> 	; 
 22238                              <1> 	; In original UNIX v1, 'rcvt' routine 
 22239                              <1> 	;		(exactly different than this one)
 22240                              <1> 	;	was in 'u9.s' file.
 22241                              <1> 	;
 22242 00005828 2C0A                <1> 	sub 	al, 10
 22243                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 22244                              <1> 	; 16/07/2013
 22245                              <1> 	; 21/05/2013
 22246 0000582A EBBA                <1>         jmp     short rttys
 22247                              <1>       
 22248                              <1> ;rppt: / read paper tape
 22249                              <1> ;	jsr	r0,pptic / gets next character in clist for ppt input and
 22250                              <1> ;			 / places
 22251                              <1> ;		br ret / it in r1; if there 1s no problem with reader, it
 22252                              <1> ;		       / also enables read bit in prs
 22253                              <1> ;	jsr	r0,passc / place character in users buffer area
 22254                              <1> ;	br	rppt
 22255                              <1> 
 22256                              <1> rmem: ; / transfer characters from memory to a user area of core
 22257                              <1> 	; 17/10/2015
 22258                              <1> 	; 11/06/2015
 22259                              <1> 	; 24/05/2015
 22260                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22261                              <1> 	;
 22262 0000582C 8B35[08700000]      <1> 	mov     esi, [u.fofp]
 22263                              <1> rmem_1:
 22264 00005832 8B1E                <1>         mov     ebx, [esi]        
 22265                              <1> 	        ; mov *u.fofp,r1 / save file offset which points to the char
 22266                              <1> 		               ; / to be transferred to user
 22267 00005834 FF06                <1>         inc     dword [esi] ; 17/10/2015
 22268                              <1> 		; inc *u.fofp / increment file offset to point to 'next' 
 22269                              <1> 			    ; / char in memory file
 22270 00005836 8A03                <1> 	mov	al, [ebx]
 22271                              <1> 		; movb (r1),r1 / get character from memory file, 
 22272                              <1> 		             ; / put it in r1
 22273 00005838 E87A000000          <1> 	call	passc        ; jsr r0,passc / move this character to 
 22274                              <1> 			     ;  / the next byte of the users core area
 22275                              <1> 		; br rmem / continue
 22276 0000583D 75F3                <1> 	jnz	short rmem_1
 22277                              <1> ret_:
 22278 0000583F 58                  <1> 	pop	eax ; 09/06/2015
 22279 00005840 C3                  <1> 	retn
 22280                              <1> 
 22281                              <1> rlpr:
 22282                              <1> ;1:
 22283                              <1> ;rcrd:
 22284 00005841 C705[6A700000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 22285 00005849 0000                <1>
 22286 0000584B E922E4FFFF          <1> 	jmp	error
 22287                              <1> 		;jmp	error / see 'error' routine
 22288                              <1> 
 22289                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22290                              <1> dskr:
 22291                              <1> 	; 12/10/2015
 22292                              <1> 	; 21/08/2015
 22293                              <1> 	; 25/07/2015
 22294                              <1> 	; 10/07/2015
 22295                              <1> 	; 16/06/2015
 22296                              <1> 	; 31/05/2015
 22297                              <1> 	; 24/05/2015 (Retro UNIX 386 v1 - Beginning)
 22298                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 22299                              <1> dskr_0:
 22300 00005850 50                  <1> 	push	eax
 22301                              <1> 		; mov (sp),r1 / i-number in r1
 22302                              <1> 	; AX = i-number
 22303 00005851 E883FCFFFF          <1> 	call	iget
 22304                              <1> 		; jsr r0,iget / get i-node (r1) into i-node section of core
 22305                              <1>         ;movzx	edx, word [i.size] ; 16/06/2015
 22306                              <1> 	;	; mov i.size,r2 / file size in bytes in r2
 22307                              <1> 	; 28/11/2021
 22308 00005856 8B15[986C0000]      <1> 	mov	edx, [i.size] ; 32 bit file size (runix v2 inode)
 22309                              <1> 	;
 22310 0000585C 8B1D[08700000]      <1> 	mov	ebx, [u.fofp]
 22311 00005862 2B13                <1> 	sub	edx, [ebx]
 22312                              <1> 		; sub *u.fofp,r2 / subtract file offset
 22313                              <1>         ; 12/10/2015
 22314                              <1> 	; jna	short ret_ 
 22315                              <1> 		; blos ret
 22316 00005864 7709                <1> 	ja	short dskr_1
 22317                              <1> 	;
 22318                              <1> dskr_retn: ; 12/10/2015
 22319 00005866 58                  <1> 	pop	eax
 22320 00005867 C605[68700000]00    <1> 	mov	byte [u.kcall], 0
 22321 0000586E C3                  <1> 	retn	
 22322                              <1> dskr_1: 
 22323 0000586F 3B15[20700000]      <1> 	cmp     edx, [u.count] 
 22324                              <1> 		; cmp r2,u.count / are enough bytes left in file 
 22325                              <1> 			       ; / to carry out read
 22326 00005875 7306                <1> 	jnb	short dskr_2
 22327                              <1> 		; bhis 1f
 22328 00005877 8915[20700000]      <1> 	mov	[u.count], edx
 22329                              <1> 		; mov r2,u.count / no, just read to end of file
 22330                              <1> dskr_2: ; 1:
 22331                              <1> 	; (E)AX = i-number ; 28/11/2021 (32 bit inode number)
 22332                              <1> 	;call	mget
 22333                              <1> 		; jsr r0,mget / returns physical block number of block 
 22334                              <1> 		    ; / in file where offset points
 22335                              <1> 	; 28/11/2021
 22336 0000587D E82EF9FFFF          <1> 	call	mget_r
 22337                              <1> 
 22338                              <1> 	; eax = physical block number
 22339                              <1> 	; [cdev] = current device number 
 22340 00005882 E8DE070000          <1> 	call	dskrd
 22341                              <1> 		; jsr r0,dskrd / read in block, r5 points to 
 22342                              <1> 			     ; / 1st word of data in buffer
 22343                              <1> 	; 09/06/2015
 22344 00005887 803D[68700000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
 22345 0000588E 770F                <1> 	ja	short dskr_4	  ; zf=0 -> the caller is 'namei'
 22346 00005890 66833D[64700000]00  <1> 	cmp	word [u.pcount], 0
 22347 00005898 7705                <1> 	ja	short dskr_4
 22348                              <1> dskr_3:
 22349                              <1> 	; [u.base] = virtual address to transfer (as destination address)
 22350 0000589A E853000000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 22351                              <1> dskr_4:
 22352                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
 22353 0000589F E8C3020000          <1> 	call	sioreg
 22354                              <1> 		; jsr r0,sioreg
 22355 000058A4 87F7                <1> 	xchg	esi, edi
 22356                              <1> 	; edi = file (user data) offset
 22357                              <1> 	; edi = sector (I/O) buffer offset
 22358                              <1> 	; ecx = byte count
 22359 000058A6 F3A4                <1> 	rep	movsb
 22360                              <1> 		; movb (r2)+,(r1)+ / move data from buffer into working core
 22361                              <1> 		                 ; / starting at u.base
 22362                              <1> 		; dec r3
 22363                              <1> 		; bne 2b / branch until proper number of bytes are transferred
 22364                              <1> 	; 25/07/2015
 22365                              <1> 	; eax = remain bytes in buffer
 22366                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 22367 000058A8 09C0                <1> 	or	eax, eax
 22368 000058AA 75EE                <1> 	jnz	short dskr_3 ; (page end before system buffer end!)		
 22369                              <1> 	; 03/08/2013
 22370                              <1> 	;pop	eax
 22371 000058AC 390D[20700000]      <1> 	cmp	[u.count], ecx ; 0
 22372                              <1> 		; tst u.count / all bytes read off disk
 22373                              <1> 		; bne dskr
 22374                              <1> 		; br ret
 22375                              <1>         ;ja	short dskr_0
 22376                              <1> 	;mov	[u.kcall], cl ; 0 ; 09/06/2015
 22377                              <1> 	;retn
 22378                              <1> 	; 12/10/2015
 22379 000058B2 76B2                <1> 	jna	short dskr_retn
 22380 000058B4 58                  <1> 	pop	eax  ; (i-node number)
 22381 000058B5 EB99                <1> 	jmp	short dskr_0
 22382                              <1> 	
 22383                              <1> passc:
 22384                              <1> 	; 18/10/2015
 22385                              <1> 	; 10/07/2015
 22386                              <1> 	; 01/07/2015
 22387                              <1> 	; 08/06/2015
 22388                              <1> 	; 04/06/2015
 22389                              <1> 	; 20/05/2015
 22390                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22391                              <1> 	;
 22392                              <1>    	;(Retro UNIX 386 v1 - translation from user's virtual address
 22393                              <1> 	;		      to physical address
 22394 000058B7 66833D[64700000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 22395                              <1> 			     ; 1-4095 --> use previous physical base address
 22396                              <1> 			     ; in [u.pbase]
 22397 000058BF 7705                <1> 	ja	short passc_3
 22398                              <1> 	; 08/06/2015 - 10/07/2015
 22399 000058C1 E82C000000          <1> 	call	trans_addr_w
 22400                              <1> passc_3:
 22401                              <1> 	; 19/05/2015
 22402 000058C6 66FF0D[64700000]    <1> 	dec	word [u.pcount]
 22403                              <1> 	;
 22404 000058CD 8B1D[60700000]      <1> 	mov	ebx, [u.pbase]
 22405 000058D3 8803                <1> 	mov	[ebx], al
 22406                              <1> 		; movb r1,*u.base / move a character to the next byte of the
 22407                              <1> 		               ; / users buffer
 22408 000058D5 FF05[1C700000]      <1> 	inc	dword [u.base]
 22409                              <1> 		; inc u.base / increment the pointer to point to 
 22410                              <1> 			  ; / the next byte in users buffer
 22411 000058DB FF05[60700000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 22412 000058E1 FF05[24700000]      <1> 	inc	dword [u.nread]
 22413                              <1> 		; inc u.nread / increment the number of bytes read
 22414 000058E7 FF0D[20700000]      <1> 	dec	dword [u.count]
 22415                              <1> 		; dec u.count / decrement the number of bytes to be read
 22416                              <1> 		; bne 1f / any more bytes to read? ; yes, branch
 22417 000058ED C3                  <1> 	retn
 22418                              <1> 		; mov (sp)+,r0 / no, do a non-local return to the caller of
 22419                              <1> 		             ; / 'readi' by:
 22420                              <1> 		;/ (1) pop the return address off the stack into r0
 22421                              <1> 		; mov (sp)+,r1 / (2) pop the i-number off the stack into r1
 22422                              <1> 	;1:
 22423                              <1> 		; clr	*$ps / clear processor status
 22424                              <1> 		; rts r0 / return to address currently on top of stack
 22425                              <1> 
 22426                              <1> trans_addr_r:
 22427                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
 22428                              <1> 	;	-'add_to_swap_queue' call is diasbled as temporary-
 22429                              <1> 	; Translate virtual address to physical address 
 22430                              <1> 	; for reading from user's memory space
 22431                              <1> 	; (Retro UNIX 386 v1 feature only !)
 22432                              <1> 	; 18/10/2015
 22433                              <1> 	; 10/07/2015
 22434                              <1> 	; 09/06/2015
 22435                              <1> 	; 08/06/2015 
 22436                              <1> 	; 04/06/2015
 22437                              <1> 	;
 22438                              <1> 	; 18/10/2015
 22439 000058EE 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
 22440 000058F0 EB04                <1> 	jmp 	short trans_addr_rw
 22441                              <1> 
 22442                              <1> 	;push	eax
 22443                              <1> 	;push	ebx
 22444                              <1> 	;mov	ebx, [u.base]
 22445                              <1> 	;call	get_physical_addr ; get physical address
 22446                              <1> 	;;jnc	short cpass_0
 22447                              <1> 	;jnc	short passc_1
 22448                              <1> 	;mov	[u.error], eax
 22449                              <1> 	;;pop	ebx
 22450                              <1> 	;;pop	eax
 22451                              <1> 	;jmp	error
 22452                              <1> ;cpass_0:
 22453                              <1> 	; 18/10/2015
 22454                              <1> 	; 20/05/2015
 22455                              <1> 	;mov 	[u.pbase], eax ; physical address	
 22456                              <1> 	;mov	[u.pcount], cx ; remain byte count in page (1-4096)
 22457                              <1> 	;pop	ebx
 22458                              <1> 	;pop	eax
 22459                              <1> 	;retn	; 08/06/2015
 22460                              <1> 
 22461                              <1> trans_addr_w:
 22462                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
 22463                              <1> 	;	-'add_to_swap_queue' call is diasbled as temporary-
 22464                              <1> 	; Translate virtual address to physical address
 22465                              <1> 	; for writing to user's memory space
 22466                              <1> 	; (Retro UNIX 386 v1 feature only !)
 22467                              <1> 	; 18/10/2015
 22468                              <1> 	; 29/07/2015
 22469                              <1> 	; 10/07/2015
 22470                              <1> 	; 09/06/2015
 22471                              <1> 	; 08/06/2015
 22472                              <1> 	; 04/06/2015 (passc)
 22473                              <1> 	;
 22474                              <1> 	; 18/10/2015
 22475 000058F2 29D2                <1> 	sub	edx, edx
 22476 000058F4 FEC2                <1> 	inc	dl ; 1 (write access sign)
 22477                              <1> trans_addr_rw:
 22478 000058F6 50                  <1> 	push	eax
 22479 000058F7 53                  <1> 	push	ebx
 22480                              <1> 	; 18/10/2015
 22481 000058F8 52                  <1> 	push 	edx ; r/w sign (in DL)
 22482                              <1> 	;
 22483 000058F9 8B1D[1C700000]      <1> 	mov	ebx, [u.base]
 22484 000058FF E812DAFFFF          <1> 	call	get_physical_addr ; get physical address
 22485 00005904 730A                <1> 	jnc	short passc_0
 22486 00005906 A3[6A700000]        <1> 	mov	[u.error], eax
 22487                              <1> 	;pop	edx
 22488                              <1> 	;pop 	ebx
 22489                              <1> 	;pop	eax
 22490 0000590B E962E3FFFF          <1> 	jmp	error
 22491                              <1> passc_0:
 22492 00005910 F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page ; 18/10/2015
 22493 00005913 5A                  <1> 	pop	edx ; 18/10/2015
 22494 00005914 7515                <1> 	jnz	short passc_1
 22495                              <1> 	; 18/10/2015
 22496 00005916 20D2                <1> 	and 	dl, dl
 22497 00005918 7411                <1> 	jz	short passc_1
 22498                              <1> 	; 20/05/2015
 22499                              <1> 	; read only (duplicated) page -must be copied to a new page-
 22500                              <1> 	; EBX = linear address
 22501 0000591A 51                  <1> 	push 	ecx
 22502 0000591B E865D9FFFF          <1> 	call 	copy_page
 22503 00005920 59                  <1> 	pop	ecx
 22504 00005921 7217                <1> 	jc	short passc_2
 22505                              <1> 	; 30/11/2021
 22506                              <1> 	;push	eax ; physical address of the new/allocated page
 22507                              <1> 	;call	add_to_swap_queue
 22508                              <1> 	;pop	eax
 22509                              <1> 	; 18/10/2015
 22510 00005923 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
 22511                              <1> 	;mov 	ecx, PAGE_SIZE
 22512                              <1> 	;sub	ecx, ebx 
 22513 00005929 01D8                <1> 	add	eax, ebx  
 22514                              <1> passc_1: 
 22515                              <1> 	; 18/10/2015
 22516                              <1> 	; 20/05/2015
 22517 0000592B A3[60700000]        <1> 	mov 	[u.pbase], eax ; physical address	
 22518 00005930 66890D[64700000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
 22519 00005937 5B                  <1> 	pop	ebx
 22520 00005938 58                  <1> 	pop	eax
 22521 00005939 C3                  <1> 	retn	; 08/06/2015
 22522                              <1> passc_2:
 22523 0000593A C705[6A700000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
 22524 00005942 0000                <1>
 22525                              <1> 	;pop 	ebx
 22526                              <1> 	;pop	eax
 22527 00005944 E929E3FFFF          <1> 	jmp	error
 22528                              <1> 
 22529                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22530                              <1> writei:
 22531                              <1> 	; 20/05/2015
 22532                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22533                              <1> 	; 12/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 22534                              <1> 	;
 22535                              <1> 	; Write data to file with inode number in R1
 22536                              <1> 	; 
 22537                              <1> 	; INPUTS ->
 22538                              <1> 	;    r1 - inode number
 22539                              <1> 	;    u.count - byte count to be written
 22540                              <1> 	;    u.base - points to user buffer
 22541                              <1> 	;    u.fofp - points to word with current file offset
 22542                              <1> 	; OUTPUTS ->
 22543                              <1> 	;    u.count - cleared
 22544                              <1> 	;    u.nread - accumulates total bytes passed back	
 22545                              <1> 	; ((AX = R1))
 22546                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 11/11/2012, UNIXCOPY.ASM)
 22547                              <1> 	;    ((Modified registers: DX, BX, CX, SI, DI, BP)) 	
 22548                              <1> 
 22549 00005949 31C9                <1> 	xor	ecx, ecx
 22550 0000594B 890D[24700000]      <1> 	mov 	[u.nread], ecx  ; 0
 22551                              <1> 		; clr u.nread / clear the number of bytes transmitted during
 22552                              <1> 		            ; / read or write calls
 22553 00005951 66890D[64700000]    <1> 	mov	[u.pcount], cx ; 19/05/2015
 22554 00005958 390D[20700000]      <1> 	cmp 	[u.count], ecx
 22555                              <1> 	;	; tst u.count / test the byte count specified by the user
 22556 0000595E 7701                <1> 	ja 	short writei_1 ; 1f
 22557                              <1> 		; bgt 1f / any bytes to output; yes, branch
 22558 00005960 C3                  <1> 	retn
 22559                              <1> 	;	; rts r0 / no, return - no writing to do
 22560                              <1> writei_1: ;1:
 22561                              <1> 	;	; mov r1 ,-(sp) / save the i-node number on the stack
 22562                              <1> 	;cmp 	ax, 40
 22563                              <1> 	;	; cmp r1,$40.
 22564                              <1> 	;	; / does the i-node number indicate a special file?
 22565                              <1>         ;ja	dskw 
 22566                              <1> 	;	; bgt dskw / no, branch to standard file output
 22567                              <1> 
 22568                              <1> 	; 28/11/2021
 22569 00005961 F605[68700000]FF    <1> 	test	byte [u.kcall], 0FFh
 22570 00005968 7505                <1> 	jnz	short writei_2  ; 'writei' called by 'mkdir'
 22571                              <1> 
 22572                              <1> 	; eax = inode number
 22573                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 22574 0000596A E86AFBFFFF          <1> 	call	iget
 22575                              <1> writei_2:
 22576                              <1> 	; 28/11/2021
 22577                              <1> 	; eax = inode number
 22578                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 22579 0000596F E874020000          <1> 	call	is_regular_file
 22580 00005974 0F8401010000        <1> 	jz	dskw ; regular file 
 22581                              <1> 
 22582                              <1> 	; (20/05/2015)
 22583 0000597A 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 22584                              <1> 	
 22585                              <1> 	; 28/11/2021	
 22586                              <1> 	; device file
 22587 0000597B BB[95590000]        <1> 	mov	ebx, writei_4
 22588 00005980 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 22589 00005983 720E                <1> 	jb	short writei_3
 22590 00005985 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 22591 00005988 7209                <1> 	jb	short writei_3	
 22592                              <1> 	
 22593                              <1> 	; convert v2 inode number to v1 device inode number
 22594 0000598A 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 22595 0000598C 89C1                <1> 	mov	ecx, eax
 22596 0000598E C0E102              <1> 	shl	cl, 2 ; * 4
 22597 00005991 01CB                <1> 	add	ebx, ecx
 22598                              <1> writei_3:
 22599 00005993 FF23                <1> 	jmp	dword [ebx]	
 22600                              <1> 		; jmp *1f-2(r1)
 22601                              <1> 		; / jump table and jump to the appropriate routine
 22602                              <1> writei_4: ;1:
 22603 00005995 [D5570000]          <1> 	dd	null ; 28/11/2021
 22604 00005999 [E5590000]          <1> 	dd	wtty ; tty, AX = 1 (runix)
 22605                              <1> 		 ;wtty / tty; r1=2
 22606                              <1> 		 ;wppt / ppt; r1=4
 22607 0000599D [4B5A0000]          <1> 	dd	wmem ; mem, AX = 2 (runix)
 22608                              <1> 		 ;wmem / mem; r1=6
 22609                              <1> 		 ;wrf0 / rf0
 22610                              <1> 		 ;wrk0 / rk0
 22611                              <1> 		 ;wtap / tap0
 22612                              <1> 		 ;wtap / tap1
 22613                              <1> 		 ;wtap / tap2
 22614                              <1> 		 ;wtap / tap3
 22615                              <1> 		 ;wtap / tap4
 22616                              <1> 		 ;wtap / tap5
 22617                              <1> 		 ;wtap / tap6
 22618                              <1> 		 ;wtap / tap7
 22619 000059A1 [8D5F0000]          <1> 	dd	wfd ; fd0, AX = 3 (runix only)
 22620 000059A5 [8D5F0000]          <1> 	dd	wfd ; fd1, AX = 4 (runix only)
 22621 000059A9 [8D5F0000]          <1> 	dd	whd ; hd0, AX = 5 (runix only)
 22622 000059AD [8D5F0000]          <1> 	dd	whd ; hd1, AX = 6 (runix only)	
 22623 000059B1 [8D5F0000]          <1> 	dd	whd ; hd2, AX = 7 (runix only)
 22624 000059B5 [8D5F0000]          <1> 	dd	whd ; hd3, AX = 8 (runix only)	
 22625 000059B9 [3C5A0000]          <1> 	dd	wlpr ; lpr, AX = 9   (runix)
 22626 000059BD [365A0000]          <1> 	dd	xmtt ; tty0, AX = 10 (runix)	  
 22627                              <1> 		 ;xmtt / tty0
 22628 000059C1 [365A0000]          <1> 	dd	xmtt ; tty1, AX = 11 (runix)	  
 22629                              <1> 		 ;xmtt / tty1
 22630 000059C5 [365A0000]          <1> 	dd	xmtt ; tty2, AX = 12 (runix)	  
 22631                              <1> 		 ;xmtt / tty2
 22632 000059C9 [365A0000]          <1> 	dd	xmtt ; tty3, AX = 13 (runix)	  
 22633                              <1> 		 ;xmtt / tty3
 22634 000059CD [365A0000]          <1> 	dd	xmtt ; tty4, AX = 14 (runix)	  
 22635                              <1> 		 ;xmtt / tty4
 22636 000059D1 [365A0000]          <1> 	dd	xmtt ; tty5, AX = 15 (runix)	  
 22637                              <1> 		 ;xmtt / tty5
 22638 000059D5 [365A0000]          <1> 	dd	xmtt ; tty6, AX = 16 (runix)	  
 22639                              <1> 		 ;xmtt / tty6
 22640 000059D9 [365A0000]          <1> 	dd	xmtt ; tty7, AX = 17 (runix)	  
 22641                              <1> 		 ;xmtt / tty7
 22642 000059DD [365A0000]          <1> 	dd	xmtt ; COM1, AX = 18 (runix only)	  
 22643                              <1> 		; / wlpr / lpr
 22644 000059E1 [365A0000]          <1> 	dd	xmtt ; COM2, AX = 19 (runix only)
 22645                              <1> 
 22646                              <1> ;	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22647                              <1> ;null:
 22648                              <1> ;	xor	eax, eax
 22649                              <1> ;	pop	eax
 22650                              <1> ;	retn	
 22651                              <1> 
 22652                              <1> wtty: ; write to console tty (write to screen)
 22653                              <1> 	; 18/11/2015
 22654                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22655                              <1> 	; 12/03/2013 - 07/07/2014 (Retro UNIX 8086 v1)
 22656                              <1> 	;
 22657                              <1> 	; Console tty output is on current video page
 22658                              <1> 	; Console tty character output procedure is changed here
 22659                              <1> 	; acconding to IBM PC compatible ROM BIOS video (text mode) functions.
 22660                              <1> 	;
 22661 000059E5 0FB61D[49700000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 22662 000059EC 8AA3[2F6D0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 22663 000059F2 88E0                <1> 	mov	al, ah ; 07/07/2014
 22664                              <1> wttys:	
 22665                              <1> 	; 10/10/2013
 22666 000059F4 8825[2D700000]      <1> 	mov 	[u.ttyn], ah
 22667                              <1> 	; 13/01/2014
 22668 000059FA FEC0                <1> 	inc	al
 22669 000059FC A2[2F700000]        <1> 	mov	[u.ttyp+1], al ; tty number + 1
 22670                              <1> wtty_nc: ; 15/05/2013
 22671                              <1> 	; AH = [u.ttyn] = tty number ; 28/07/2013
 22672 00005A01 E801010000          <1> 	call	cpass
 22673                              <1> 		; jsr r0,cpass / get next character from user buffer area; if
 22674                              <1> 		             ; / none go to return address in syswrite
 22675                              <1> 		; tst r1 / is character = null
 22676                              <1> 		; beq wtty / yes, get next character
 22677                              <1> 	; 10/10/2013
 22678 00005A06 742C                <1> 	jz	short wret
 22679                              <1> 	;1 :
 22680                              <1> 		;mov 	$240,*$ps / no, set processor priority to five
 22681                              <1> 		;cmpb	cc+1,$20. / is character count for console tty greater
 22682                              <1> 		;	          / than 20
 22683                              <1> 		;bhis	2f / yes; branch to put process to sleep
 22684                              <1> 	; 27/06/2014
 22685                              <1> wtty_1:
 22686                              <1> 	; AH = tty number
 22687                              <1> 	; AL = ASCII code of the character
 22688                              <1> 	; 15/04/2014
 22689 00005A08 6650                <1> 	push	ax
 22690 00005A0A E8CB0A0000          <1> 	call	putc ; 14/05/2013
 22691 00005A0F 731F                <1> 	jnc	short wtty_2
 22692                              <1> 	; 18/11/2015
 22693 00005A11 E87AF6FFFF          <1> 	call	idle
 22694 00005A16 668B0424            <1> 	mov	ax, [esp]
 22695 00005A1A E8BB0A0000          <1> 	call	putc
 22696 00005A1F 730F                <1> 	jnc	short wtty_2 
 22697                              <1> 	; 02/06/2014
 22698 00005A21 8A25[2D700000]      <1> 	mov	ah, [u.ttyn]
 22699 00005A27 E8F8F6FFFF          <1> 	call	sleep
 22700 00005A2C 6658                <1> 	pop	ax
 22701 00005A2E EBD8                <1> 	jmp 	short wtty_1
 22702                              <1> 		; jc 	error ; 15/05/2013 (COM1 or COM2 serial port error)
 22703                              <1> 		; jsr 	r0,putc; 1 / find place in freelist to assign to 
 22704                              <1> 			      ; / console tty and
 22705                              <1> 		; br 	2f / place character in list; if none available
 22706                              <1> 		   	  ; / branch to put process to sleep
 22707                              <1> 		; jsr	r0,startty / attempt to output character on tty
 22708                              <1> wtty_2:
 22709                              <1> 	; 15/04/2014
 22710 00005A30 6658                <1> 	pop	ax
 22711 00005A32 EBCD                <1> 	jmp	short wtty_nc
 22712                              <1> 		; br wtty
 22713                              <1> wret:	; 10/10/2013 (20/05/2015)
 22714 00005A34 58                  <1> 	pop	eax
 22715 00005A35 C3                  <1> 	retn
 22716                              <1> 	;2:
 22717                              <1> 		;mov	r1,-(sp) / place character on stack
 22718                              <1> 		;jsr	r0,sleep; 1 / put process to sleep
 22719                              <1> 		;mov	(sp)+,r1 / remove character from stack
 22720                              <1> 		;br	1b / try again to place character in clist and output
 22721                              <1> 
 22722                              <1> xmtt:   ; < send/write character to tty >
 22723                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22724                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 22725                              <1> 	;
 22726                              <1> 	; Retro UNIX 8086 v1 modification !
 22727                              <1> 	; 
 22728                              <1> 	; In original UNIX v1, 'xmtt' routine 
 22729                              <1> 	;		(exactly different than this one)
 22730                              <1> 	;	was in 'u9.s' file.
 22731                              <1> 	;
 22732 00005A36 2C0A                <1> 	sub 	al, 10
 22733                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 22734                              <1> 	; 10/10/2013
 22735 00005A38 88C4                <1> 	mov	ah, al
 22736                              <1> 	; 28/07/2013
 22737 00005A3A EBB8                <1> 	jmp	short wttys
 22738                              <1> 
 22739                              <1> ;wppt:
 22740                              <1> ;	jsr	r0,cpass / get next character from user buffer area,
 22741                              <1> ;		         / if none return to writei's calling routine
 22742                              <1> ;	jsr	r0,pptoc / output character on ppt
 22743                              <1> ;	br	wppt
 22744                              <1> wlpr:
 22745 00005A3C C705[6A700000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 22746 00005A44 0000                <1>
 22747 00005A46 E927E2FFFF          <1> 	jmp 	error   ; ... Printing procedure will be located here ...
 22748                              <1> 		;/	jsr	r0,cpass
 22749                              <1> 		;/	cmp	r0,$'a
 22750                              <1> 		;/	blo	1f
 22751                              <1> 		;/	cmp	r1,$'z
 22752                              <1> 		;/	bhi	1f
 22753                              <1> 		;/	sub	$40,r1
 22754                              <1> 		;/1:
 22755                              <1> 		;/	jsr	r0,lptoc
 22756                              <1> 		;/	br	wlpr
 22757                              <1> 		; br rmem / continue
 22758                              <1> 
 22759                              <1> wmem: ; / transfer characters from a user area of core to memory file
 22760                              <1> 	; 17/10/2015
 22761                              <1> 	; 11/06/2015
 22762                              <1> 	; 24/05/2015
 22763                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22764                              <1> 	;
 22765 00005A4B 813D[0B070000]-     <1> 	cmp	dword [x_timer], clock ; multi tasking clock/timer
 22766 00005A51 [B4500000]          <1>
 22767 00005A55 7415                <1>         je      short wmem_acc_err
 22768                              <1> 	;
 22769 00005A57 8B35[08700000]      <1>         mov     esi, [u.fofp] 
 22770                              <1> wmem_1:
 22771 00005A5D E8A5000000          <1> 	call	cpass
 22772                              <1> 		; jsr r0,cpass / get next character from users area of
 22773                              <1> 			     ; / core and put it in r1
 22774                              <1>         	; mov r1,-(sp) / put character on the stack
 22775                              <1> 	; 20/09/2013
 22776 00005A62 74D0                <1> 	jz	short wret ; wmem_2  
 22777 00005A64 8B1E                <1>         mov     ebx, [esi]
 22778                              <1> 		; mov *u.fofp,r1 / save file offset in r1
 22779 00005A66 FF06                <1>         inc     dword [esi] ; 17/10/2015
 22780                              <1> 		; inc *u.fofp / increment file offset to point to next
 22781                              <1> 			    ; / available location in file
 22782 00005A68 8803                <1> 	mov	[ebx], al	
 22783                              <1> 		; movb (sp)+,(r1) / pop char off stack, put in memory loc 
 22784                              <1> 			        ; / assigned to it
 22785 00005A6A EBF1                <1> 	jmp	short wmem_1
 22786                              <1> 		; br wmem / continue
 22787                              <1> 	;1:
 22788                              <1> 	;jmp	error / ?
 22789                              <1> ;wmem_2:	
 22790                              <1> ;	; 20/09/2013
 22791                              <1> ;	pop	ax
 22792                              <1> ;	retn
 22793                              <1> 
 22794                              <1> wmem_acc_err:
 22795 00005A6C C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 22796 00005A74 0000                <1>
 22797 00005A76 E9F7E1FFFF          <1> 	jmp	error
 22798                              <1> 
 22799                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22800                              <1> 
 22801                              <1> dskw: ; / write routine for non-special files
 22802                              <1> 	;
 22803                              <1> 	; 28/11/2021
 22804                              <1> 	; 25/07/2015
 22805                              <1> 	; 16/06/2015
 22806                              <1> 	; 09/06/2015
 22807                              <1> 	; 31/05/2015 (Retro UNIX 386 v1 - Beginning)
 22808                              <1> 	; 26/04/2013 - 20/09/2013 (Retro UNIX 8086 v1)
 22809                              <1> 
 22810                              <1> 	; 01/08/2013 (mkdir_w check)
 22811                              <1> 	;push	ax ; 26/04/2013
 22812                              <1> 	;	; mov (sp),r1 / get an i-node number from the stack into r1
 22813                              <1> 	; 28/11/2021
 22814 00005A7B 50                  <1> 	push	eax
 22815                              <1> 	; AX = inode number
 22816 00005A7C E858FAFFFF          <1> 	call	iget
 22817                              <1> 		; jsr r0,iget / write i-node out (if modified), 
 22818                              <1> 		            ; / read i-node 'r1' into i-node area of core
 22819 00005A81 8B1D[08700000]      <1>         mov     ebx, [u.fofp] 
 22820 00005A87 8B13                <1> 	mov 	edx, [ebx]
 22821                              <1> 		; mov *u.fofp,r2 / put the file offset [(u.off) or the offset
 22822                              <1> 			       ; / in the fsp entry for this file] in r2
 22823 00005A89 0315[20700000]      <1> 	add 	edx, [u.count]	
 22824                              <1> 		; add u.count,r2 / no. of bytes to be written
 22825                              <1> 			       ; / + file offset is put in r2
 22826                              <1> 	;; 16/06/2015        
 22827                              <1> 	;cmp	edx, 65535 ; file size limit (for UNIX v1 file system)
 22828                              <1> 	;jna	short dskw_0
 22829                              <1> 	;mov	dword [u.error], ERR_FILE_SIZE ; 'file size error !'
 22830                              <1> 	;jmp	error
 22831                              <1> dskw_0:	
 22832                              <1> 	; 28/11/2021
 22833 00005A8F 3B15[986C0000]      <1> 	cmp	edx, [i.size] ; 32 bit file size (runix v2 inode)
 22834                              <1> 	;cmp	dx, [i.size]
 22835                              <1> 	;	; cmp r2,i.size / is this greater than the present size of
 22836                              <1> 		              ; / the file?
 22837 00005A95 760B                <1> 	jna	short dskw_1
 22838                              <1> 		; blos 1f / no, branch
 22839 00005A97 8915[986C0000]      <1> 	mov	[i.size], edx ; 32 bit file size (runix v2 inode)
 22840                              <1> 	;mov	[i.size], dx
 22841                              <1> 	 	; mov r2,i.size / yes, increase the file size to 
 22842                              <1> 			      ; / file offset + no. of data bytes
 22843 00005A9D E8CAFBFFFF          <1> 	call	setimod
 22844                              <1> 	 	; jsr r0,setimod / set imod=1 (i.e., core inode has been
 22845                              <1> 		          ; / modified), stuff time of modification into
 22846                              <1> 	          	  ; / core image of i-node
 22847                              <1> dskw_1: ; 1:
 22848                              <1> 	; 28/11/2021
 22849                              <1> 	;call	mget
 22850 00005AA2 E800F7FFFF          <1> 	call	mget_w
 22851                              <1> 	; EAX = Block number
 22852                              <1> 		; jsr r0,mget / get the block no. in which to write 
 22853                              <1> 			    ; /	the next data byte
 22854                              <1> 	; eax = block number
 22855 00005AA7 8B1D[08700000]      <1> 	mov     ebx, [u.fofp]
 22856 00005AAD 8B13                <1> 	mov	edx, [ebx]
 22857 00005AAF 81E2FF010000        <1> 	and	edx, 1FFh  
 22858                              <1> 		; bit *u.fofp,$777 / test the lower 9 bits of the file offset
 22859 00005AB5 750C                <1> 	jnz	short dskw_2
 22860                              <1> 		; bne 2f / if its non-zero, branch; if zero, file offset = 0,
 22861                              <1> 		       ; / 512, 1024,...(i.e., start of new block)
 22862 00005AB7 813D[20700000]0002- <1> 	cmp	dword [u.count], 512
 22863 00005ABF 0000                <1>
 22864                              <1> 		; cmp u.count,$512. / if zero, is there enough data to fill
 22865                              <1> 				  ; / an entire block? (i.e., no. of
 22866 00005AC1 7305                <1> 	jnb	short dskw_3
 22867                              <1> 		; bhis 3f / bytes to be written greater than 512.? 
 22868                              <1> 			; / Yes, branch. Don't have to read block
 22869                              <1> dskw_2: ; 2: / in as no past info. is to be saved (the entire block will be
 22870                              <1>    		; / overwritten).
 22871 00005AC3 E89D050000          <1> 	call	dskrd
 22872                              <1> 		; jsr r0,dskrd / no, must retain old info.. 
 22873                              <1> 			     ; / Hence, read block 'r1' into an I/O buffer
 22874                              <1> dskw_3: ; 3:
 22875                              <1> 	; EAX (r1) = block/sector number
 22876 00005AC8 E8F8050000          <1> 	call	wslot
 22877                              <1> 		; jsr r0,wslot / set write and inhibit bits in I/O queue, 
 22878                              <1> 			   ; / proc. status=0, r5 points to 1st word of data
 22879 00005ACD 803D[68700000]00    <1> 	cmp	byte [u.kcall], 0
 22880 00005AD4 770F                <1> 	ja	short dskw_5 ; zf=0 -> the caller is 'mkdir'
 22881                              <1> 	;
 22882 00005AD6 66833D[64700000]00  <1> 	cmp	word [u.pcount], 0
 22883 00005ADE 7705                <1> 	ja	short dskw_5
 22884                              <1> dskw_4:
 22885                              <1> 	; [u.base] = virtual address to transfer (as source address)
 22886 00005AE0 E809FEFFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 22887                              <1> dskw_5:
 22888                              <1> 	; eBX (r5) = system (I/O) buffer address
 22889 00005AE5 E87D000000          <1> 	call	sioreg
 22890                              <1> 		; jsr r0,sioreg / r3 = no. of bytes of data, 
 22891                              <1> 			     ; / r1 = address of data, r2 points to location
 22892                              <1> 			     ; / in buffer in which to start writing data
 22893                              <1> 	; eSI = file (user data) offset
 22894                              <1> 	; eDI = sector (I/O) buffer offset
 22895                              <1> 	; eCX = byte count
 22896                              <1> 	;
 22897 00005AEA F3A4                <1>   	rep	movsb
 22898                              <1> 		; movb (r1 )+,(r2)+ 
 22899                              <1> 		         ; / transfer a byte of data to the I/O buffer
 22900                              <1> 		; dec r3 / decrement no. of bytes to be written
 22901                              <1> 		; bne 2b / have all bytes been transferred? No, branch
 22902                              <1> 	; 25/07/2015
 22903                              <1> 	; eax = remain bytes in buffer
 22904                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 22905 00005AEC 09C0                <1> 	or	eax, eax
 22906 00005AEE 75F0                <1> 	jnz	short dskw_4 ; (page end before system buffer end!)	
 22907                              <1> dskw_6:
 22908 00005AF0 E8EC050000          <1> 	call	dskwr
 22909                              <1> 		; jsr r0,dskwr / yes, write the block and the i-node
 22910 00005AF5 833D[20700000]00    <1>         cmp     dword [u.count], 0
 22911                              <1> 		; tst u.count / any more data to write?
 22912 00005AFC 77A4                <1> 	ja	short dskw_1
 22913                              <1> 		; bne 1b / yes, branch
 22914                              <1> 	; 03/08/2013
 22915 00005AFE C605[68700000]00    <1> 	mov	byte [u.kcall], 0
 22916                              <1> 	; 20/09/2013 (;;)
 22917                              <1> 	;pop	ax
 22918                              <1> 	; 28/11/2021
 22919 00005B05 58                  <1> 	pop	eax  
 22920 00005B06 C3                  <1> 	retn
 22921                              <1> 	;;jmp 	short dskw_ret 
 22922                              <1> 	        ; jmp ret / no, return to the caller via 'ret'
 22923                              <1> 
 22924                              <1> cpass: ; / get next character from user area of core and put it in r1
 22925                              <1> 	; 18/10/2015
 22926                              <1> 	; 10/10/2015
 22927                              <1> 	; 10/07/2015
 22928                              <1> 	; 02/07/2015
 22929                              <1> 	; 01/07/2015
 22930                              <1> 	; 24/06/2015
 22931                              <1> 	; 08/06/2015
 22932                              <1> 	; 04/06/2015
 22933                              <1> 	; 20/05/2015
 22934                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22935                              <1> 	;
 22936                              <1> 	; INPUTS -> 
 22937                              <1> 	;     [u.base] = virtual address in user area
 22938                              <1> 	;     [u.count] = byte count (max.)
 22939                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
 22940                              <1> 	; OUTPUTS -> 
 22941                              <1> 	;     AL = the character which is pointed by [u.base]
 22942                              <1> 	;     zf = 1 -> transfer count has been completed	
 22943                              <1>         ;
 22944                              <1> 	; ((Modified registers:  EAX, EDX, ECX))
 22945                              <1> 	;
 22946                              <1> 	;
 22947 00005B07 833D[20700000]00    <1> 	cmp 	dword [u.count], 0  ; 14/08/2013
 22948                              <1> 		; tst u.count / have all the characters been transferred
 22949                              <1> 			    ; / (i.e., u.count, # of chars. left
 22950 00005B0E 763F                <1> 	jna	short cpass_3
 22951                              <1> 		; beq 1f / to be transferred = 0?) yes, branch
 22952 00005B10 FF0D[20700000]      <1> 	dec	dword [u.count]
 22953                              <1> 		; dec u.count / no, decrement u.count
 22954                              <1>         ; 19/05/2015 
 22955                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
 22956                              <1> 	;		      to physical address
 22957 00005B16 66833D[64700000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 22958                              <1> 			     ; 1-4095 --> use previous physical base address
 22959                              <1> 			     ; in [u.pbase]
 22960 00005B1E 770E                <1> 	ja	short cpass_1
 22961                              <1> 	; 02/07/2015
 22962 00005B20 833D[5C700000]00    <1>         cmp     dword [u.ppgdir], 0  ; is the caller os kernel
 22963 00005B27 7427                <1>         je      short cpass_k       ; (sysexec, '/etc/init') ? 
 22964                              <1> 	; 08/06/2015 - 10/07/2015
 22965 00005B29 E8C0FDFFFF          <1> 	call	trans_addr_r
 22966                              <1> cpass_1:
 22967                              <1> 	; 02/07/2015
 22968                              <1> 	; 24/06/2015
 22969 00005B2E 66FF0D[64700000]    <1> 	dec	word [u.pcount]
 22970                              <1> cpass_2: 
 22971                              <1> 	 ;10/10/2015
 22972                              <1> 	; 02/07/2015
 22973 00005B35 8B15[60700000]      <1> 	mov	edx, [u.pbase]
 22974 00005B3B 8A02                <1> 	mov	al, [edx] ; 10/10/2015
 22975                              <1> 		; movb *u.base,r1 / take the character pointed to 
 22976                              <1> 				; / by u.base and put it in r1
 22977 00005B3D FF05[24700000]      <1> 	inc	dword [u.nread]
 22978                              <1> 		; inc u.nread / increment no. of bytes transferred
 22979 00005B43 FF05[1C700000]      <1> 	inc	dword [u.base]
 22980                              <1> 		; inc u.base / increment the buffer address to point to the
 22981                              <1> 			   ; / next byte
 22982 00005B49 FF05[60700000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 22983                              <1> cpass_3:
 22984 00005B4F C3                  <1> 	retn
 22985                              <1> 		; rts	r0 / next byte
 22986                              <1> 	; 1: 
 22987                              <1> 		; mov (sp)+,r0 
 22988                              <1> 		         ; / put return address of calling routine into r0
 22989                              <1> 		; mov (sp)+,r1 / i-number in r1
 22990                              <1> 		; rts r0 / non-local return
 22991                              <1> cpass_k:
 22992                              <1> 	; 02/07/2015
 22993                              <1> 	; The caller is os kernel 
 22994                              <1> 	; (get sysexec arguments from kernel's memory space)
 22995                              <1> 	;
 22996 00005B50 8B1D[1C700000]      <1> 	mov	ebx, [u.base]
 22997 00005B56 66C705[64700000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
 22998 00005B5E 10                  <1>
 22999 00005B5F 891D[60700000]      <1> 	mov	[u.pbase], ebx
 23000 00005B65 EBCE                <1> 	jmp	short cpass_2
 23001                              <1> 	
 23002                              <1> sioreg: 
 23003                              <1> 	; 25/07/2015
 23004                              <1> 	; 18/07/2015
 23005                              <1> 	; 02/07/2015
 23006                              <1> 	; 17/06/2015
 23007                              <1> 	; 09/06/2015
 23008                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23009                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
 23010                              <1> 	;
 23011                              <1> 	; INPUTS -> 
 23012                              <1> 	;     eBX = system buffer (data) address (r5)
 23013                              <1> 	;     [u.fofp] = pointer to file offset pointer
 23014                              <1> 	;     [u.base] = virtual address of the user buffer
 23015                              <1> 	;     [u.pbase] = physical address of the user buffer
 23016                              <1> 	;     [u.count] = byte count
 23017                              <1> 	;     [u.pcount] = byte count within page frame 			
 23018                              <1> 	; OUTPUTS -> 
 23019                              <1> 	;     eSI = user data offset (r1)
 23020                              <1> 	;     eDI = system (I/O) buffer offset (r2)
 23021                              <1> 	;     eCX = byte count (r3)
 23022                              <1> 	;     EAX = remain bytes after byte count within page frame
 23023                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
 23024                              <1>         ;
 23025                              <1> 	; ((Modified registers:  EDX))
 23026                              <1>  
 23027 00005B67 8B35[08700000]      <1>         mov     esi, [u.fofp]
 23028 00005B6D 8B3E                <1>         mov     edi, [esi]
 23029                              <1> 		; mov *u.fofp,r2 / file offset (in bytes) is moved to r2
 23030 00005B6F 89F9                <1> 	mov	ecx, edi
 23031                              <1> 		; mov r2,r3 / and also to r3
 23032 00005B71 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
 23033                              <1> 		; bis $177000,r3 / set bits 9,...,15 of file offset in r3
 23034 00005B77 81E7FF010000        <1> 	and	edi, 1FFh
 23035                              <1> 		; bic $!777,r2 / calculate file offset mod 512.
 23036 00005B7D 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
 23037                              <1> 		; add r5,r2 / r2 now points to 1st byte in system buffer
 23038                              <1> 			  ; / where data is to be placed
 23039                              <1>                 ; mov u.base,r1 / address of data is in r1
 23040 00005B7F F7D9                <1> 	neg	ecx
 23041                              <1> 		; neg r3 / 512 - file offset (mod512.) in r3 
 23042                              <1> 		       ; / (i.e., the no. of free bytes in the file block)
 23043 00005B81 3B0D[20700000]      <1> 	cmp	ecx, [u.count]
 23044                              <1> 		; cmp r3,u.count / compare this with the no. of data bytes
 23045                              <1> 			       ; / to be written to the file
 23046 00005B87 7606                <1> 	jna	short sioreg_0
 23047                              <1> 		; blos	2f / if less than branch. Use the no. of free bytes
 23048                              <1> 			 ; / in the file block as the number to be written
 23049 00005B89 8B0D[20700000]      <1> 	mov	ecx, [u.count]
 23050                              <1> 		; mov u.count,r3 / if greater than, use the no. of data 
 23051                              <1> 			       ; / bytes as the number to be written
 23052                              <1> sioreg_0:
 23053                              <1> 	; 17/06/2015
 23054 00005B8F 803D[68700000]00    <1> 	cmp	byte [u.kcall], 0 
 23055 00005B96 7613                <1> 	jna	short sioreg_1
 23056                              <1> 	; 25/07/2015
 23057                              <1> 	 ; the caller is 'mkdir' or 'namei'
 23058 00005B98 A1[1C700000]        <1> 	mov	eax, [u.base] ; 25/07/2015
 23059 00005B9D A3[60700000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
 23060 00005BA2 66890D[64700000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
 23061 00005BA9 EB0B                <1> 	jmp	short sioreg_2
 23062                              <1> sioreg_1:
 23063                              <1> 	; 25/07/2015
 23064                              <1> 	; 18/07/2015
 23065                              <1> 	; 09/06/2015 
 23066 00005BAB 0FB715[64700000]    <1> 	movzx	edx, word [u.pcount]
 23067                              <1> 		; ecx and [u.pcount] are always > 0, here
 23068 00005BB2 39D1                <1> 	cmp	ecx, edx	
 23069 00005BB4 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
 23070                              <1> sioreg_2: ; 2:
 23071 00005BB6 31C0                <1> 	xor 	eax, eax ; 25/07/2015
 23072                              <1> sioreg_3:
 23073 00005BB8 010D[24700000]      <1> 	add 	[u.nread], ecx
 23074                              <1> 		; add r3,u.nread / r3 + number of bytes xmitted 
 23075                              <1> 			         ; / during write is put into u.nread
 23076 00005BBE 290D[20700000]      <1> 	sub 	[u.count], ecx
 23077                              <1> 		; sub r3,u.count / u.count = no. of bytes that still 
 23078                              <1> 			       ; / must be written or read
 23079 00005BC4 010D[1C700000]      <1> 	add 	[u.base], ecx
 23080                              <1> 		; add r3,u.base / u.base points to the 1st of the remaining
 23081                              <1> 			      ; / data bytes
 23082 00005BCA 010E                <1>         add 	[esi], ecx 
 23083                              <1> 		; add r3,*u.fofp / new file offset = number of bytes done
 23084                              <1> 			       ; / + old file offset
 23085                              <1> 	; 25/07/2015
 23086 00005BCC 8B35[60700000]      <1> 	mov	esi, [u.pbase]
 23087 00005BD2 66290D[64700000]    <1> 	sub	[u.pcount], cx
 23088 00005BD9 010D[60700000]      <1> 	add	[u.pbase], ecx
 23089 00005BDF C3                  <1>         retn
 23090                              <1> 		; rts r0
 23091                              <1> 		; transfer count > [u.pcount]
 23092                              <1> sioreg_4:
 23093                              <1> 	; 25/07/2015
 23094                              <1> 	; transfer count > [u.pcount] 
 23095                              <1> 	; (ecx > edx)
 23096 00005BE0 89C8                <1> 	mov	eax, ecx
 23097 00005BE2 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
 23098 00005BE4 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
 23099 00005BE6 EBD0                <1> 	jmp	short sioreg_3
 23100                              <1> 
 23101                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23102                              <1> is_regular_file:
 23103                              <1> 	; check if it is a regular file or device file inode
 23104                              <1> 	;
 23105                              <1> 	; INPUT:
 23106                              <1> 	;	current inode
 23107                              <1> 	; OUTPUT:
 23108                              <1> 	;	cf = 0 and zf = 1 -> regular file
 23109                              <1> 	;	cf = 0 and zf = 0 -> device file
 23110                              <1> 	;	cf = 1 -> invalid file (jump to 'error')
 23111                              <1> 	;
 23112                              <1> 	; Modified registers: ecx (cl)
 23113                              <1> 
 23114                              <1> 	; 28/11/2021
 23115 00005BE8 8A0D[916C0000]      <1> 	mov	cl, [i.flgs+1]
 23116 00005BEE F6C180              <1> 	test	cl, 80h		; regular file ?
 23117 00005BF1 7514                <1> 	jnz	short isregf_1  ; yes 
 23118 00005BF3 80E120              <1> 	and	cl, 20h 	; device file ?
 23119 00005BF6 7511                <1> 	jnz	short isregf_2  ; yes 
 23120                              <1> 
 23121                              <1> 	; 28/11/2021
 23122                              <1> 	; invalid inode/file type !
 23123 00005BF8 C705[6A700000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
 23124 00005C00 0000                <1>
 23125                              <1> 	;stc
 23126                              <1> 	;retn
 23127 00005C02 E96BE0FFFF          <1> 	jmp	error
 23128                              <1> isregf_1:
 23129 00005C07 30C9                <1> 	xor	cl, cl  ; cl = 0
 23130                              <1> 	; zf = 1
 23131                              <1> 	;retn
 23132                              <1> isregf_2:
 23133                              <1> 	; zf = 0
 23134                              <1> 	; cl = 20h
 23135 00005C09 C3                  <1> 	retn	
 23136                                  %include 'u7.s'        ; 18/04/2015
 23137                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS7.INC
 23138                              <1> ; Last Modification: 14/11/2015
 23139                              <1> ; ----------------------------------------------------------------------------
 23140                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 23141                              <1> ; (v0.1 - Beginning: 11/07/2012)
 23142                              <1> ;
 23143                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 23144                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 23145                              <1> ; <Bell Laboratories (17/3/1972)>
 23146                              <1> ; <Preliminary Release of UNIX Implementation Document>
 23147                              <1> ;
 23148                              <1> ; Retro UNIX 8086 v1 - U7.ASM (13/07/2014) //// UNIX v1 -> u7.s
 23149                              <1> ;
 23150                              <1> ; ****************************************************************************
 23151                              <1> 
 23152                              <1> sysmount: ; / mount file system; args special; name
 23153                              <1> 	; 14/11/2015
 23154                              <1> 	; 24/10/2015
 23155                              <1> 	; 13/10/2015
 23156                              <1> 	; 10/07/2015
 23157                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 23158                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 23159                              <1> 	;
 23160                              <1> 	; 'sysmount' anounces to the system that a removable 
 23161                              <1> 	; file system has been mounted on a special file.
 23162                              <1> 	; The device number of the special file is obtained via
 23163                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
 23164                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
 23165                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
 23166                              <1> 	; to read file system into core, i.e. the first block on the
 23167                              <1> 	; mountable file system is read in. This block is super block
 23168                              <1> 	; for the file system. This call is super user restricted.	
 23169                              <1> 	;
 23170                              <1> 	; Calling sequence:
 23171                              <1> 	;	sysmount; special; name
 23172                              <1> 	; Arguments:
 23173                              <1> 	;	special - pointer to name of special file (device)
 23174                              <1> 	;	name -  pointer to name of the root directory of the
 23175                              <1> 	;		newly mounted file system. 'name' should 
 23176                              <1> 	;		always be a directory.
 23177                              <1> 	; Inputs: - 
 23178                              <1> 	; Outputs: -
 23179                              <1> 	; ...............................................................
 23180                              <1> 	;				
 23181                              <1> 	; Retro UNIX 8086 v1 modification: 
 23182                              <1> 	;       'sysmount' system call has two arguments; so,
 23183                              <1> 	;	* 1st argument, special is pointed to by BX register
 23184                              <1> 	;	* 2nd argument, name is in CX register
 23185                              <1> 	;
 23186                              <1> 	;	NOTE: Device numbers, names and related procedures are 
 23187                              <1> 	;	       already modified for IBM PC compatibility and 
 23188                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
 23189                              <1> 	
 23190                              <1> 	;call	arg2
 23191                              <1> 		; jsr r0,arg2 / get arguments special and name
 23192 00005C0A 891D[10700000]      <1> 	mov	[u.namep], ebx
 23193 00005C10 51                  <1> 	push	ecx ; directory name
 23194 00005C11 66833D[E06F0000]00  <1> 	cmp	word [mnti], 0
 23195                              <1> 		; tst mnti / is the i-number of the cross device file
 23196                              <1> 			 ; / zero?
 23197                              <1> 	;ja	error
 23198                              <1>         	; bne errora / no, error
 23199 00005C19 0F87E9000000        <1> 	ja	sysmnt_err0
 23200                              <1> 	;
 23201 00005C1F E8CC000000          <1> 	call	getspl
 23202                              <1> 		; jsr r0,getspl / get special files device number in r1
 23203                              <1> 	; 13/10/2015
 23204 00005C24 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
 23205 00005C27 F683[3A6A0000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
 23206 00005C2E 750F                <1> 	jnz	short sysmnt_1
 23207                              <1> sysmnt_err1:
 23208 00005C30 C705[6A700000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
 23209 00005C38 0000                <1>
 23210 00005C3A E933E0FFFF          <1> 	jmp	error
 23211                              <1> sysmnt_1:
 23212 00005C3F 8F05[10700000]      <1> 	pop	dword [u.namep]
 23213                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
 23214                              <1> 				  ; / on the device
 23215                              <1> 	; 14/11/2015
 23216 00005C45 53                  <1> 	push	ebx ; 13/10/2015
 23217                              <1> 		; mov r1,-(sp) / save the device number
 23218                              <1>         ;
 23219 00005C46 E8E5EEFFFF          <1> 	call	namei
 23220                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 23221                              <1> 		       ; ax = 0 -> file not found 	
 23222                              <1> 	;jz	error
 23223                              <1> 	;jc	error
 23224                              <1> 		; jsr r0,namei / get the i-number of the file
 23225                              <1>                	; br errora
 23226 00005C4B 730F                <1> 	jnc	short sysmnt_2
 23227                              <1> sysmnt_err2:
 23228 00005C4D C705[6A700000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
 23229 00005C55 0000                <1>
 23230 00005C57 E916E0FFFF          <1> 	jmp	error
 23231                              <1> sysmnt_2:	
 23232 00005C5C 66A3[E06F0000]      <1> 	mov	[mnti], ax
 23233                              <1>         	; mov r1,mnti / put it in mnti
 23234                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
 23235                              <1> sysmnt_3: ;1:
 23236                              <1>         ;cmp	byte [ebx+1], 0
 23237                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
 23238                              <1> 			   ; / dismountable device set?
 23239                              <1>         ;jna	short sysmnt_4		
 23240                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
 23241                              <1> 	;call	idle 	; (wait for hardware interrupt)
 23242                              <1> 	;jmp	short sysmnt_3
 23243                              <1> sysmnt_4:   
 23244 00005C62 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
 23245 00005C63 A2[D76F0000]        <1> 	mov	[mdev], al
 23246                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
 23247 00005C68 8803                <1> 	mov	[ebx], al
 23248                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
 23249                              <1> 			      ; / of the I/O queue entry
 23250                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
 23251                              <1>         	; mov (sp)+,cdev / put device number in cdev
 23252 00005C6A 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
 23253                              <1> 		; bis $2000,sb1 / set the read bit
 23254                              <1> 	; Retro UNIX 386 v1 modification : 
 23255                              <1> 	;	32 bit block number at buffer header offset 4
 23256 00005C6F C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
 23257 00005C76 E8AA050000          <1> 	call 	diskio
 23258 00005C7B 731C                <1> 	jnc	short sysmnt_5
 23259 00005C7D 31C0                <1> 	xor 	eax, eax
 23260 00005C7F 66A3[E06F0000]      <1> 	mov	[mnti], ax ; 0
 23261 00005C85 A2[D76F0000]        <1> 	mov	[mdev], al ; 0
 23262                              <1> 	;mov	[cdev], al ; 0
 23263                              <1> sysmnt_invd:
 23264                              <1> 	; 14/11/2015
 23265 00005C8A FEC8                <1> 	dec 	al
 23266 00005C8C 8903                <1> 	mov	[ebx], eax ; 000000FFh
 23267 00005C8E FEC0                <1> 	inc	al
 23268 00005C90 48                  <1> 	dec	eax
 23269 00005C91 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
 23270 00005C94 E9D9DFFFFF          <1> 	jmp	error
 23271                              <1> sysmnt_5:
 23272                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
 23273                              <1> 	; (Following check is needed to prevent mounting an
 23274                              <1> 	; in valid valid file system (in valid super block).
 23275                              <1> 	; 
 23276 00005C99 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
 23277 00005C9C C0E002              <1> 	shl	al, 2 ; 4*index
 23278 00005C9F 8B88[1E6A0000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
 23279 00005CA5 C1E103              <1> 	shl 	ecx, 3
 23280 00005CA8 0FB715[6C7F0000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
 23281 00005CAF 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
 23282                              <1> 			 ; (in sectors), if they are not equal
 23283                              <1> 			 ; the disk to be mounted is an...	
 23284 00005CB1 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
 23285                              <1> 			 ; (which has not got a valid super block)
 23286                              <1> 	;
 23287 00005CB3 C6430100            <1> 	mov	byte [ebx+1], 0
 23288                              <1> 	       	; jsr r0,ppoke / read in entire file system
 23289                              <1> ;sysmnt_6: ;1:
 23290                              <1> 	;;cmp	byte [sb1+1], 0
 23291                              <1> 		; tstb   sb1+1 / done reading?
 23292                              <1>    	;;jna	sysret
 23293                              <1> 	;;call	idle ; (wait for hardware interrupt)
 23294                              <1> 	;;jmp	short sysmnt_6
 23295                              <1> 		;bne 1b / no, wait
 23296                              <1>         	;br sysreta / yes
 23297 00005CB7 E9D6DFFFFF          <1> 	jmp	sysret
 23298                              <1> 
 23299                              <1> sysumount: ; / special dismount file system
 23300                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 23301                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 23302                              <1> 	;
 23303                              <1> 	; 04/11/2013
 23304                              <1> 	; 09/07/2013
 23305                              <1> 	; 'sysumount' anounces to the system that the special file, 
 23306                              <1> 	; indicated as an argument is no longer contain a removable
 23307                              <1> 	; file system. 'getspl' gets the device number of the special
 23308                              <1> 	; file. If no file system was mounted on that device an error
 23309                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
 23310                              <1> 	; to 'sysret'.
 23311                              <1> 	;
 23312                              <1> 	; Calling sequence:
 23313                              <1> 	;	sysmount; special
 23314                              <1> 	; Arguments:
 23315                              <1> 	;	special - special file to dismount (device)
 23316                              <1> 	;
 23317                              <1> 	; Inputs: - 
 23318                              <1> 	; Outputs: -
 23319                              <1> 	; ...............................................................
 23320                              <1> 	;				
 23321                              <1> 	; Retro UNIX 8086 v1 modification: 
 23322                              <1> 	;       'sysumount' system call has one argument; so,
 23323                              <1> 	;	* Single argument, special is pointed to by BX register
 23324                              <1> 	;
 23325                              <1> 	
 23326                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
 23327                              <1> 	;call	arg
 23328                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
 23329 00005CBC 891D[10700000]      <1>         mov	[u.namep], ebx
 23330 00005CC2 E829000000          <1> 	call	getspl
 23331                              <1> 		; jsr r0,getspl / get the device number in r1
 23332 00005CC7 3A05[D76F0000]      <1> 	cmp	al, [mdev]
 23333                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
 23334 00005CCD 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
 23335                              <1> 	;jne	error
 23336                              <1>         	; bne errora / no error
 23337 00005CCF 30C0                <1> 	xor	al, al ; ah = 0
 23338                              <1> sysumnt_0: ;1:
 23339 00005CD1 3805[697F0000]      <1>      	cmp 	[sb1+1], al ; 0
 23340                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
 23341                              <1> 			   ; / (inhibit bit set)?
 23342 00005CD7 7607                <1> 	jna	short sysumnt_1		
 23343                              <1> 		; bne 1b / yes, wait
 23344 00005CD9 E8B2F3FFFF          <1> 	call	idle ; (wait for hardware interrupt)
 23345 00005CDE EBF1                <1> 	jmp	short sysumnt_0
 23346                              <1> sysumnt_1:        
 23347 00005CE0 A2[D76F0000]        <1> 	mov	[mdev], al
 23348                              <1> 	     	; clr mntd / no, clear these
 23349 00005CE5 66A3[E06F0000]      <1>    	mov	[mnti], ax
 23350                              <1>         	; clr mnti
 23351 00005CEB E9A2DFFFFF          <1>         jmp	sysret
 23352                              <1> 		; br sysreta / return
 23353                              <1> 
 23354                              <1> getspl: ; / get device number from a special file name
 23355 00005CF0 E83BEEFFFF          <1> 	call	namei
 23356                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 23357                              <1> 		       ; ax = 0 -> file not found 	
 23358 00005CF5 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
 23359                              <1> 	;jz	error
 23360                              <1> 	;jc	error
 23361                              <1> 		; jsr r0,namei / get the i-number of the special file
 23362                              <1>                 ; br errora / no such file
 23363 00005CFB 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
 23364                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
 23365                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
 23366 00005CFF 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
 23367                              <1> 	;jc	error
 23368                              <1> 		; ble errora / less than 0?  yes, error
 23369 00005D01 6683F805            <1>         cmp	ax, 5 ;
 23370                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
 23371 00005D05 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
 23372                              <1> 	;ja	error
 23373                              <1>         	; bgt errora / yes, error
 23374                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
 23375                              <1> iopen_retn:
 23376 00005D07 C3                  <1> 	retn
 23377                              <1> 		; rts    r0 / return with device number in r1
 23378                              <1> sysmnt_err0:
 23379 00005D08 C705[6A700000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 23380 00005D10 0000                <1>
 23381 00005D12 E95BDFFFFF          <1> 	jmp	error
 23382                              <1> iopen:
 23383                              <1> 	; 19/05/2015
 23384                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 23385                              <1> 	; 21/05/2013 - 27/08/2013 (Retro UNIX 8086 v1)
 23386                              <1> 	;
 23387                              <1> 	; open file whose i-number is in r1
 23388                              <1> 	; 
 23389                              <1> 	; INPUTS ->
 23390                              <1> 	;    r1 - inode number
 23391                              <1> 	; OUTPUTS ->
 23392                              <1> 	;    file's inode in core	
 23393                              <1> 	;    r1 - inode number (positive)
 23394                              <1> 	;
 23395                              <1> 	; ((AX = R1))
 23396                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, edi, ebp)) 
 23397                              <1> 	;        
 23398                              <1> ; / open file whose i-number is in r1
 23399 00005D17 F6C480              <1> 	test	ah, 80h ; Bit 15 of AX
 23400                              <1> 		;tst r1 / write or read access?
 23401 00005D1A 756A                <1>         jnz	short iopen_2
 23402                              <1> 		;blt 2f / write, go to 2f
 23403 00005D1C B202                <1> 	mov	dl, 2 ; read access
 23404 00005D1E E89DF8FFFF          <1> 	call	access
 23405                              <1>         	; jsr r0,access; 2 
 23406                              <1> 	; / get inode into core with read access
 23407                              <1> 	; DL=2
 23408                              <1> iopen_0:
 23409 00005D23 6683F828            <1>         cmp	ax, 40
 23410                              <1> 		; cmp r1,$40. / is it a special file
 23411 00005D27 77DE                <1>         ja	short iopen_retn
 23412                              <1> 		;bgt  3f / no. 3f
 23413 00005D29 6650                <1> 	push	ax
 23414                              <1> 		; mov r1,-(sp) / yes, figure out
 23415 00005D2B 0FB6D8              <1> 	movzx	ebx, al
 23416 00005D2E 66C1E302            <1> 	shl	bx, 2
 23417                              <1> 		; asl r1
 23418 00005D32 81C3[365D0000]      <1>         add     ebx, iopen_1 - 4
 23419 00005D38 FF23                <1> 	jmp	dword [ebx]
 23420                              <1>         	; jmp *1f-2(r1) / which one and transfer to it
 23421                              <1> iopen_1: ; 1:
 23422 00005D3A [A05D0000]          <1> 	dd	otty ; tty, AX = 1 (runix)
 23423                              <1>  		 ;otty / tty ; r1=2
 23424                              <1>         	 ;oppt / ppt ; r1=4
 23425 00005D3E [3D5E0000]          <1> 	dd	sret ; mem, AX = 2 (runix)
 23426                              <1> 		 ;sret / mem ; r1=6
 23427                              <1> 		 ;sret / rf0
 23428                              <1>         	 ;sret / rk0
 23429                              <1>         	 ;sret / tap0
 23430                              <1>         	 ;sret / tap1
 23431                              <1>         	 ;sret / tap2
 23432                              <1>         	 ;sret / tap3
 23433                              <1>         	 ;sret / tap4
 23434                              <1>         	 ;sret / tap5
 23435                              <1>         	 ;sret / tap6
 23436                              <1>         	 ;sret / tap7
 23437 00005D42 [3D5E0000]          <1>         dd	sret ; fd0, AX = 3 (runix only)
 23438 00005D46 [3D5E0000]          <1>         dd	sret ; fd1, AX = 4 (runix only)
 23439 00005D4A [3D5E0000]          <1>         dd	sret ; hd0, AX = 5 (runix only)
 23440 00005D4E [3D5E0000]          <1>         dd	sret ; hd1, AX = 6 (runix only) 
 23441 00005D52 [3D5E0000]          <1>         dd	sret ; hd2, AX = 7 (runix only)
 23442 00005D56 [3D5E0000]          <1>         dd	sret ; hd3, AX = 8 (runix only) 
 23443                              <1> 	;dd	error ; lpr, AX = 9 (error !)
 23444 00005D5A [3D5E0000]          <1>         dd      sret ; lpr, AX = 9 (runix)
 23445 00005D5E [AF5D0000]          <1> 	dd	ocvt ; tty0, AX = 10 (runix)	  
 23446                              <1> 		 ;ocvt / tty0
 23447 00005D62 [AF5D0000]          <1> 	dd	ocvt ; tty1, AX = 11 (runix)	  
 23448                              <1> 		 ;ocvt / tty1
 23449 00005D66 [AF5D0000]          <1> 	dd	ocvt ; tty2, AX = 12 (runix)	  
 23450                              <1> 		 ;ocvt / tty2
 23451 00005D6A [AF5D0000]          <1> 	dd	ocvt ; tty3, AX = 13 (runix)	  
 23452                              <1> 		 ;ocvt / tty3
 23453 00005D6E [AF5D0000]          <1> 	dd	ocvt ; tty4, AX = 14 (runix)	  
 23454                              <1> 		 ;ocvt / tty4
 23455 00005D72 [AF5D0000]          <1> 	dd	ocvt ; tty5, AX = 15 (runix)	  
 23456                              <1> 		 ;ocvt / tty5
 23457 00005D76 [AF5D0000]          <1> 	dd	ocvt ; tty6, AX = 16 (runix)	  
 23458                              <1> 		 ;ocvt / tty6
 23459 00005D7A [AF5D0000]          <1> 	dd	ocvt ; tty7, AX = 17 (runix)	  
 23460                              <1> 		 ;ocvt / tty7
 23461 00005D7E [AF5D0000]          <1> 	dd	ocvt ; COM1, AX = 18 (runix only)	  
 23462                              <1> 		 ;error / crd
 23463 00005D82 [AF5D0000]          <1> 	dd	ocvt ; COM2, AX = 19 (runix only)
 23464                              <1> 
 23465                              <1> iopen_2: ; 2: / check open write access
 23466 00005D86 66F7D8              <1> 	neg	ax
 23467                              <1> 		;neg r1 / make inode number positive
 23468 00005D89 B201                <1> 	mov	dl, 1 ; write access
 23469 00005D8B E830F8FFFF          <1> 	call	access
 23470                              <1> 		;jsr r0,access; 1 / get inode in core
 23471                              <1> 	; DL=1
 23472 00005D90 66F705[906C0000]00- <1> 	test	word [i.flgs], 4000h ; Bit 14 : Directory flag
 23473 00005D98 40                  <1>
 23474                              <1>  		;bit $40000,i.flgs / is it a directory?
 23475 00005D99 7488                <1> 	jz	short iopen_0
 23476                              <1> 	;mov	[u.error], ERR_DIR_ACCESS
 23477                              <1> 	;jmp	error ; permission denied !
 23478 00005D9B E968FFFFFF          <1> 	jmp	sysmnt_err0
 23479                              <1> 	;;jnz	error		
 23480                              <1>        		; bne 2f / yes, transfer (error)
 23481                              <1>         ;;jmp     short iopen_0
 23482                              <1> 	;cmp	ax, 40
 23483                              <1> 		; cmp r1,$40. / no, is it a special file?
 23484                              <1>         ;ja	short iopen_2
 23485                              <1> 		 ;bgt 3f / no, return
 23486                              <1> 	;push	ax
 23487                              <1> 		;mov r1,-(sp) / yes
 23488                              <1> 	;movzx	ebx, al
 23489                              <1> 	;shl	bx, 1
 23490                              <1> 		; asl r1
 23491                              <1> 	;add	ebx, ipen_3 - 2
 23492                              <1> 	;jmp	dword [ebx]
 23493                              <1> 		; jmp *1f-2(r1) / figure out 
 23494                              <1> 			; / which special file it is and transfer
 23495                              <1> ;iopen_3: ; 1:
 23496                              <1> ;	dd 	otty ; tty, AX = 1 (runix)
 23497                              <1>  		 ;otty / tty ; r1=2
 23498                              <1>         	 ;leadr / ppt ; r1=4
 23499                              <1> ;	dd	sret ; mem, AX = 2 (runix)
 23500                              <1> 		 ;sret / mem ; r1=6
 23501                              <1> 		 ;sret / rf0
 23502                              <1>         	 ;sret / rk0
 23503                              <1>         	 ;sret / tap0
 23504                              <1>         	 ;sret / tap1
 23505                              <1>         	 ;sret / tap2
 23506                              <1>         	 ;sret / tap3
 23507                              <1>         	 ;sret / tap4
 23508                              <1>         	 ;sret / tap5
 23509                              <1>         	 ;sret / tap6
 23510                              <1>         	 ;sret / tap7
 23511                              <1> ;	dd 	sret ; fd0, AX = 3 (runix only)
 23512                              <1> ;	dd 	sret ; fd1, AX = 4 (runix only)
 23513                              <1> ;	dd 	sret ; hd0, AX = 5 (runix only)
 23514                              <1> ;	dd 	sret ; hd1, AX = 6 (runix only)	
 23515                              <1> ;	dd 	sret ; hd2, AX = 7 (runix only)
 23516                              <1> ;	dd 	sret ; hd3, AX = 8 (runix only)	
 23517                              <1> ;	dd	sret ; lpr, AX = 9  (runix)
 23518                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 23519                              <1> ;	dd	sret ; tty0, AX = 10 (runix)	  
 23520                              <1> 		 ;ocvt / tty0
 23521                              <1> ;	dd	sret ; tty1, AX = 11 (runix)	  
 23522                              <1> 		 ;ocvt / tty1
 23523                              <1> ;	dd	sret ; tty2, AX = 12 (runix)	  
 23524                              <1> 		 ;ocvt / tty2
 23525                              <1> ;	dd	sret ; tty3, AX = 13 (runix)	  
 23526                              <1> 		 ;ocvt / tty3
 23527                              <1> ;	dd	sret ; tty4, AX = 14 (runix)	  
 23528                              <1> 		 ;ocvt / tty4
 23529                              <1> ;	dd	sret ; tty5, AX = 15 (runix)	  
 23530                              <1> 		 ;ocvt / tty5
 23531                              <1> ;	dd	sret ; tty6, AX = 16 (runix)	  
 23532                              <1> 		 ;ocvt / tty6
 23533                              <1> ;	dd	sret ; tty7, AX = 17 (runix)	  
 23534                              <1> 		 ;ocvt / tty7
 23535                              <1> ;	dd	ocvt ; COM1, AX = 18 (runix only)	  
 23536                              <1> 		 ;/ ejec / lpr
 23537                              <1> ;	dd	ocvt ; COM2, AX = 19 (runix only)
 23538                              <1> 
 23539                              <1> 
 23540                              <1> otty: ;/ open console tty for reading or writing
 23541                              <1> 	; 16/11/2015
 23542                              <1> 	; 12/11/2015
 23543                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 23544                              <1> 	; 21/05/2013 - 13/07/2014 (Retro UNIX 8086 v1)
 23545                              <1> 	; 16/07/2013
 23546                              <1> 	; Retro UNIX 8086 v1 modification:
 23547                              <1> 	;  If a tty is open for read or write by
 23548                              <1> 	;     a process (u.uno), only same process can open
 23549                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 23550                              <1> 	;
 23551                              <1> 	; (INPUT: DL=2 for Read, DL=1 for Write, DL=0 for sysstty)
 23552                              <1> 	;
 23553 00005DA0 0FB61D[49700000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 23554 00005DA7 8A83[2F6D0000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 23555                              <1> 	; 13/01/2014
 23556 00005DAD EB02                <1> 	jmp	short ottyp
 23557                              <1> ocvt:
 23558 00005DAF 2C0A                <1> 	sub	al, 10
 23559                              <1> ottyp:
 23560                              <1> 	; 16/11/2015
 23561                              <1> 	; 12/11/2015
 23562                              <1> 	; 18/05/2015 (32 bit modifications)
 23563                              <1> 	; 06/12/2013 - 13/07/2014
 23564 00005DB1 88C6                <1> 	mov	dh, al ; tty number
 23565 00005DB3 0FB6D8              <1> 	movzx 	ebx, al ; AL = tty number (0 to 9), AH = 0
 23566 00005DB6 D0E3                <1> 	shl 	bl, 1  ; aligned to word
 23567                              <1> 	;26/01/2014	
 23568 00005DB8 81C3[446F0000]      <1> 	add 	ebx, ttyl
 23569 00005DBE 668B0B              <1> 	mov 	cx, [ebx]
 23570                              <1> 		   ; CL = lock value (0 or process number)
 23571                              <1> 		   ; CH = open count 
 23572 00005DC1 20C9                <1> 	and 	cl, cl
 23573                              <1> 	; 13/01/2014
 23574 00005DC3 7439                <1> 	jz 	short otty_ret
 23575                              <1> 	;
 23576                              <1> 	; 16/11/2015
 23577 00005DC5 3A0D[49700000]      <1> 	cmp 	cl, [u.uno]
 23578 00005DCB 745C                <1> 	je	short ottys_3
 23579                              <1> 	;
 23580 00005DCD 0FB6D9              <1> 	movzx 	ebx, cl ; the process which has locked the tty
 23581 00005DD0 D0E3                <1> 	shl 	bl, 1
 23582 00005DD2 668B83[CE6C0000]    <1> 	mov 	ax, [ebx+p.pid-2]
 23583                              <1> 	;movzx 	ebx, byte [u.uno]
 23584 00005DD9 8A1D[49700000]      <1> 	mov	bl, [u.uno]
 23585 00005DDF D0E3                <1> 	shl 	bl, 1
 23586 00005DE1 663B83[EE6C0000]    <1> 	cmp 	ax, [ebx+p.ppid-2]
 23587 00005DE8 743F                <1> 	je 	short ottys_3  ; 16/11/2015
 23588                              <1> 	;
 23589                              <1> 	; the tty is locked by another process
 23590                              <1> 	; except the parent process (p.ppid)
 23591                              <1>         ;
 23592 00005DEA C705[6A700000]0B00- <1> 	mov     dword [u.error], ERR_DEV_ACCESS
 23593 00005DF2 0000                <1>
 23594                              <1> 			; permission denied ! error
 23595                              <1> otty_err: ; 13/01/2014
 23596 00005DF4 08D2                <1> 	or 	dl, dl ; DL = 0 -> called by sysstty
 23597 00005DF6 0F8576DEFFFF        <1> 	jnz	error
 23598 00005DFC F9                  <1> 	stc
 23599 00005DFD C3                  <1> 	retn
 23600                              <1> otty_ret: 
 23601                              <1> 	; 13/01/2014
 23602 00005DFE 80FE07              <1> 	cmp 	dh, 7
 23603 00005E01 761C                <1> 	jna	short ottys_2
 23604                              <1> 	; 16/11/2015
 23605                              <1> com_port_check:
 23606 00005E03 BE[626F0000]        <1> 	mov	esi, com1p
 23607 00005E08 80FE08              <1> 	cmp	dh, 8	; COM1 (tty8) ?
 23608 00005E0B 7601                <1> 	jna	short ottys_1 ; yes, it is COM1
 23609 00005E0D 46                  <1> 	inc	esi	; no, it is COM2 (tty9)
 23610                              <1> ottys_1:
 23611                              <1> 	; 12/11/2015
 23612 00005E0E 803E00              <1> 	cmp	byte [esi], 0 ; E3h (or 23h)
 23613 00005E11 770C                <1> 	ja	short com_port_ready
 23614                              <1> 	;
 23615 00005E13 C705[6A700000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY
 23616 00005E1B 0000                <1>
 23617                              <1> 			   ; device not ready ! error
 23618 00005E1D EBD5                <1> 	jmp	short otty_err	 
 23619                              <1> com_port_ready:
 23620                              <1> ottys_2:
 23621 00005E1F 08C9                <1> 	or	cl, cl  ; cl = lock/owner, ch = open count
 23622 00005E21 7506                <1> 	jnz	short ottys_3
 23623 00005E23 8A0D[49700000]      <1> 	mov	cl, [u.uno]
 23624                              <1> ottys_3:
 23625 00005E29 FEC5                <1> 	inc 	ch
 23626 00005E2B 66890B              <1> 	mov 	[ebx], cx ; set tty lock again
 23627                              <1> 	; 06/12/2013
 23628 00005E2E FEC6                <1> 	inc	dh ; tty number + 1
 23629 00005E30 BB[2E700000]        <1> 	mov	ebx, u.ttyp
 23630                              <1> 	; 13/01/2014
 23631 00005E35 F6C202              <1> 	test	dl, 2 ; open for read sign
 23632 00005E38 7501                <1> 	jnz	short ottys_4
 23633 00005E3A 43                  <1> 	inc	ebx
 23634                              <1> ottys_4:
 23635                              <1> 	; Set 'u.ttyp' ('the recent TTY') value
 23636 00005E3B 8833                <1> 	mov 	[ebx], dh ; tty number + 1
 23637                              <1> sret:
 23638 00005E3D 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 23639 00005E3F 7402                <1> 	jz	short iclose_retn
 23640 00005E41 6658                <1> 	pop 	ax
 23641                              <1> iclose_retn:	
 23642 00005E43 C3                  <1> 	retn
 23643                              <1> 
 23644                              <1> 	;
 23645                              <1> 	; Original UNIX v1 'otty' routine:
 23646                              <1> 	;	
 23647                              <1> 	;mov    $100,*$tks / set interrupt enable bit (zero others) in
 23648                              <1>         ;                 / reader status reg
 23649                              <1>         ;mov    $100,*$tps / set interrupt enable bit (zero others) in
 23650                              <1>         ;                 / punch status reg
 23651                              <1>         ;mov    tty+[ntty*8]-8+6,r5 / r5 points to the header of the
 23652                              <1>         ;                          / console tty buffer
 23653                              <1>         ;incb   (r5) / increment the count of processes that opened the
 23654                              <1>         ;            / console tty
 23655                              <1>         ;tst    u.ttyp / is there a process control tty (i.e., has a tty
 23656                              <1>         ;             / buffer header
 23657                              <1>         ;bne    sret / address been loaded into u.ttyp yet)?  yes, branch
 23658                              <1>         ;mov    r5,u.ttyp / no, make the console tty the process control
 23659                              <1>         ;                 / tty
 23660                              <1>         ;br     sret / ?
 23661                              <1> ;sret:
 23662                              <1> 		;clr *$ps / set processor priority to zero
 23663                              <1> ;	pop	ax
 23664                              <1>         	;mov (sp)+,r1 / pop stack to r1
 23665                              <1> ;3:
 23666                              <1> ;	retn
 23667                              <1>         	;rts r0
 23668                              <1> 	
 23669                              <1> ;ocvt:	; < open tty >
 23670                              <1> 	; 13/01/2014
 23671                              <1> 	; 06/12/2013 (major modification: p.ttyc, u.ttyp)
 23672                              <1> 	; 24/09/2013 consistency check -> ok
 23673                              <1> 	; 16/09/2013
 23674                              <1> 	; 03/09/2013
 23675                              <1> 	; 27/08/2013
 23676                              <1> 	; 16/08/2013
 23677                              <1> 	; 16/07/2013
 23678                              <1> 	; 27/05/2013
 23679                              <1> 	; 21/05/2013
 23680                              <1> 	;
 23681                              <1> 	; Retro UNIX 8086 v1 modification !
 23682                              <1> 	; 
 23683                              <1> 	; In original UNIX v1, 'ocvt' routine 
 23684                              <1> 	;		(exactly different than this one)
 23685                              <1> 	;	was in 'u9.s' file.
 23686                              <1> 	;
 23687                              <1> 	; 16/07/2013
 23688                              <1> 	; Retro UNIX 8086 v1 modification:
 23689                              <1> 	;  If a tty is open for read or write by
 23690                              <1> 	;     a process (u.uno), only same process can open
 23691                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 23692                              <1> 	;
 23693                              <1> 	; INPUT: DL=2 for Read DL=1 for Write
 23694                              <1> 
 23695                              <1> 	; 16/09/2013
 23696                              <1> 	; sub 	al, 10
 23697                              <1> 	
 23698                              <1> 	; 06/12/2013
 23699                              <1> 	;cmp	al, 7
 23700                              <1>         ;jna     short ottyp
 23701                              <1> 	; 13/01/2014
 23702                              <1> 	;jmp	short ottyp
 23703                              <1> 
 23704                              <1> 
 23705                              <1> ;oppt: / open paper tape for reading or writing
 23706                              <1> ;        mov    $100,*$prs / set reader interrupt enable bit
 23707                              <1> ;        tstb   pptiflg / is file already open
 23708                              <1> ;        bne    2f / yes, branch
 23709                              <1> ;1:
 23710                              <1> ;        mov    $240,*$ps / no, set processor priority to 5
 23711                              <1> ;        jsr    r0,getc; 2 / remove all entries in clist
 23712                              <1> ;               br .+4 / for paper tape input and place in free list
 23713                              <1> ;        br     1b
 23714                              <1> ;        movb   $2,pptiflg / set pptiflg to indicate file just open
 23715                              <1> ;        movb   $10.,toutt+1 / place 10 in paper tape input tout entry
 23716                              <1> ;        br     sret
 23717                              <1> ;2:
 23718                              <1> ;        jmp    error / file already open
 23719                              <1> 
 23720                              <1> iclose: 
 23721                              <1> 	; 19/05/2015
 23722                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 23723                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 23724                              <1> 	;
 23725                              <1> 	; close file whose i-number is in r1
 23726                              <1> 	; 
 23727                              <1> 	; INPUTS ->
 23728                              <1> 	;    r1 - inode number
 23729                              <1> 	; OUTPUTS ->
 23730                              <1> 	;    file's inode in core	
 23731                              <1> 	;    r1 - inode number (positive)
 23732                              <1> 	;
 23733                              <1> 	; ((AX = R1))
 23734                              <1>         ;    ((Modified registers: -ebx-, edx)) 
 23735                              <1> 	;        
 23736                              <1> ;/ close file whose i-number is in r1
 23737 00005E44 B202                <1> 	mov	dl, 2 ; 12/01/2014
 23738 00005E46 F6C480              <1> 	test	ah, 80h ; Bit 15 of AX
 23739                              <1> 		;tst r1 / test i-number
 23740                              <1>         ;jnz	short iclose_2
 23741                              <1> 		;blt 2f / if neg., branch
 23742 00005E49 7405                <1> 	jz	short iclose_0 ; 30/07/2013
 23743                              <1> 	; 16/07/2013 
 23744 00005E4B 66F7D8              <1> 	neg	ax ; make it positive
 23745                              <1> 	; 12/01/2014
 23746 00005E4E FECA                <1> 	dec	dl ; dl = 1 (open for write)
 23747                              <1> iclose_0:
 23748 00005E50 6683F828            <1> 	cmp	ax, 40
 23749                              <1> 		;cmp r1,$40. / is it a special file
 23750 00005E54 77ED                <1>         ja	short iclose_retn  ; 13/01/2014
 23751                              <1> 		;bgt 3b / no, return
 23752                              <1> 	; 12/01/2014
 23753                              <1> 	; DL=2 -> special file was opened for reading
 23754                              <1> 	; DL=1 -> special file was opened for writing
 23755 00005E56 6650                <1> 	push	ax
 23756                              <1> 		;mov r1,-(sp) / yes, save r1 on stack
 23757 00005E58 0FB6D8              <1> 	movzx	ebx, al
 23758 00005E5B 66C1E302            <1> 	shl	bx, 2
 23759                              <1> 		; asl r1
 23760 00005E5F 81C3[635E0000]      <1> 	add	ebx, iclose_1 - 4
 23761 00005E65 FF23                <1> 	jmp	dword [ebx]
 23762                              <1> 		; jmp *1f-2(r1) / compute jump address and transfer
 23763                              <1> iclose_1 :
 23764 00005E67 [B35E0000]          <1> 	dd	ctty ; tty, AX = 1 (runix)
 23765 00005E6B [045F0000]          <1> 	dd	cret ; mem, AX = 2 (runix)
 23766 00005E6F [045F0000]          <1> 	dd	cret ; fd0, AX = 3 (runix only)
 23767 00005E73 [045F0000]          <1> 	dd	cret ; fd1, AX = 4 (runix only)
 23768 00005E77 [045F0000]          <1> 	dd	cret ; hd0, AX = 5 (runix only)
 23769 00005E7B [045F0000]          <1> 	dd	cret ; hd1, AX = 6 (runix only)	
 23770 00005E7F [045F0000]          <1> 	dd	cret ; hd2, AX = 7 (runix only)
 23771 00005E83 [045F0000]          <1> 	dd	cret ; hd3, AX = 8 (runix only)	
 23772 00005E87 [045F0000]          <1> 	dd	cret ; lpr, AX = 9 (runix)
 23773                              <1> 	;dd	error; lpr, AX = 9 (error !)
 23774                              <1> 	;;dd	offset ejec ;;lpr, AX = 9  
 23775 00005E8B [C25E0000]          <1> 	dd	ccvt ; tty0, AX = 10 (runix)	  
 23776 00005E8F [C25E0000]          <1> 	dd	ccvt ; tty1, AX = 11 (runix)	  
 23777 00005E93 [C25E0000]          <1> 	dd	ccvt ; tty2, AX = 12 (runix)	  
 23778 00005E97 [C25E0000]          <1> 	dd	ccvt ; tty3, AX = 13 (runix)	  
 23779 00005E9B [C25E0000]          <1> 	dd	ccvt ; tty4, AX = 14 (runix)	  
 23780 00005E9F [C25E0000]          <1> 	dd	ccvt ; tty5, AX = 15 (runix)	  
 23781 00005EA3 [C25E0000]          <1> 	dd	ccvt ; tty6, AX = 16 (runix)	  
 23782 00005EA7 [C25E0000]          <1> 	dd	ccvt ; tty7, AX = 17 (runix)	  
 23783 00005EAB [C25E0000]          <1> 	dd	ccvt ; COM1, AX = 18 (runix only)	  
 23784 00005EAF [C25E0000]          <1> 	dd	ccvt ; COM2, AX = 19 (runix only)
 23785                              <1> 
 23786                              <1> 	; 1:
 23787                              <1> 	;        ctty   / tty
 23788                              <1> 	;        cppt   / ppt
 23789                              <1> 	;        sret   / mem
 23790                              <1> 	;        sret   / rf0
 23791                              <1> 	;        sret   / rk0
 23792                              <1> 	;        sret   / tap0
 23793                              <1> 	;        sret   / tap1
 23794                              <1> 	;        sret   / tap2
 23795                              <1> 	;        sret   / tap3
 23796                              <1> 	;        sret   / tap4
 23797                              <1> 	;        sret   / tap5
 23798                              <1> 	;        sret   / tap6
 23799                              <1> 	;        sret   / tap7
 23800                              <1> 	;        ccvt   / tty0
 23801                              <1> 	;        ccvt   / tty1
 23802                              <1> 	;        ccvt   / tty2
 23803                              <1> 	;        ccvt   / tty3
 23804                              <1> 	;        ccvt   / tty4
 23805                              <1> 	;        ccvt   / tty5
 23806                              <1> 	;        ccvt   / tty6
 23807                              <1> 	;        ccvt   / tty7
 23808                              <1> 	;        error / crd
 23809                              <1> 
 23810                              <1> ;iclose_2: ; 2: / negative i-number
 23811                              <1> 	;neg	ax
 23812                              <1> 		;neg r1 / make it positive
 23813                              <1> 	;cmp	ax, 40
 23814                              <1> 		;cmp r1,$40. / is it a special file?
 23815                              <1>         ;ja	short @b
 23816                              <1> 		;bgt    3b / no. return
 23817                              <1> 	;push	ax
 23818                              <1> 		;mov r1,-(sp)
 23819                              <1> 	;movzx	ebx, al
 23820                              <1> 	;shl	bx, 1
 23821                              <1> 		;asl r1 / yes. compute jump address and transfer
 23822                              <1> 	;add	ebx, iclose_3 - 2
 23823                              <1> 	;jmp	dword [ebx]
 23824                              <1> 		;jmp *1f-2(r1) / figure out 
 23825                              <1> ;iclose_3:
 23826                              <1> 	;dd	ctty ; tty, AX = 1 (runix)
 23827                              <1> 	;dd	sret ; mem, AX = 2 (runix)
 23828                              <1> 	;dd	sret ; fd0, AX = 3 (runix only)
 23829                              <1> 	;dd	sret ; fd1, AX = 4 (runix only)
 23830                              <1> 	;dd	sret ; hd0, AX = 5 (runix only)
 23831                              <1> 	;dd	sret ; hd1, AX = 6 (runix only)	
 23832                              <1> 	;dd	sret ; hd2, AX = 7 (runix only)
 23833                              <1> 	;dd	sret ; hd3, AX = 8 (runix only)
 23834                              <1> 	 ;dd	sret ; lpr, AX = 9	
 23835                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 23836                              <1> 	;dd	ccvt ; tty0, AX = 10 (runix)	  
 23837                              <1> 	;dd	ccvt ; tty1, AX = 11 (runix)	  
 23838                              <1> 	;dd	ccvt ; tty2, AX = 12 (runix)	  
 23839                              <1> 	;dd	ccvt ; tty3, AX = 13 (runix)	  
 23840                              <1> 	;dd	ccvt ; tty4, AX = 14 (runix)	  
 23841                              <1> 	;dd	ccvt ; tty5, AX = 15 (runix)	  
 23842                              <1> 	;dd	ccvt ; tty6, AX = 16 (runix)	  
 23843                              <1> 	;dd	ccvt ; tty7, AX = 17 (runix)	  
 23844                              <1> 	;dd	ccvt ; COM1, AX = 18 (runix only)	  
 23845                              <1> 	;dd	ccvt ; COM2, AX = 19 (runix only) 
 23846                              <1> 	
 23847                              <1> 	;1:
 23848                              <1> 	;      	ctty   / tty
 23849                              <1> 	;       leadr  / ppt
 23850                              <1> 	;       sret   / mem
 23851                              <1> 	;       sret   / rf0
 23852                              <1> 	;       sret   / rk0
 23853                              <1> 	;       sret   / tap0
 23854                              <1> 	;       sret   / tap1
 23855                              <1> 	;       sret   / tap2
 23856                              <1> 	;       sret   / tap3
 23857                              <1> 	;       sret   / tap4
 23858                              <1> 	;       sret   / tap5
 23859                              <1> 	;       sret   / tap6
 23860                              <1> 	;       sret   / tap7
 23861                              <1> 	;       ccvt   / tty0
 23862                              <1> 	;       ccvt   / tty1
 23863                              <1> 	;       ccvt   / tty2
 23864                              <1> 	;       ccvt   / tty3
 23865                              <1> 	;       ccvt   / tty4
 23866                              <1> 	;       ccvt   / tty5
 23867                              <1> 	;       ccvt   / tty6
 23868                              <1> 	;       ccvt   / tty7
 23869                              <1> 	;/       ejec / lpr
 23870                              <1> 
 23871                              <1> ctty: ; / close console tty
 23872                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 23873                              <1> 	; 21/05/2013 - 26/01/2014 (Retro UNIX 8086 v1)
 23874                              <1> 	;
 23875                              <1> 	; Retro UNIX 8086 v1 modification !
 23876                              <1> 	; (DL = 2 -> it is open for reading)
 23877                              <1> 	; (DL = 1 -> it is open for writing)
 23878                              <1> 	; (DL = 0 -> it is open for sysstty system call)
 23879                              <1> 	;
 23880                              <1> 	; 06/12/2013
 23881 00005EB3 0FB61D[49700000]    <1>         movzx   ebx, byte [u.uno] ; process number
 23882 00005EBA 8A83[2F6D0000]      <1>         mov     al, [ebx+p.ttyc-1]
 23883                              <1> 	; 13/01/2014
 23884 00005EC0 EB02                <1> 	jmp	short cttyp
 23885                              <1> ccvt:
 23886 00005EC2 2C0A                <1> 	sub 	al, 10
 23887                              <1> cttyp:	
 23888                              <1> 	; 18/05/2015 (32 bit modifications)
 23889                              <1> 	; 16/08/2013 - 26/01/2014
 23890 00005EC4 0FB6D8              <1> 	movzx 	ebx, al ; tty number (0 to 9)
 23891 00005EC7 D0E3                <1> 	shl 	bl, 1  ; aligned to word	
 23892                              <1> 	; 26/01/2014
 23893 00005EC9 81C3[446F0000]      <1> 	add 	ebx, ttyl
 23894 00005ECF 88C6                <1> 	mov 	dh, al ; tty number
 23895 00005ED1 668B03              <1> 	mov 	ax, [ebx]
 23896                              <1> 		   ; AL = lock value (0 or process number)
 23897                              <1> 		   ; AH = open count 
 23898 00005ED4 20E4                <1> 	and 	ah, ah
 23899 00005ED6 750F                <1> 	jnz	short ctty_ret
 23900 00005ED8 C705[6A700000]0A00- <1>         mov     dword [u.error], ERR_DEV_NOT_OPEN
 23901 00005EE0 0000                <1>
 23902                              <1> 			; device not open ! error
 23903                              <1> 	;jmp 	short ctty_err ; open count = 0, it is not open !
 23904 00005EE2 E98BDDFFFF          <1> 	jmp	error
 23905                              <1> 	; 26/01/2014
 23906                              <1> ctty_ret:
 23907 00005EE7 FECC                <1> 	dec 	ah ; decrease open count
 23908 00005EE9 7502                <1> 	jnz	short ctty_1
 23909 00005EEB 30C0                <1> 	xor	al, al ; unlock/free tty
 23910                              <1> ctty_1:
 23911 00005EED 668903              <1> 	mov 	[ebx], ax ; close tty instance
 23912                              <1> 	;
 23913 00005EF0 BB[2E700000]        <1> 	mov	ebx, u.ttyp
 23914 00005EF5 F6C201              <1> 	test	dl, 1 ; open for write sign
 23915 00005EF8 7401                <1> 	jz	short ctty_2
 23916 00005EFA 43                  <1> 	inc	ebx
 23917                              <1> ctty_2:
 23918 00005EFB FEC6                <1> 	inc	dh ; tty number + 1
 23919 00005EFD 3A33                <1> 	cmp	dh, [ebx]
 23920 00005EFF 7503                <1> 	jne	short cret
 23921                              <1> 	; Reset/Clear 'u.ttyp' ('the recent TTY') value
 23922 00005F01 C60300              <1> 	mov	byte [ebx], 0
 23923                              <1> cret:
 23924 00005F04 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 23925 00005F06 7402                <1> 	jz	short ctty_3
 23926 00005F08 6658                <1> 	pop	ax
 23927                              <1> ctty_3:
 23928 00005F0A C3                  <1> 	retn
 23929                              <1> 
 23930                              <1> ;ctty_err: ; 13/01/2014
 23931                              <1> ;	or 	dl, dl ; DL = 0 -> called by sysstty
 23932                              <1> ;	jnz	error
 23933                              <1> ;	stc
 23934                              <1> ;	retn
 23935                              <1> 
 23936                              <1> 
 23937                              <1> 	; Original UNIX v1 'ctty' routine:
 23938                              <1> 	;	
 23939                              <1>         ;mov    tty+[ntty*8]-8+6,r5 
 23940                              <1> 	;		;/ point r5 to the console tty buffer
 23941                              <1>         ;decb   (r5) / dec number of processes using console tty
 23942                              <1>         ;br     sret / return via sret
 23943                              <1> 
 23944                              <1> ;ccvt:	; < close tty >
 23945                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 23946                              <1> 	;
 23947                              <1> 	; Retro UNIX 8086 v1 modification !
 23948                              <1> 	; 
 23949                              <1> 	; In original UNIX v1, 'ccvt' routine 
 23950                              <1> 	;		(exactly different than this one)
 23951                              <1> 	;	was in 'u9.s' file.
 23952                              <1> 	;
 23953                              <1> 	; DL = 2 -> it is open for reading
 23954                              <1> 	; DL = 1 -> it is open for writing
 23955                              <1> 	;
 23956                              <1> 	; 17/09/2013
 23957                              <1> 	;sub 	al, 10
 23958                              <1> 	;cmp	al, 7
 23959                              <1> 	;jna	short cttyp
 23960                              <1> 	; 13/01/2014
 23961                              <1> 	;jmp	short cttyp
 23962                              <1> 
 23963                              <1> ;cppt: / close paper tape
 23964                              <1> ;        clrb   pptiflg / set pptiflg to indicate file not open
 23965                              <1> ;1:
 23966                              <1> ;        mov    $240,*$ps /set process or priority to 5
 23967                              <1> ;        jsr    r0,getc; 2 / remove all ppt input entries from clist
 23968                              <1> ;                          / and assign to free list
 23969                              <1> ;               br sret
 23970                              <1> ;        br     1b
 23971                              <1> 
 23972                              <1> ;ejec:	
 23973                              <1> ;	jmp	error
 23974                              <1> ;/ejec:
 23975                              <1> ;/       mov    $100,*$lps / set line printer interrupt enable bit
 23976                              <1> ;/       mov    $14,r1 / 'form feed' character in r1 (new page).
 23977                              <1> ;/       jsr    r0,lptoc / space the printer to a new page
 23978                              <1> ;/       br     sret / return to caller via 'sret'
 23979                                  %include 'u8.s'        ; 11/06/2015
 23980                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 23981                              <1> ; (re-write kernel for test by using previous version without a major defect)
 23982                              <1> ; ****************************************************************************
 23983                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS8.INC
 23984                              <1> ; Last Modification: 29/11/2021
 23985                              <1> ; ----------------------------------------------------------------------------
 23986                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 23987                              <1> ; (v0.1 - Beginning: 11/07/2012)
 23988                              <1> ;
 23989                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 23990                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 23991                              <1> ; <Bell Laboratories (17/3/1972)>
 23992                              <1> ; <Preliminary Release of UNIX Implementation Document>
 23993                              <1> ;
 23994                              <1> ; Retro UNIX 8086 v1 - U8.ASM (18/01/2014) //// UNIX v1 -> u8.s
 23995                              <1> ;
 23996                              <1> ; ****************************************************************************
 23997                              <1> 
 23998                              <1> ;; I/O Buffer - Retro UNIX 386 v1 modification
 23999                              <1> ;;     (8+512 bytes, 8 bytes header, 512 bytes data)
 24000                              <1> ;; Word 1, byte 0 = device id
 24001                              <1> ;; Word 1, byte 1 = status bits (bits 8 to 15)
 24002                              <1> ;;          bit 9 = write bit
 24003                              <1> ;;	    bit 10 = read bit	  
 24004                              <1> ;;	    bit 12 = waiting to write bit	
 24005                              <1> ;;	    bit 13 = waiting to read bit
 24006                              <1> ;;	    bit 15 = inhibit bit
 24007                              <1> ;; Word 2 (byte 2 & byte 3) = reserved (for now - 07/06/2015)
 24008                              <1> ;; Word 3 + Word 4 (byte 4,5,6,7) = physical block number 
 24009                              <1> ;;		   (In fact, it is 32 bit LBA for Retro UNIX 386 v1)
 24010                              <1> ;;
 24011                              <1> ;; I/O Buffer ((8+512 bytes in original Unix v1))
 24012                              <1> ;;	      ((4+512 bytes in Retro UNIX 8086 v1))
 24013                              <1> ;;
 24014                              <1> ;; I/O Queue Entry (of original UNIX operating system v1)
 24015                              <1> ;; Word 1, Byte 0 = device id
 24016                              <1> ;; Word 1, Byte 1 = (bits 8 to 15)
 24017                              <1> ;;          bit 9 = write bit
 24018                              <1> ;;	    bit 10 = read bit	  
 24019                              <1> ;;	    bit 12 = waiting to write bit	
 24020                              <1> ;;	    bit 13 = waiting to read bit
 24021                              <1> ;;	    bit 15 = inhibit bit
 24022                              <1> ;; Word 2 = physical block number (In fact, it is LBA for Retro UNIX 8086 v1)
 24023                              <1> ;;
 24024                              <1> ;; Original UNIX v1 ->
 24025                              <1> ;;		Word 3 = number of words in buffer (=256) 		
 24026                              <1> ;; Original UNIX v1 -> 
 24027                              <1> ;;		Word 4 = bus address (addr of first word of data buffer)
 24028                              <1> ;;
 24029                              <1> ;; Retro UNIX 8086 v1 -> Buffer Header (I/O Queue Entry) size is 4 bytes !
 24030                              <1> ;;
 24031                              <1> ;; Device IDs (of Retro Unix 8086 v1)
 24032                              <1> ;;          0 = fd0
 24033                              <1> ;;	    1 = fd1
 24034                              <1> ;;	    2 = hd0
 24035                              <1> ;;	    3 = hd1
 24036                              <1> ;;	    4 = hd2
 24037                              <1> ;;	    5 = hd3
 24038                              <1> 
 24039                              <1> ; Retro UNIX 386 v1 - 32 bit modifications (rfd, wfd, rhd, whd) - 09/06/2015
 24040                              <1> 
 24041                              <1> rfd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24042                              <1> 	; 26/04/2013
 24043                              <1>    	; 13/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 24044                              <1>    	;sub 	ax, 3 ; zero based device number (Floppy disk)
 24045                              <1>       	;jmp 	short bread ; **** returns to routine that called readi			
 24046                              <1> 
 24047                              <1> rhd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24048                              <1> 	; 26/04/2013
 24049                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 24050                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 24051                              <1>    	;jmp	short bread ; **** returns to routine that called readi	
 24052                              <1> 
 24053                              <1> bread: 
 24054                              <1> 	; 14/07/2015
 24055                              <1> 	; 10/07/2015
 24056                              <1> 	; 09/06/2015
 24057                              <1> 	; 07/06/2015 (Retro UNIX 386 v1 - Beginning)
 24058                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 24059                              <1> 	;	
 24060                              <1> 	; / read a block from a block structured device
 24061                              <1> 	;
 24062                              <1> 	; INPUTS ->
 24063                              <1> 	;    [u.fopf] points to the block number
 24064                              <1> 	;    CX = maximum block number allowed on device
 24065                              <1> 	;	 ; that was an arg to bread, in original Unix v1, but
 24066                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 24067                              <1> 	;    [u.count]	number of bytes to read in
 24068                              <1> 	; OUTPUTS ->
 24069                              <1> 	;    [u.base] starting address of data block or blocks in user area  	
 24070                              <1> 	;    [u.fopf] points to next consecutive block to be read
 24071                              <1> 	;
 24072                              <1> 	; ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))
 24073                              <1> 	;
 24074                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if read
 24075                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 24076                              <1> 	;	is increased by 1. For example: If user/program request 
 24077                              <1> 	;       to read 16 bytes in current block, 'sys read' increases
 24078                              <1> 	;  	the next block number just as 512 byte reading is done.
 24079                              <1> 	;       This wrong is done in 'bread'. So, in Retro UNIX 8086 v1, 
 24080                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 24081                              <1> 	;       enough to keep byte position/offset of the disk), this
 24082                              <1> 	;	defect will not be corrected, user/program must request
 24083                              <1> 	;	512 byte read per every 'sys read' call to block devices
 24084                              <1> 	;       for achieving correct result. In future version(s), 
 24085                              <1> 	;	this defect will be corrected by using different 
 24086                              <1> 	;       user (u) structure.  26/07/2013 - Erdogan Tan 	
 24087                              <1> 
 24088                              <1> 	   	; jsr r0,tstdeve / error on special file I/O 
 24089                              <1> 			       ; / (only works on tape)
 24090                              <1> 		; mov *u.fofp,r1 / move block number to r1
 24091                              <1> 		; mov $2.-cold,-(sp) / "2-cold" to stack
 24092                              <1> ;1:
 24093                              <1> 		; cmp r1,(r0) / is this block # greater than or equal to
 24094                              <1> 			    ; / maximum block # allowed on device
 24095                              <1> 		; jnb short @f
 24096                              <1> 		; bhis	1f / yes, 1f (error)
 24097                              <1> 		; mov r1,-(sp) / no, put block # on stack
 24098                              <1> 		; jsr r0,preread / read in the block into an I/O buffer
 24099                              <1> 		; mov (sp)+,r1 / return block # to r1
 24100                              <1> 		; inc r1 / bump block # to next consecutive block
 24101                              <1> 		; dec (sp) / "2-1-cold" on stack
 24102                              <1> 		; bgt 1b / 2-1-cold = 0?  No, go back and read in next block
 24103                              <1> ;1:
 24104                              <1> 		; tst (sp)+ / yes, pop stack to clear off cold calculation
 24105                              <1> 	;push	ecx ; **
 24106                              <1> 	;26/04/2013
 24107                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 24108 00005F0B 2C03                <1> 	sub	al, 3
 24109                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 24110 00005F0D A2[69700000]        <1> 	mov	[u.brwdev], al
 24111                              <1> 	; 09/06/2015
 24112 00005F12 0FB6D8              <1> 	movzx	ebx, al
 24113 00005F15 8B8B[1E6A0000]      <1> 	mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 24114                              <1> bread_0:
 24115 00005F1B 51                  <1> 	push	ecx ; ** ; 09/06/2015 
 24116                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 24117                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 24118 00005F1C 8B1D[08700000]      <1> 	mov	ebx, [u.fofp]
 24119 00005F22 8B03                <1> 	mov	eax, [ebx]
 24120 00005F24 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 24121                              <1> 		; mov *u.fofp,r1 / restore r1 to initial value of the
 24122                              <1> 			       ; / block #
 24123 00005F27 39C8                <1> 	cmp	eax, ecx
 24124                              <1> 		; cmp r1,(r0)+ / block # greater than or equal to maximum
 24125                              <1>        	                     ; / block number allowed
 24126                              <1> 	;jnb	error 	     ; 18/04/2013
 24127                              <1> 		; bhis error10 / yes, error
 24128 00005F29 720F                <1> 	jb	short bread_1
 24129 00005F2B C705[6A700000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error	
 24130 00005F33 0000                <1>
 24131 00005F35 E938DDFFFF          <1> 	jmp	error
 24132                              <1> bread_1:
 24133                              <1> 	; inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 24134                              <1> 		; inc *u.fofp / no, *u.fofp has next block number
 24135                              <1> 	; eAX = Block number (zero based)
 24136                              <1> 		;;jsr r0,preread / read in the block whose number is in r1
 24137                              <1> preread: ;; call preread
 24138 00005F3A BF[69700000]        <1> 	mov	edi, u.brwdev ; block device number for direct I/O
 24139 00005F3F E86B020000          <1> 	call	bufaloc_0 ; 26/04/2013
 24140                              <1> 	;; jc 	error
 24141                              <1> 	; eBX = Buffer (Header) Address -Physical-
 24142                              <1>         ; eAX = Block/Sector number (r1)
 24143                              <1> 	       ; jsr r0,bufaloc / get a free I/O buffer (r1 has block number)
 24144                              <1> 	; 14/03/2013
 24145 00005F44 740A                <1>         jz	short bread_2 ; Retro UNIX 8086 v1 modification
 24146                              <1>        		; br 1f / branch if block already in a I/O buffer
 24147 00005F46 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 24148                              <1>         	; bis $2000,(r5) / set read bit (bit 10 in I/O buffer)
 24149 00005F4B E8B3010000          <1> 	call	poke
 24150                              <1>         	; jsr r0,poke / perform the read
 24151                              <1> 	;;jc	error ;2 0/07/2013
 24152                              <1> ; 1:
 24153                              <1>  		; clr *$ps / ps = 0
 24154                              <1>         	; rts r0
 24155                              <1> ;; return from preread
 24156                              <1> bread_2:
 24157 00005F50 66810B0040          <1> 	or	word [ebx], 4000h 
 24158                              <1> 		; bis $40000,(r5) 
 24159                              <1> 			; / set bit 14 of the 1st word of the I/O buffer
 24160                              <1> bread_3: ; 1:
 24161 00005F55 66F7030024          <1> 	test	word [ebx], 2400h
 24162                              <1> 		; bit $22000,(r5) / are 10th and 13th bits set (read bits)
 24163 00005F5A 7407                <1> 	jz	short bread_4
 24164                              <1> 		; beq 1f / no
 24165                              <1> 		; cmp cdev,$1 / disk or drum?
 24166                              <1> 		; ble 2f / yes
 24167                              <1> 		; tstb uquant / is the time quantum = 0?
 24168                              <1> 		; bne 2f / no, 2f
 24169                              <1> 		; mov r5,-(sp) / yes, save r5 (buffer address)
 24170                              <1> 		; jsr r0,sleep; 31. 
 24171                              <1> 			; / put process to sleep in channel 31 (tape)
 24172                              <1> 		; mov (sp)+,r5 / restore r5
 24173                              <1> 		; br 1b / go back
 24174                              <1> ; 2: / drum or disk
 24175                              <1>         ;; mov     cx, [s.wait_]+2 ;; 29/07/2013
 24176 00005F5C E82FF1FFFF          <1> 	call	idle
 24177                              <1> 		; jsr r0,idle; s.wait+2 / wait
 24178 00005F61 EBF2                <1> 	jmp	short bread_3
 24179                              <1>        		; br 1b
 24180                              <1> bread_4: ; 1: / 10th and 13th bits not set
 24181 00005F63 668123FFBF          <1> 	and	word [ebx], 0BFFFh ; 1011111111111111b
 24182                              <1> 		; bic $40000,(r5) / clear bit 14
 24183                              <1>        		; jsr r0,tstdeve / test device for error (tape)
 24184 00005F68 83C308              <1> 	add	ebx, 8
 24185                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 24186                              <1> 	; 09/06/2015
 24187 00005F6B 66833D[64700000]00  <1> 	cmp	word [u.pcount], 0
 24188 00005F73 7705                <1> 	ja	short bread_5
 24189 00005F75 E878F9FFFF          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 24190                              <1> bread_5:
 24191                              <1> 	; eBX = system (I/O) buffer address
 24192 00005F7A E870000000          <1> 	call	dioreg
 24193                              <1>        		; jsr r0,dioreg / do bookkeeping on u.count etc.
 24194                              <1> 	; esi =  start address of the transfer (in the buffer)
 24195                              <1> 	; edi =  [u.pbase], destination address in user's memory space
 24196                              <1> 	; ecx =  transfer count (in bytes)
 24197                              <1> 	;
 24198                              <1> ;1: / r5 points to beginning of data in I/O buffer, r2 points to beginning
 24199                              <1> ;   / of users data
 24200 00005F7F F3A4                <1> 	rep	movsb
 24201                              <1> 		; movb (r5)+,(r2)+ / move data from the I/O buffer
 24202                              <1>        		; dec r3 / to the user's area in core starting at u.base
 24203                              <1>        		; bne 1b
 24204 00005F81 59                  <1> 	pop	ecx ; **
 24205 00005F82 833D[20700000]00    <1> 	cmp	dword [u.count], 0
 24206                              <1> 		; tst u.count / done
 24207 00005F89 7790                <1> 	ja	short bread_0 ; 09/06/2015
 24208                              <1>        		; beq 1f / yes, return
 24209                              <1> 		; tst -(r0) / no, point r0 to the argument again
 24210                              <1>        		; br bread / read some more
 24211                              <1> ; 1:
 24212 00005F8B 58                  <1> 	pop	eax ; ****
 24213                              <1>        		; mov (sp)+,r0
 24214 00005F8C C3                  <1>         retn		; 09/06/2015
 24215                              <1> 	;jmp     ret_ 
 24216                              <1> 		;jmp ret  / jump to routine that called readi
 24217                              <1> 
 24218                              <1> wfd:    ; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24219                              <1> 	; 26/04/2013
 24220                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 24221                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 24222                              <1>    	;jmp	short bwrite ; **** returns to routine that called writei
 24223                              <1> 				
 24224                              <1> whd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24225                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 24226                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 24227                              <1>    	;jmp 	short bwrite ; **** returns to routine that called writei ('jmp ret')
 24228                              <1> 
 24229                              <1> bwrite: 
 24230                              <1> 	; 14/07/2015
 24231                              <1> 	; 10/07/2015
 24232                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24233                              <1> 	; 14/03/2013 - 20/07/2013 (Retro UNIX 8086 v1)
 24234                              <1> 	;	
 24235                              <1> 	;; / write on block structured device
 24236                              <1> 	;
 24237                              <1> 	; INPUTS ->
 24238                              <1> 	;    [u.fopf] points to the block number
 24239                              <1> 	;    CX = maximum block number allowed on device
 24240                              <1> 	;	 ; that was an arg to bwrite, in original Unix v1, but
 24241                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 24242                              <1> 	;    [u.count]	number of bytes to user desires to write
 24243                              <1> 	; OUTPUTS ->
 24244                              <1> 	;    [u.fopf] points to next consecutive block to be written into
 24245                              <1> 	;
 24246                              <1> 	; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))
 24247                              <1> 	;
 24248                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if write
 24249                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 24250                              <1> 	;	is increased by 1. For example: If user/program request 
 24251                              <1> 	;       to write 16 bytes in current block, 'sys write' increases
 24252                              <1> 	;  	the next block number just as 512 byte writing is done.
 24253                              <1> 	;       This wrong is done in 'bwrite'. So, in Retro UNIX 8086 v1, 
 24254                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 24255                              <1> 	;       enough to keep byte position/offset of the disk), this
 24256                              <1> 	;	defect will not be corrected, user/program must request
 24257                              <1> 	;	512 byte write per every 'sys write' call to block devices
 24258                              <1> 	;       for achieving correct result. In future version(s), 
 24259                              <1> 	;	this defect will be corrected by using different 
 24260                              <1> 	;       user (u) structure.  26/07/2013 - Erdogan Tan 	
 24261                              <1> 
 24262                              <1>        		; jsr r0,tstdeve / test the device for an error
 24263                              <1> 	;push	ecx ; **
 24264                              <1> 	;26/04/2013
 24265                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 24266 00005F8D 2C03                <1> 	sub	al, 3
 24267                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 24268 00005F8F A2[69700000]        <1> 	mov	[u.brwdev], al
 24269                              <1> 	; 09/06/2015
 24270 00005F94 0FB6D8              <1> 	movzx	ebx, al
 24271 00005F97 8B8B[1E6A0000]      <1> 	mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 24272                              <1> bwrite_0:
 24273 00005F9D 51                  <1> 	push	ecx ; ** ; 09/06/2015
 24274                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 24275                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 24276 00005F9E 8B1D[08700000]      <1> 	mov	ebx, [u.fofp]
 24277 00005FA4 8B03                <1> 	mov	eax, [ebx]       
 24278 00005FA6 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 24279                              <1> 		; mov *u.fofp,r1 / put the block number in r1
 24280 00005FA9 39C8                <1> 	cmp	eax, ecx
 24281                              <1> 		; cmp r1,(r0)+ / does block number exceed maximum allowable #
 24282                              <1>        	                     ; / block number allowed
 24283                              <1> 	;jnb	error	     ; 18/04/2013
 24284                              <1> 		; bhis error10 / yes, error
 24285 00005FAB 720F                <1>      	jb	short bwrite_1
 24286 00005FAD C705[6A700000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error	
 24287 00005FB5 0000                <1>
 24288 00005FB7 E9B6DCFFFF          <1> 	jmp	error
 24289                              <1> bwrite_1:
 24290                              <1> 	; inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 24291                              <1> 		; inc *u.fofp / no, increment block number
 24292                              <1> 	; 09/06/2015 - 10/07/2015
 24293 00005FBC 66833D[64700000]00  <1> 	cmp	word [u.pcount], 0
 24294 00005FC4 7705                <1> 	ja	short bwrite_2
 24295 00005FC6 E823F9FFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 24296                              <1> bwrite_2:
 24297 00005FCB BF[69700000]        <1> 	mov	edi, u.brwdev  ; block device number for direct I/O
 24298 00005FD0 E8C4000000          <1>        	call	bwslot ; 26/04/2013 (wslot -> bwslot)	 				
 24299                              <1> 		; jsr r0,wslot / get an I/O buffer to write into
 24300                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 24301 00005FD5 E815000000          <1>         call	dioreg
 24302                              <1> 		; jsr r0,dioreg / do the necessary bookkeeping
 24303                              <1> 	; esi =  destination address (in the buffer)
 24304                              <1> 	; edi =  [u.pbase], start address of transfer in user's memory space
 24305                              <1> 	; ecx =  transfer count (in bytes)
 24306                              <1> ; 1: / r2 points to the users data; r5 points to the I/O buffers data area
 24307 00005FDA 87F7                <1> 	xchg 	esi, edi ; 14/07/2015
 24308 00005FDC F3A4                <1> 	rep	movsb
 24309                              <1> 		; movb (r2)+,(r5)+ / ; r3, has the byte count
 24310                              <1>        		; dec r3 / area to the I/O buffer
 24311                              <1>        		; bne 1b
 24312 00005FDE E8FE000000          <1> 	call	dskwr
 24313                              <1> 		; jsr r0,dskwr / write it out on the device
 24314 00005FE3 59                  <1> 	pop	ecx ; **
 24315 00005FE4 833D[20700000]00    <1>         cmp     dword [u.count], 0
 24316                              <1> 		; tst u.count / done
 24317 00005FEB 77B0                <1> 	ja	short bwrite_0 ; 09/06/2015
 24318                              <1> 		; beq 1f / yes, 1f
 24319                              <1> 		; tst -(r0) / no, point r0 to the argument of the call
 24320                              <1>        		; br bwrite / go back and write next block
 24321                              <1> ; 1:
 24322 00005FED 58                  <1> 	pop	eax ; ****
 24323                              <1>        		; mov (sp)+,r0
 24324 00005FEE C3                  <1> 	retn		; 09/06/2015
 24325                              <1>         ;jmp     ret_ 
 24326                              <1> 		; jmp ret / return to routine that called writei
 24327                              <1> ;error10:
 24328                              <1> ;       jmp     error  ; / see 'error' routine
 24329                              <1> 
 24330                              <1> dioreg:
 24331                              <1> 	; 14/07/2015
 24332                              <1> 	; 10/07/2015 (UNIX v1 bugfix - [u.fofp]: byte pos., not block)
 24333                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24334                              <1> 	; 14/03/2013 (Retro UNIX 8086 v1)
 24335                              <1> 	;	
 24336                              <1> 	; bookkeeping on block transfers of data
 24337                              <1> 	;
 24338                              <1> 	; * returns value of u.pbase before it gets updated, in EDI
 24339                              <1> 	; * returns byte count (to transfer) in ECX (<=512)
 24340                              <1> 	; 10/07/2015
 24341                              <1> 	; * returns byte offset from beginning of current sector buffer
 24342                              <1> 	; (beginning of data) in ESI
 24343                              <1> 	;
 24344 00005FEF 8B0D[20700000]      <1> 	mov	ecx, [u.count]
 24345                              <1> 		; mov u.count,r3 / move char count to r3
 24346 00005FF5 81F900020000        <1>        	cmp 	ecx, 512
 24347                              <1> 		; cmp r3,$512. / more than 512. char?
 24348 00005FFB 7605                <1> 	jna	short dioreg_0
 24349                              <1> 		; blos 1f / no, branch
 24350 00005FFD B900020000          <1> 	mov	ecx, 512
 24351                              <1> 		; mov $512.,r3 / yes, just take 512.
 24352                              <1> dioreg_0:
 24353                              <1> 	; 09/06/2015
 24354 00006002 663B0D[64700000]    <1> 	cmp	cx, [u.pcount]
 24355 00006009 7607                <1> 	jna	short dioreg_1
 24356 0000600B 668B0D[64700000]    <1> 	mov	cx, [u.pcount]
 24357                              <1> dioreg_1:
 24358                              <1> ; 1:
 24359 00006012 8B15[1C700000]      <1> 	mov	edx, [u.base] ; 09/06/2015 (eax -> edx)
 24360                              <1> 	        ; mov u.base,r2 / put users base in r2
 24361 00006018 010D[24700000]      <1> 	add	[u.nread], ecx
 24362                              <1> 		; add r3,u.nread / add the number to be read to u.nread
 24363 0000601E 290D[20700000]      <1> 	sub	[u.count], ecx
 24364                              <1> 		; sub r3,u.count / update count
 24365 00006024 010D[1C700000]      <1> 	add	[u.base], ecx
 24366                              <1> 		; add r3,u.base / update base
 24367                              <1> 	; 10/07/2015
 24368                              <1> 	; Retro UNIX 386 v1 - modification !
 24369                              <1> 	; (File pointer points to byte position, not block/sector no.)
 24370                              <1> 	; (It will point to next byte position instead of next block no.)
 24371 0000602A 8B35[08700000]      <1> 	mov	esi, [u.fofp] ; u.fopf points to byte position pointer  
 24372 00006030 8B06                <1> 	mov	eax, [esi] ; esi points to current byte pos. on the disk
 24373 00006032 010E                <1> 	add	[esi], ecx ; ecx is added to set the next byte position
 24374 00006034 25FF010000          <1> 	and	eax, 1FFh  ; get offset from beginning of current block	
 24375 00006039 89DE                <1> 	mov	esi, ebx   ; beginning of data in sector/block buffer
 24376 0000603B 01C6                <1> 	add	esi, eax   ; esi contains start address of the transfer
 24377                              <1> 	; 09/06/2015 - 10/07/2015
 24378 0000603D 66290D[64700000]    <1> 	sub	[u.pcount], cx
 24379 00006044 81E2FF0F0000        <1> 	and	edx, PAGE_OFF ; 0FFFh
 24380 0000604A 8B3D[60700000]      <1> 	mov	edi, [u.pbase]
 24381 00006050 81E700F0FFFF        <1> 	and	edi, ~PAGE_OFF
 24382 00006056 01D7                <1> 	add	edi, edx
 24383 00006058 893D[60700000]      <1> 	mov	[u.pbase], edi
 24384 0000605E 010D[60700000]      <1> 	add	[u.pbase], ecx ; 14/07/2015
 24385 00006064 C3                  <1> 	retn
 24386                              <1> 		; rts r0 / return
 24387                              <1> 
 24388                              <1> dskrd:
 24389                              <1> 	; 18/08/2015
 24390                              <1> 	; 02/07/2015
 24391                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24392                              <1> 	; 14/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 24393                              <1> 	;
 24394                              <1> 	; 'dskrd' acquires an I/O buffer, puts in the proper
 24395                              <1> 	; I/O queue entries (via bufaloc) then reads a block
 24396                              <1> 	; (number specified in r1) in the acquired buffer.)
 24397                              <1> 	; If the device is busy at the time dskrd is called,	
 24398                              <1> 	; dskrd calls idle.
 24399                              <1> 	; 
 24400                              <1> 	; INPUTS ->
 24401                              <1> 	;    r1 - block number
 24402                              <1> 	;    cdev - current device number 
 24403                              <1> 	; OUTPUTS ->
 24404                              <1> 	;    r5 - points to first data word in I/O buffer
 24405                              <1> 	;
 24406                              <1> 	; ((AX = R1)) input/output
 24407                              <1> 	; ((BX = R5)) output 
 24408                              <1> 	;
 24409                              <1>         ; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 24410                              <1> 	;
 24411 00006065 E837010000          <1> 	call 	bufaloc
 24412                              <1> 		; jsr r0,bufaloc / shuffle off to bufaloc; 
 24413                              <1> 			       ; / get a free I/O buffer
 24414                              <1> 	;;jc	error ; 20/07/2013
 24415 0000606A 741B                <1> 	jz	short dskrd_1 ; Retro UNIX 8086 v1 modification
 24416                              <1>        		; br 1f / branch if block already in a I/O buffer
 24417                              <1> dskrd_0: ; 10/07/2015 (wslot)
 24418 0000606C 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 24419                              <1>         	; bis $2000,(r5) / set bit 10 of word 1 of 
 24420                              <1> 		               ; / I/O queue entry for buffer
 24421 00006071 E88D000000          <1> 	call	poke
 24422                              <1> 		; jsr r0,poke / just assigned in bufaloc, 
 24423                              <1> 			    ; /	bit 10=1 says read
 24424                              <1> 	; 09/06/2015
 24425 00006076 730F                <1> 	jnc	short dskrd_1
 24426                              <1> 	;
 24427 00006078 C705[6A700000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; disk read error !
 24428 00006080 0000                <1>
 24429 00006082 E9EBDBFFFF          <1> 	jmp	error
 24430                              <1> dskrd_1: ; 1:
 24431                              <1>        		;clr *$ps
 24432 00006087 66F7030024          <1>        	test	word [ebx], 2400h
 24433                              <1> 		; bit $22000,(r5) / if either bits 10, or 13 are 1; 
 24434                              <1> 				; / jump to idle
 24435 0000608C 7407                <1>        	jz	short dskrd_2
 24436                              <1> 		; beq 1f
 24437                              <1>         ;;mov   ecx, [s.wait_]
 24438 0000608E E8FDEFFFFF          <1>        	call	idle
 24439                              <1> 		; jsr r0,idle; s.wait+2
 24440 00006093 EBF2                <1> 	jmp 	short dskrd_1
 24441                              <1>        		; br 1b
 24442                              <1> dskrd_2: ; 1:
 24443 00006095 83C308              <1>         add	ebx, 8
 24444                              <1> 		; add $8,r5 / r5 points to first word of data in block 
 24445                              <1> 			  ; / just read in
 24446 00006098 C3                  <1>        	retn
 24447                              <1> 		; rts r0
 24448                              <1> 
 24449                              <1> bwslot:
 24450                              <1> 	; 10/07/2015
 24451                              <1> 	;	If the block/sector is not placed in a buffer
 24452                              <1> 	;	before 'wslot', it must be read before
 24453                              <1> 	;	it is written! (Otherwise transfer counts less
 24454                              <1> 	;	than 512 bytes will be able to destroy existing 
 24455                              <1> 	;	data on disk.)
 24456                              <1> 	;
 24457                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 24458                              <1> 	; 26/04/2013(Retro UNIX 8086 v1)
 24459                              <1> 	; Retro UNIX 8086 v1 modification !
 24460                              <1> 	; ('bwslot' will be called from 'bwrite' only!)
 24461                              <1> 	; INPUT -> eDI - points to device id (in u.brwdev)	
 24462                              <1> 	;	-> eAX = block number
 24463                              <1> 	;
 24464 00006099 E811010000          <1> 	call	bufaloc_0
 24465 0000609E 742A                <1> 	jz	short wslot_0 ; block/sector already is in the buffer
 24466                              <1> bwslot_0:
 24467                              <1> 	; 10/07/2015
 24468 000060A0 8B35[08700000]      <1> 	mov	esi, [u.fofp]
 24469 000060A6 8B06                <1> 	mov	eax, [esi]
 24470 000060A8 25FF010000          <1> 	and	eax, 1FFh ; offset from beginning of the sector/block
 24471 000060AD 750C                <1> 	jnz 	short bwslot_1 ; it is not a full sector write
 24472                              <1> 		       ; recent disk data must be placed in the buffer
 24473 000060AF 813D[20700000]0002- <1> 	cmp	dword [u.count], 512
 24474 000060B7 0000                <1>
 24475 000060B9 730F                <1> 	jnb	short wslot_0	
 24476                              <1> bwslot_1:
 24477 000060BB E8ACFFFFFF          <1> 	call	dskrd_0
 24478 000060C0 83EB08              <1> 	sub	ebx, 8 ; set ebx to the buffer header address again	
 24479 000060C3 EB05                <1> 	jmp 	short wslot_0
 24480                              <1> 
 24481                              <1> wslot:
 24482                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 24483                              <1> 	; 		(32 bit modifications)
 24484                              <1> 	; 14/03/2013 - 29/07/2013(Retro UNIX 8086 v1)
 24485                              <1> 	;
 24486                              <1> 	; 'wslot' calls 'bufaloc' and obtains as a result, a pointer
 24487                              <1> 	; to the I/O queue of an I/O buffer for a block structured
 24488                              <1> 	; device. It then checks the first word of I/O queue entry.	
 24489                              <1> 	; If bits 10 and/or 13 (read bit, waiting to read bit) are set,
 24490                              <1> 	; wslot calls 'idle'. When 'idle' returns, or if bits 10 
 24491                              <1> 	; and/or 13 are not set, 'wslot' sets bits 9 and 15 of the first
 24492                              <1> 	; word of the I/O queue entry (write bit, inhibit bit).
 24493                              <1> 	;
 24494                              <1> 	; INPUTS ->
 24495                              <1>  	;    r1 - block number
 24496                              <1> 	;    cdev - current (block/disk) device number
 24497                              <1>  	;
 24498                              <1> 	; OUTPUTS ->
 24499                              <1> 	;    bufp - bits 9 and 15 are set, 
 24500                              <1> 	;           the remainder of the word left unchanged
 24501                              <1> 	;    r5 - points to first data word in I/O buffer
 24502                              <1> 	;
 24503                              <1> 	; ((AX = R1)) input/output
 24504                              <1> 	; ((BX = R5)) output 
 24505                              <1> 	;
 24506                              <1>         ; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP)) 
 24507                              <1> 
 24508 000060C5 E8D7000000          <1> 	call	bufaloc
 24509                              <1> 	; 10/07/2015
 24510                              <1> 		; jsr r0,bufaloc / get a free I/O buffer; pointer to first
 24511                              <1>         	; br 1f / word in buffer in r5
 24512                              <1> 	; eBX = Buffer (Header) Address (r5) (ES=CS=DS, system/kernel segment)
 24513                              <1>         ; eAX = Block/Sector number (r1)
 24514                              <1> wslot_0: ;1:
 24515 000060CA 66F7030024          <1>      	test	word [ebx], 2400h
 24516                              <1> 		; bit $22000,(r5) / check bits 10, 13 (read, waiting to read)
 24517                              <1> 				; / of I/O queue entry
 24518 000060CF 7407                <1> 	jz	short wslot_1
 24519                              <1>                 ; beq 1f  / branch if 10, 13 zero (i.e., not reading, 
 24520                              <1> 		     ; / or not waiting to read)
 24521                              <1> 
 24522                              <1>         ;; mov     ecx, [s.wait_] ; 29/07/2013
 24523 000060D1 E8BAEFFFFF          <1> 	call	idle
 24524                              <1> 		; jsr r0,idle; / if buffer is reading or writing to read,
 24525                              <1>        	                     ; / idle
 24526 000060D6 EBF2                <1> 	jmp	short wslot_0
 24527                              <1> 		; br 1b / till finished
 24528                              <1> wslot_1: ;1:
 24529 000060D8 66810B0082          <1>         or      word [ebx], 8200h
 24530                              <1>        		; bis $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
 24531                              <1>                             	 ; / (write, inhibit bits)
 24532                              <1>        		; clr     *$ps / clear processor status
 24533 000060DD 83C308              <1>         add	ebx, 8 ; 11/06/2015
 24534                              <1> 		; add $8,r5 / r5 points to first word in data area 
 24535                              <1> 			  ; / for this block
 24536 000060E0 C3                  <1>        	retn
 24537                              <1> 		; rts r0
 24538                              <1> dskwr:
 24539                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24540                              <1> 	; 14/03/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 24541                              <1> 	;
 24542                              <1> 	; 'dskwr' writes a block out on disk, via ppoke. The only
 24543                              <1> 	; thing dskwr does is clear bit 15 in the first word of I/O queue
 24544                              <1> 	; entry pointed by 'bufp'. 'wslot' which must have been called
 24545                              <1> 	; previously has supplied all the information required in the
 24546                              <1> 	; I/O queue entry.
 24547                              <1> 	;
 24548                              <1> 	; (Modified registers: eCX, eDX, eBX, eSI, eDI)
 24549                              <1> 	;
 24550                              <1> 	;
 24551 000060E1 8B1D[B06F0000]      <1> 	mov	ebx, [bufp]
 24552 000060E7 668123FF7F          <1> 	and	word [ebx], 7FFFh ; 0111111111111111b
 24553                              <1> 		; bic $100000,*bufp / clear bit 15 of I/O queue entry at
 24554                              <1>                                   ; / bottom of queue
 24555 000060EC E812000000          <1> 	call	poke
 24556                              <1> 	; 09/06/2015
 24557 000060F1 730F                <1> 	jnc	short dskwr_1
 24558 000060F3 C705[6A700000]1200- <1> 	mov	dword [u.error], ERR_DRV_WRITE ; disk write error !
 24559 000060FB 0000                <1>
 24560 000060FD E970DBFFFF          <1> 	jmp	error
 24561                              <1> dskwr_1:
 24562 00006102 C3                  <1> 	retn
 24563                              <1> 
 24564                              <1> 
 24565                              <1> ;ppoke:
 24566                              <1>        		; mov $340,*$ps
 24567                              <1>        		; jsr r0,poke
 24568                              <1>        		; clr *$ps
 24569                              <1> 		; rts r0
 24570                              <1> poke:
 24571                              <1> 	; 29/11/2021 (32 bit push-pop)
 24572                              <1> 	; 24/10/2015
 24573                              <1> 	; 20/08/2015
 24574                              <1> 	; 18/08/2015
 24575                              <1> 	; 02/07/2015
 24576                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 24577                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 24578                              <1> 	;
 24579                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
 24580                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
 24581                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
 24582                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
 24583                              <1> 	;
 24584                              <1> 	; Basic I/O functions for all block structured devices
 24585                              <1> 	;
 24586                              <1>         ; (Modified registers: eCX, eDX, eSI, eDI)
 24587                              <1> 	;
 24588                              <1> 	; 20/07/2013 modifications
 24589                              <1> 	;            (Retro UNIX 8086 v1 features only !)
 24590                              <1> 	; INPUTS -> 
 24591                              <1> 	;        (EBX = buffer header address)
 24592                              <1> 	; OUTPUTS ->
 24593                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
 24594                              <1> 	;	 cf=1 -> error, word [eBX] = 0FFFFh
 24595                              <1> 	;		(drive not ready or r/w error!)
 24596                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
 24597                              <1> 	;	 (dword [EBx+4] = 0FFFFFFFFh means RW/IO error)
 24598                              <1> 	;        (also it indicates invalid buffer data)
 24599                              <1> 	;
 24600 00006103 53                  <1> 	push	ebx
 24601                              <1>        		; mov r1,-(sp)
 24602                              <1>        		; mov r2,-(sp)
 24603                              <1>        		; mov r3,-(sp)
 24604 00006104 50                  <1> 	push 	eax ; Physical Block Number (r1) (mget)
 24605                              <1> 	;
 24606                              <1> 	; 09/06/2015
 24607                              <1> 	; (permit read/write after a disk R/W error)
 24608 00006105 8A0B                <1> 	mov	cl, [ebx] ; device id (0 to 5)
 24609 00006107 B001                <1> 	mov	al, 1
 24610 00006109 D2E0                <1> 	shl	al, cl
 24611 0000610B 8405[D86F0000]      <1> 	test 	al, [active] ; busy ? (error)
 24612 00006111 7408                <1> 	jz	short poke_0
 24613 00006113 F6D0                <1> 	not	al
 24614 00006115 2005[D86F0000]      <1> 	and	[active], al ; reset busy bit for this device only
 24615                              <1> poke_0:
 24616 0000611B BE[D06F0000]        <1>         mov     esi, bufp + (4*(nbuf+2)) 
 24617                              <1> 		; mov $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority
 24618                              <1> 					 ; / I/O queue pointer
 24619                              <1> poke_1: ; 1:
 24620 00006120 83EE04              <1>         sub	esi, 4
 24621 00006123 8B1E                <1> 	mov	ebx, [esi]
 24622                              <1> 		; mov -(r2),r1 / r1 points to an I/O queue entry
 24623 00006125 668B03              <1> 	mov	ax, [ebx] ; 17/07/2013
 24624 00006128 F6C406              <1>        	test	ah, 06h
 24625                              <1> 	;test	word [ebx], 600h ; 0000011000000000b
 24626                              <1> 		; bit $3000,(r1) / test bits 9 and 10 of word 1 of I/O 
 24627                              <1> 			       ; / queue entry
 24628 0000612B 745C                <1>         jz      short poke_5
 24629                              <1> 		; beq 2f / branch to 2f if both are clear
 24630                              <1> 	; 31/07/2013
 24631                              <1> 	;test	ah, 0B0h ; (*)
 24632                              <1> 	;;test	word [ebx], 0B000h ; 1011000000000000b
 24633                              <1> 		; bit $130000,(r1) / test bits 12, 13, and 15
 24634                              <1>         ;jnz     short poke_5 ; 31/07/2013 (*)
 24635                              <1> 		; bne 2f / branch if any are set
 24636                              <1> 	;movzx	ecx, byte [ebx] ; 09/06/2015 ; Device Id
 24637                              <1>     		; movb (r1),r3 / get device id
 24638 0000612D 0FB6C8              <1> 	movzx	ecx, al ; 18/08/2015
 24639                              <1> 	;mov	edi, ecx ; 26/04/2013
 24640 00006130 31C0                <1> 	xor 	eax, eax ; 0
 24641                              <1> 	;cmp 	[edi+drv.error], al ; 0
 24642                              <1> 		; tstb deverr(r3) / test for errors on this device
 24643                              <1>        	;jna	short poke_2 
 24644                              <1> 		; beq 3f / branch if no errors
 24645                              <1> 	; 02/07/2015
 24646                              <1> 	;dec	eax
 24647                              <1> 	;mov	[ebx+4], ax ; 0FFFFFFFFh ; -1 
 24648                              <1>        		; mov $-1,2(r1) / destroy associativity
 24649                              <1> 	;shr	eax, 24
 24650                              <1> 	;mov	[ebx], eax ; 000000FFh, reset
 24651                              <1> 		; clrb 1(r1) / do not do I/O
 24652                              <1> 	;jmp     short poke_5
 24653                              <1>         ;       ; br 2f
 24654                              <1>                 ; rts r0
 24655                              <1> poke_2: ; 3:
 24656                              <1> 	; 02/07/2015
 24657 00006132 FEC1                <1> 	inc	cl ; 0FFh -> 0
 24658 00006134 7453                <1> 	jz	short poke_5
 24659 00006136 FEC0                <1> 	inc	al ; mov ax, 1
 24660 00006138 FEC9                <1> 	dec	cl
 24661 0000613A 7402                <1> 	jz	short poke_3
 24662                              <1> 	; 26/04/2013 Modification
 24663                              <1> 	;inc	al ; mov ax, 1
 24664                              <1> 	;or	cl, cl ; Retro UNIX 8086 v1 device id.
 24665                              <1> 	;jz	short poke_3 ; cl = 0
 24666 0000613C D2E0                <1> 	shl	al, cl ; shl ax, cl
 24667                              <1> poke_3:
 24668                              <1> 	;test	[active], ax
 24669 0000613E 8405[D86F0000]      <1> 	test	[active], al
 24670                              <1> 		; bit $2,active / test disk busy bit
 24671 00006144 7543                <1> 	jnz     short poke_5
 24672                              <1> 		; bne 2f / branch if bit is set
 24673                              <1> 	;or	[active], ax
 24674 00006146 0805[D86F0000]      <1> 	or	[active], al
 24675                              <1> 		; bis $2,active / set disk busy bit
 24676 0000614C 50                  <1> 	push	eax ; 29/11/2021
 24677 0000614D E8D3000000          <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
 24678                              <1> 	;mov    [edi+drv.error], ah
 24679 00006152 58                  <1> 	pop	eax
 24680 00006153 730E                <1> 	jnc	short poke_4 ; 20/07/2013
 24681                              <1> 	;cmp 	[edi+drv.error], al ; 0	
 24682                              <1> 	;jna	short poke_4
 24683                              <1> 		; tstb deverr(r3) / test for errors on this device
 24684                              <1>        		; beq 3f / branch if no errors
 24685                              <1> 	; 02/07/2015 (32 bit modification)
 24686                              <1> 	; 20/07/2013
 24687 00006155 C74304FFFFFFFF      <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
 24688                              <1>        		; mov $-1,2(r1) / destroy associativity
 24689 0000615C 66C703FF00          <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
 24690                              <1> 		; clrb 1(r1) / do not do I/O
 24691 00006161 EB26                <1> 	jmp     short poke_5
 24692                              <1> poke_4:	; 20/07/2013
 24693                              <1> 	; 17/07/2013
 24694 00006163 F6D0                <1> 	not 	al 
 24695 00006165 2005[D86F0000]      <1> 	and	[active], al ; reset, not busy
 24696                              <1> 	; eBX = system I/O buffer header (queue entry) address
 24697                              <1> seta: ; / I/O queue bookkeeping; set read/write waiting bits.
 24698 0000616B 668B03              <1> 	mov	ax, [ebx]
 24699                              <1>        		; mov (r1),r3 / move word 1 of I/O queue entry into r3
 24700 0000616E 66250006            <1>         and	ax, 600h
 24701                              <1> 		; bic $!3000,r3 / clear all bits except 9 and 10
 24702 00006172 668123FFF9          <1> 	and 	word [ebx], 0F9FFh
 24703                              <1>        		; bic $3000,(r1) / clear only bits 9 and 10
 24704 00006177 C0E403              <1> 	shl	ah, 3
 24705                              <1>        		; rol r3
 24706                              <1>                 ; rol r3
 24707                              <1>                 ; rol r3	
 24708 0000617A 660903              <1> 	or	[ebx], ax
 24709                              <1> 		; bis r3,(r1) / or old value of bits 9 and 10 with 
 24710                              <1> 			   ; bits 12 and 13
 24711 0000617D E80EEFFFFF          <1> 	call	idle ; 18/01/2014
 24712                              <1> 	;; sti
 24713                              <1> 	;hlt 	; wait for a hardware interrupt
 24714                              <1> 	;; cli
 24715                              <1> 	; NOTE: In fact, disk controller's 'disk I/O completed' 
 24716                              <1>         ; interrupt would be used to reset busy bits, but INT 13h
 24717                              <1> 	; returns when disk I/O is completed. So, here, as temporary
 24718                              <1> 	; method, this procedure will wait for a time according to
 24719                              <1> 	; multi tasking and time sharing concept.
 24720                              <1> 	;
 24721                              <1> 	; 24/10/2015
 24722                              <1> 	;not	ax 
 24723 00006182 66B8FF00            <1> 	mov 	ax, 0FFh ; 24/10/2015 (temporary)
 24724 00006186 662103              <1> 	and	[ebx], ax ; clear bits 12 and 13
 24725                              <1> poke_5: ;2:
 24726 00006189 81FE[B06F0000]      <1>         cmp     esi, bufp
 24727                              <1> 		; cmp r2,$bufp / test to see if entire I/O queue 
 24728                              <1>                             ; / has been scanned
 24729 0000618F 778F                <1> 	ja      short poke_1
 24730                              <1> 		; bhi 1b
 24731                              <1> 	; 24/03/2013
 24732                              <1>        		; mov (sp)+,r3
 24733                              <1>        		; mov (sp)+,r2
 24734                              <1>        		; mov (sp)+,r1
 24735 00006191 58                  <1>         pop 	eax  ; Physical Block Number (r1) (mget)
 24736 00006192 5B                  <1> 	pop 	ebx
 24737                              <1> 	; 02/07/2015 (32 bit modification)
 24738                              <1> 	; 20/07/2013
 24739                              <1> 	;cmp 	dword [ebx+4], 0FFFFFFFFh
 24740 00006193 803BFF              <1> 	cmp	byte [ebx], 0FFh ; 20/08/2015
 24741                              <1> 	;	
 24742                              <1> 	; 'poke' returns with cf=0 if the requested buffer is read 
 24743                              <1> 	; or written succesfully; even if an error occurs while
 24744                              <1> 	; reading to or writing from other buffers. 20/07/2013
 24745                              <1> 	;
 24746                              <1> 	; 09/06/2015
 24747 00006196 F5                  <1> 	cmc
 24748 00006197 C3                  <1> 	retn
 24749                              <1>                 ; rts r0
 24750                              <1> 
 24751                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatibility code
 24752                              <1> get_system_time:
 24753                              <1> 	; 27/10/2021
 24754                              <1> 	; 21/02/2020 - Retro UNIX 386 v2
 24755                              <1> 	; get system time
 24756                              <1> 	;  (from recent value which is saved in RTC interrupt)
 24757                              <1> 	; Input:
 24758                              <1> 	; 	none
 24759                              <1> 	; Return:
 24760                              <1> 	;   	eax = system time in unix epoch format 
 24761                              <1> 	;
 24762                              <1> 	; Modified registers: eax, ecx, edx
 24763                              <1> 	
 24764                              <1> 	; 27/11/2021
 24765 00006198 53                  <1> 	push	ebx
 24766 00006199 E810D6FFFF          <1> 	call	epoch
 24767 0000619E 5B                  <1> 	pop	ebx
 24768 0000619F C3                  <1> 	retn
 24769                              <1> 
 24770                              <1> get_serial_number:
 24771                              <1> 	; temporary - 21/02/2020
 24772                              <1> 	; 26/04/2020 (esi)
 24773                              <1> 	; 25/04/2020
 24774                              <1> 	; (Possible) Modified registers: eax, ecx, edx
 24775                              <1> 	; (edi, ebx & esi registers must be preserved)
 24776                              <1> 	; Return:
 24777                              <1> 	; eax = 32 bit serial number  
 24778                              <1> 	; (edx = high 32 bit of 64 bit serial number)
 24779                              <1> 	; -64 bit serial numbers will not be used in RUNIX 386 v2-
 24780 000061A0 C3                  <1> 	retn
 24781                              <1> 
 24782                              <1> bufaloc:
 24783                              <1> 	; 20/08/2015
 24784                              <1> 	; 19/08/2015
 24785                              <1> 	; 02/07/2015
 24786                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 24787                              <1> 	;	     (32 bit modifications)	
 24788                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 24789                              <1> 	;
 24790                              <1> 	; bufaloc - Block device I/O buffer allocation
 24791                              <1> 	; 
 24792                              <1> 	; INPUTS ->
 24793                              <1> 	;    r1 - block number
 24794                              <1> 	;    cdev - current (block/disk) device number
 24795                              <1> 	;    bufp+(2*n)-2 --- n = 1 ... nbuff
 24796                              <1> 	; OUTPUTS ->
 24797                              <1> 	;    r5 - pointer to buffer allocated
 24798                              <1> 	;    bufp ... bufp+12 --- (bufp), (bufp)+2
 24799                              <1> 	;
 24800                              <1> 	; ((AX = R1)) input/output
 24801                              <1> 	; ((BX = R5)) output
 24802                              <1>         ;    ((Modified registers: DX, CX, BX, SI, DI, BP))
 24803                              <1> 	;    zf=1 -> block already in a I/O buffer
 24804                              <1> 	;    zf=0 -> a new I/O buffer has been allocated
 24805                              <1> 	;    ((DL = Device ID))
 24806                              <1> 	;    (((DH = 0 or 1)))
 24807                              <1> 	;    (((CX = previous value of word ptr [bufp])))
 24808                              <1> 	;    ((CX and DH will not be used after return)))
 24809                              <1> 
 24810                              <1> 	;;push 	esi ; ***
 24811                              <1> 		; mov r2,-(sp) / save r2 on stack
 24812                              <1>        		; mov $340,*$ps / set processor priority to 7
 24813                              <1> 	; 20/07/2013
 24814                              <1> 	; 26/04/2013
 24815 000061A1 0FB61D[D56F0000]    <1> 	movzx	ebx, byte [cdev] ; 0 or 1
 24816 000061A8 BF[D66F0000]        <1> 	mov	edi, rdev  ; offset mdev = offset rdev + 1
 24817 000061AD 01DF                <1> 	add	edi, ebx
 24818                              <1> bufaloc_0: ; 26/04/2013 !! here is called from bread or bwrite !!
 24819                              <1> 			;; eDI points to device id.
 24820 000061AF 0FB61F              <1> 	movzx	ebx, byte [edi] ; [EDI] -> rdev/mdev or brwdev
 24821                              <1> 	; 11/06/20215
 24822 000061B2 80BB[3A6A0000]F0    <1> 	cmp 	byte [ebx+drv.status], 0F0h ; Drive not ready !
 24823 000061B9 720F                <1> 	jb	short bufaloc_9
 24824 000061BB C705[6A700000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 24825 000061C3 0000                <1>
 24826 000061C5 E9A8DAFFFF          <1> 	jmp	error
 24827                              <1> bufaloc_9:
 24828 000061CA 89DA                <1> 	mov	edx, ebx ; dh = 0, dl = device number (0 to 5)
 24829                              <1> bufaloc_10: ; 02/07/2015
 24830 000061CC 31ED                <1> 	xor 	ebp, ebp ; 0
 24831 000061CE 55                  <1> 	push	ebp ; 0
 24832 000061CF 89E5                <1>         mov     ebp, esp	
 24833                              <1> 	;
 24834                              <1> bufaloc_1: ;1:
 24835                              <1> 		; clr -(sp) / vacant buffer
 24836 000061D1 BE[B06F0000]        <1>         mov 	esi, bufp
 24837                              <1> 		; mov $bufp,r2 / bufp contains pointers to I/O queue 
 24838                              <1> 			     ; / entrys in buffer area
 24839                              <1> bufaloc_2: ;2:
 24840 000061D6 8B1E                <1> 	mov	ebx, [esi]
 24841                              <1>        		; mov (r2)+,r5 / move pointer to word 1 of an I/O 
 24842                              <1> 			    ; queue entry into r5
 24843 000061D8 66F70300F6          <1> 	test	word [ebx], 0F600h
 24844                              <1> 		; bit $173000,(r5) / lock+keep+active+outstanding
 24845 000061DD 7503                <1>         jnz	short bufaloc_3
 24846                              <1> 		; bne 3f / branch when 
 24847                              <1> 		       ; / any of bits 9,10,12,13,14,15 are set
 24848                              <1>                        ; / (i.e., buffer busy)
 24849 000061DF 897500              <1>         mov     [ebp], esi ; pointer to I/0 queue entry
 24850                              <1>                 ; mov  r2,(sp) ;/ save pointer to last non-busy buffer
 24851                              <1> 			; / found points to word 2 of I/O queue entry)
 24852                              <1> bufaloc_3: ;3:
 24853                              <1> 	;mov	dl, [edi] ; 26/04/2013
 24854                              <1> 	;
 24855 000061E2 3813                <1> 	cmp	[ebx], dl	
 24856                              <1> 		; cmpb (r5),cdev / is device in I/O queue entry same 
 24857                              <1> 			       ; / as current device
 24858 000061E4 7508                <1> 	jne	short bufaloc_4
 24859                              <1>        		; bne 3f
 24860 000061E6 394304              <1> 	cmp	[ebx+4], eax
 24861                              <1>        		; cmp 2(r5),r1 / is block number in I/O queue entry, 
 24862                              <1> 			     ; / same as current block number
 24863 000061E9 7503                <1>        	jne	short bufaloc_4
 24864                              <1> 		; bne 3f
 24865                              <1> 	;add	esp, 4
 24866 000061EB 59                  <1> 	pop	ecx
 24867                              <1>        		; tst (sp)+ / bump stack pointer
 24868 000061EC EB20                <1> 	jmp	short bufaloc_7 ; Retro Unix 8086 v1 modification
 24869                              <1> 				; jump to bufaloc_6 in original Unix v1
 24870                              <1>        		; br 1f / use this buffer
 24871                              <1> bufaloc_4: ;3:
 24872 000061EE 83C604              <1> 	add	esi, 4 ; 20/08/2015
 24873                              <1> 	;
 24874 000061F1 81FE[C86F0000]      <1> 	cmp	esi, bufp + (nbuf*4)
 24875                              <1> 		; cmp r2,$bufp+nbuf+nbuf
 24876 000061F7 72DD                <1> 	jb	short bufaloc_2
 24877                              <1> 		; blo 2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
 24878                              <1>                        ; / buffers not checked)
 24879 000061F9 5E                  <1>         pop	esi
 24880                              <1> 		; mov (sp)+,r2 / once all bufs are examined move pointer
 24881                              <1> 			     ; / to last free block
 24882 000061FA 09F6                <1>        	or	esi, esi 
 24883 000061FC 7507                <1> 	jnz	short bufaloc_5
 24884                              <1> 		; bne 2f / if (sp) is non zero, i.e., 
 24885                              <1> 	        ; / if a free buffer is found branch to 2f
 24886                              <1>         ;; mov  ecx, [s.wait_]
 24887 000061FE E88DEEFFFF          <1> 	call	idle
 24888                              <1> 		; jsr r0,idle; s.wait+2 / idle if no free buffers
 24889 00006203 EBC7                <1> 	jmp 	short bufaloc_10 ; 02/07/2015
 24890                              <1>        		; br 1b
 24891                              <1> bufaloc_5: ;2:
 24892                              <1> 		; tst (r0)+ / skip if warmed over buffer
 24893 00006205 FEC6                <1> 	inc	dh ; Retro UNIX 8086 v1 modification
 24894                              <1> bufaloc_6: ;1:
 24895 00006207 8B1E                <1>         mov    	ebx, [esi] 
 24896                              <1> 		; mov -(r2),r5 / put pointer to word 1 of I/O queue 
 24897                              <1> 			     ; / entry in r5
 24898                              <1> 	;; 26/04/2013
 24899                              <1>         ;mov	dl, [edi] ; byte [rdev] or byte [mdev]
 24900 00006209 8813                <1> 	mov 	[ebx], dl
 24901                              <1> 		; movb cdev,(r5) / put current device number 
 24902                              <1> 				 ; / in I/O queue entry
 24903 0000620B 894304              <1> 	mov 	[ebx+4], eax
 24904                              <1> 		; mov r1,2(r5) / move block number into word 2 
 24905                              <1> 			     ; / of I/O queue entry
 24906                              <1> bufaloc_7: ;1:
 24907 0000620E 81FE[B06F0000]      <1>         cmp	esi, bufp
 24908                              <1> 		; cmp r2,$bufp / bump all entrys in bufp 
 24909                              <1> 			     ; / and put latest assigned
 24910 00006214 760A                <1> 	jna	short bufaloc_8	
 24911                              <1>        		; blos 1f / buffer on the top 
 24912                              <1> 			; / (this makes if the lowest priority)
 24913 00006216 83EE04              <1> 	sub	esi, 4
 24914 00006219 8B0E                <1> 	mov	ecx, [esi]
 24915 0000621B 894E04              <1> 	mov	[esi+4], ecx
 24916                              <1> 		; mov -(r2),2(r2) / job for a particular device
 24917 0000621E EBEE                <1> 	jmp 	short bufaloc_7        
 24918                              <1> 		; br 1b
 24919                              <1> bufaloc_8: ;1:
 24920 00006220 891E                <1>         mov	[esi], ebx
 24921                              <1> 		; mov r5,(r2)
 24922                              <1> 	;;pop	esi ; ***
 24923                              <1>        		; mov (sp)+,r2 / restore r2
 24924 00006222 08F6                <1>        	or 	dh, dh ; 0 or 1 ?
 24925                              <1> 		; Retro UNIX 8086 v1 modification
 24926                              <1> 		; zf=1 --> block already is in an I/O buffer
 24927                              <1> 		; zf=0 --> a new I/O buffer has been allocated
 24928 00006224 C3                  <1> 	retn
 24929                              <1> 		; rts r0
 24930                              <1> 
 24931                              <1> diskio:
 24932                              <1> 	; 28/11/2021
 24933                              <1> 	; 10/07/2015
 24934                              <1> 	; 02/07/2015
 24935                              <1> 	; 16/06/2015
 24936                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 24937                              <1> 	;	     (80386 protected mode modifications)	
 24938                              <1> 	; 15/03/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 24939                              <1> 	;
 24940                              <1> 	; Retro UNIX 8086 v1 feature only !
 24941                              <1> 	;
 24942                              <1> 	; Derived from proc_chs_read procedure of TRDOS DISKIO.ASM (2011)
 24943                              <1> 	; 04/07/2009 - 20/07/2011
 24944                              <1> 	;
 24945                              <1> 	; NOTE: Reads only 1 block/sector (sector/block size is 512 bytes)
 24946                              <1> 	;
 24947                              <1>         ; INPUTS ->
 24948                              <1> 	; 	   ebx = System I/O Buffer header address
 24949                              <1> 	;
 24950                              <1>         ; OUTPUTS -> cf=0 --> done 
 24951                              <1> 	; 	     cf=1 ---> error code in AH
 24952                              <1> 	;
 24953                              <1> 	; (Modified registers: eax, ecx, edx)
 24954                              <1> 	
 24955                              <1> ;rw_disk_sector:
 24956                              <1> 	; 28/11/2021
 24957                              <1> 	; 10/07/2015
 24958                              <1> 	; 02/07/2015
 24959                              <1> 	; 11/06/2015 - Retro UNIX 386 v1 - 'u8.s' 
 24960                              <1> 	; 21/02/2015 ('dsectpm.s', 'read_disk_sector')
 24961                              <1> 	; 16/02/2015 (Retro UNIX 386 v1 test - 'unix386.s')
 24962                              <1> 	; 01/12/2014 - 18/01/2015 ('dsectrm2.s')
 24963                              <1> 	;
 24964                              <1> 	;mov	dx, 0201h ; Read 1 sector/block
 24965 00006225 B602                <1> 	mov	dh, 2
 24966                              <1> 	;mov	ax, [ebx]
 24967                              <1> 	; 28/11/2021
 24968 00006227 8B03                <1> 	mov	eax, [ebx]
 24969                              <1> 	;
 24970 00006229 56                  <1> 	push	esi ; ****
 24971 0000622A 53                  <1> 	push	ebx ; ***
 24972                              <1> 	;
 24973 0000622B 0FB6C8              <1> 	movzx	ecx, al
 24974                              <1> 	; 28/11/2021
 24975                              <1> 	;mov	ecx, eax
 24976 0000622E 89CE                <1> 	mov	esi, ecx
 24977                              <1> 	;
 24978 00006230 38F1                <1> 	cmp	cl, dh ; 2
 24979 00006232 7202                <1> 	jb	short rwdsk0
 24980 00006234 047E                <1> 	add	al, 7Eh  ; 80h, 81h, 82h, 83h
 24981                              <1> rwdsk0:
 24982 00006236 A2[EB690000]        <1> 	mov	[drv], al
 24983 0000623B 81C6[3A6A0000]      <1> 	add	esi, drv.status
 24984                              <1> 	; 11/06/2015
 24985 00006241 803EF0              <1> 	cmp	byte [esi], 0F0h 
 24986 00006244 720F                <1> 	jb      short rwdsk1
 24987                              <1> 	; 'drive not ready' error
 24988 00006246 C705[6A700000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 24989 0000624E 0000                <1>
 24990 00006250 E91DDAFFFF          <1> 	jmp	error
 24991                              <1> rwdsk1:
 24992 00006255 F6C402              <1> 	test	ah, 2
 24993                              <1> 	;test	ax, 200h ; Bit 9 of word 0 (status word)
 24994                              <1> 			   ; write bit
 24995 00006258 7402                <1> 	jz	short rwdsk2
 24996                              <1> 	;test	ah, 4
 24997                              <1> 	;;test	ax, 400h ; Bit 10 of word 0 (status word)
 24998                              <1> 	;		 ; read bit
 24999                              <1> 	;jz	short diskio_ret
 25000 0000625A FEC6                <1> 	inc	dh ; 03h = write
 25001                              <1> rwdsk2:
 25002 0000625C 88C2                <1> 	mov	dl, al
 25003 0000625E 83C304              <1> 	add	ebx, 4 ; sector/block address/number pointer
 25004 00006261 8B03                <1> 	mov	eax, [ebx] ; sector/block number (LBA)
 25005 00006263 C0E102              <1> 	shl	cl, 2
 25006 00006266 81C1[1E6A0000]      <1> 	add	ecx, drv.size ; disk size
 25007 0000626C 3B01                <1> 	cmp	eax, [ecx] ; Last sector + 1 (number of secs.)
 25008 0000626E 720F                <1> 	jb      short rwdsk3
 25009                              <1>  	; 'out of volume' error
 25010 00006270 C705[6A700000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE 	
 25011 00006278 0000                <1>
 25012 0000627A E9F3D9FFFF          <1> 	jmp	error
 25013                              <1> rwdsk3:
 25014                              <1> 	; 11/06/2015
 25015 0000627F 83C304              <1> 	add	ebx, 4 ; buffer address
 25016 00006282 C605[2F710000]04    <1> 	mov	byte [retry_count], 4
 25017 00006289 F60601              <1> 	test	byte [esi], 1 ; LBA ready ?
 25018 0000628C 7432                <1>         jz      short rwdsk_chs
 25019                              <1> rwdsk_lba:
 25020                              <1> 	; LBA read/write (with private LBA function) 
 25021                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 25022 0000628E 83C607              <1>         add     esi, drv.error - drv.status ; 10/07/2015
 25023 00006291 89C1                <1> 	mov	ecx, eax ; sector number
 25024                              <1> 	; ebx = buffer (data) address
 25025                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
 25026                              <1> rwdsk_lba_retry:
 25027                              <1> 	;mov	dl, [drv]
 25028                              <1> 		; Function 1Bh = LBA read, 1Ch = LBA write
 25029 00006293 B419                <1> 	mov	ah, 1Ch - 3h ; LBA write function number - 3
 25030 00006295 00F4                <1> 	add	ah, dh		
 25031 00006297 B001                <1> 	mov	al, 1
 25032                              <1> 	;int	13h
 25033 00006299 E857C4FFFF          <1> 	call	int13h
 25034 0000629E 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 25035 000062A0 730E                <1> 	jnc	short rwdsk_lba_ok
 25036 000062A2 80FC80              <1> 	cmp	ah, 80h ; time out ?
 25037 000062A5 7408                <1>         je      short rwdsk_lba_fails
 25038 000062A7 FE0D[2F710000]      <1> 	dec	byte [retry_count]
 25039 000062AD 7504                <1>         jnz     short rwdsk_lba_reset ; 10/07/2015
 25040                              <1> rwdsk_lba_fails:
 25041 000062AF F9                  <1> 	stc
 25042                              <1> rwdsk_lba_ok:
 25043 000062B0 5B                  <1> 	pop	ebx ; ***
 25044 000062B1 5E                  <1> 	pop	esi ; ****
 25045 000062B2 C3                  <1> 	retn
 25046                              <1> rwdsk_lba_reset:
 25047 000062B3 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 25048                              <1> 	;int	13h
 25049 000062B5 E83BC4FFFF          <1>         call	int13h
 25050 000062BA 73D7                <1> 	jnc     short rwdsk_lba_retry
 25051 000062BC 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 25052 000062BE EBF0                <1> 	jmp	short rwdsk_lba_ok
 25053                              <1> 	;
 25054                              <1> 	; CHS read (convert LBA address to CHS values)	
 25055                              <1> rwdsk_chs:
 25056                              <1> 	; 10/07/2015
 25057 000062C0 81EE[3A6A0000]      <1> 	sub	esi, drv.status
 25058 000062C6 89F1                <1> 	mov	ecx, esi
 25059 000062C8 81C6[416A0000]      <1> 	add 	esi, drv.error
 25060                              <1> 	; 02/07/2015
 25061                              <1> 	; 16/06/2015
 25062                              <1>  	; 11/06/2015 
 25063 000062CE 53                  <1> 	push	ebx ; ** ; buffer
 25064 000062CF D1E1                <1> 	shl	ecx, 1
 25065 000062D1 51                  <1> 	push	ecx ; * 
 25066                              <1> 	;
 25067 000062D2 89CB                <1> 	mov	ebx, ecx
 25068 000062D4 8835[2D710000]      <1> 	mov	[rwdsk], dh ; 02/07/2015
 25069 000062DA 31D2                <1> 	xor	edx, edx ; 0
 25070 000062DC 29C9                <1> 	sub	ecx, ecx 
 25071 000062DE 81C3[106A0000]      <1>         add     ebx, drv.spt
 25072 000062E4 668B0B              <1> 	mov	cx, [ebx] ; sector per track
 25073                              <1> 		; EDX:EAX = LBA
 25074                              <1> ; 28/11/2021 - temporary
 25075 000062E7 09C9                <1> or ecx, ecx
 25076 000062E9 7515                <1> jnz short bunugec1
 25077 000062EB 50                  <1> push	eax
 25078 000062EC B44E                <1> mov	ah, 4Eh
 25079 000062EE B021                <1> mov	al, '!'
 25080 000062F0 66A300800B00        <1> mov	[0B8000h], ax
 25081 000062F6 B9FFFFFF0F          <1> mov	ecx, 0FFFFFFFh
 25082                              <1> above4:
 25083 000062FB 4A                  <1> dec	edx
 25084 000062FC 42                  <1> inc	edx
 25085 000062FD E2FC                <1> loop	above4
 25086 000062FF 58                  <1> pop	eax
 25087                              <1> 
 25088                              <1> bunugec1: 
 25089                              <1> 
 25090 00006300 F7F1                <1> 	div	ecx
 25091 00006302 88D1                <1> 	mov	cl, dl	; sector number - 1
 25092 00006304 FEC1                <1> 	inc	cl	; sector number (1 based)
 25093 00006306 5B                  <1> 	pop	ebx ; * ; 11/06/2015
 25094 00006307 51                  <1> 	push	ecx ; 28/11/2021
 25095 00006308 81C3[026A0000]      <1>         add     ebx, drv.heads
 25096 0000630E 668B0B              <1> 	mov	cx, [ebx] ; heads
 25097 00006311 31D2                <1> 	xor	edx, edx
 25098                              <1> 		; EAX = cylinders * heads + head
 25099 00006313 F7F1                <1> 	div	ecx
 25100                              <1> 	;pop	cx     ; sector number
 25101 00006315 59                  <1> 	pop	ecx ; 28/11/2021
 25102 00006316 88D6                <1> 	mov	dh, dl ; head number
 25103 00006318 8A15[EB690000]      <1> 	mov	dl, [drv]
 25104 0000631E 88C5                <1> 	mov	ch, al ; cylinder (bits 0-7)
 25105 00006320 C0E406              <1> 	shl	ah, 6
 25106 00006323 08E1                <1> 	or	cl, ah ; cylinder (bits 8-9)
 25107                              <1> 		       ; sector (bits 0-7)
 25108 00006325 5B                  <1> 	pop	ebx ; ** ; buffer ; 11/06/2015
 25109                              <1> 		; CL = sector (bits 0-5)
 25110                              <1> 		;      cylinder (bits 8-9 -> bits 6-7)
 25111                              <1> 		; CH = cylinder (bits 0-7)
 25112                              <1> 		; DH = head
 25113                              <1> 		; DL = drive
 25114                              <1> 	;
 25115 00006326 C605[2F710000]04    <1> 	mov	byte [retry_count], 4
 25116                              <1> rwdsk_retry:	
 25117 0000632D 8A25[2D710000]      <1> 	mov	ah, [rwdsk] ; 02h = read, 03h = write
 25118 00006333 B001                <1> 	mov	al, 1 ; sector count	
 25119                              <1> 	;int	13h
 25120 00006335 E8BBC3FFFF          <1> 	call	int13h
 25121 0000633A 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 25122 0000633C 730E                <1> 	jnc	short rwdsk_ok ; ah = 0
 25123 0000633E 80FC80              <1> 	cmp	ah, 80h ; time out ?
 25124 00006341 7408                <1> 	je	short rwdsk_fails
 25125 00006343 FE0D[2F710000]      <1> 	dec	byte [retry_count]
 25126 00006349 7504                <1> 	jnz	short rwdsk_reset
 25127                              <1> rwdsk_fails:
 25128 0000634B F9                  <1> 	stc
 25129                              <1> rwdsk_ok:
 25130 0000634C 5B                  <1> 	pop	ebx ; ***
 25131 0000634D 5E                  <1> 	pop	esi ; ****
 25132 0000634E C3                  <1> 	retn
 25133                              <1> rwdsk_reset:
 25134                              <1> 	; 02/02/2015
 25135 0000634F 28E4                <1> 	sub	ah, ah
 25136 00006351 80FA80              <1> 	cmp	dl, 80h
 25137 00006354 7202                <1> 	jb	short rwdsk_fd_reset
 25138 00006356 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 25139                              <1> rwdsk_fd_reset:
 25140                              <1> 	;int	13h
 25141 00006358 E898C3FFFF          <1>         call	int13h
 25142 0000635D 73CE                <1> 	jnc	short rwdsk_retry
 25143 0000635F 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 25144 00006361 EBE9                <1> 	jmp 	short rwdsk_ok
 25145                              <1> 
 25146                              <1> ; Original UNIX v1 - drum (& disk) interrupt routine
 25147                              <1> ;	(Equivalent to IRQ 14 & IRQ 15 disk/hardware interrupts)
 25148                              <1> ;
 25149                              <1> ; This feature is not used in Retro UNIX 386 (& 8086) for now.
 25150                              <1> ; Because, current Retro UNIX 386 disk I/O -INT13H- routine is 
 25151                              <1> ; derived from IBM PC AT -infact: XT286- BIOS source code, int 13h
 25152                              <1> ; that uses hardware -transfer has been completed-  interrupt inside it. 
 25153                              <1> ; In a next Retro UNIX 386 version, these interrupts
 25154                              <1> ; (fdc_int, hdc1_int, hdc2_int) will be handled by a separate routine
 25155                              <1> ; as in original unix v1.
 25156                              <1> ; I am not removing IBM BIOS source code derivatives -compatible code-
 25157                              <1> ; for now, regarding the new/next 32 bit TRDOS project by me
 25158                              <1> ; (to keep source code files easy adaptable to 32 bit TRDOS.)
 25159                              <1> ;
 25160                              <1> ; Erdogan tan (10/07/2015) 
 25161                              <1> 
 25162                              <1> ;drum: / interrupt handler
 25163                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 25164                              <1> ;       jsr     r0,trapt; dcs; rfap; 1 / check for stray interrupt or
 25165                              <1> ;                                      / error
 25166                              <1> ;               br 3f / no, error
 25167                              <1> ;       br      2f / error
 25168                              <1> ;
 25169                              <1> ;disk:
 25170                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 25171                              <1> ;       jmp     *$0f
 25172                              <1> ;0:
 25173                              <1> ;       jsr     r0,trapt; rkcs; rkap; 2
 25174                              <1> ;      	        br 3f / no, errors
 25175                              <1> ;       mov     $115,(r2) / drive reset, errbit was set
 25176                              <1> ;       mov     $1f,0b-2 / next time jmp *$0f is executed jmp will be
 25177                              <1> ;                        / to 1f
 25178                              <1> ;       br      4f
 25179                              <1> ;1:
 25180                              <1> ;       bit     $20000,rkcs
 25181                              <1> ;       beq     4f / wait for seek complete
 25182                              <1> ;       mov     $0b,0b-2
 25183                              <1> ;       mov     rkap,r1
 25184                              <1> ;2:
 25185                              <1> ;       bit     $3000,(r1) / are bits 9 or 10 set in the 1st word of
 25186                              <1> ;                          / the disk buffer
 25187                              <1> ;       bne     3f / no, branch ignore error if outstanding
 25188                              <1> ;       inc     r1
 25189                              <1> ;       asr     (r1)
 25190                              <1> ;       asr     (r1)
 25191                              <1> ;       asr     (r1) / reissue request
 25192                              <1> ;       dec     r1
 25193                              <1> ;3:
 25194                              <1> ;       bic     $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
 25195                              <1> ;       mov     ac,-(sp)
 25196                              <1> ;       mov     mq,-(sp) / put these on the stack
 25197                              <1> ;       mov     sc,-(sp)
 25198                              <1> ;       jsr     r0,poke
 25199                              <1> ;       mov     (sp)+,sc
 25200                              <1> ;       mov     (sp)+,mq / pop them off stack
 25201                              <1> ;       mov     (sp)+,ac
 25202                              <1> ;4:
 25203                              <1> ;       jmp     retisp / u4-3
 25204                              <1> ;
 25205                              <1> ;trapt:                  / r2 points to the
 25206                              <1> ;       mov     (r0)+,r2 / device control register
 25207                              <1> ;       mov     *(r0)+,r1 / transaction pointer points to buffer
 25208                              <1> ;       tst     (sp)+
 25209                              <1> ;       tstb    (r2) / is ready bit of dcs set?
 25210                              <1> ;       bge     4b / device still active so branch
 25211                              <1> ;       bit     (r0),active / was device busy?
 25212                              <1> ;       beq     4b / no, stray interrupt
 25213                              <1> ;       bic     (r0)+,active / yes, set active to zero
 25214                              <1> ;       tst     (r2) / test the err(bit is) of dcs
 25215                              <1> ;       bge     2f / if no error jump to 2f
 25216                              <1> ;       tst     (r0)+ / skip on error
 25217                              <1> ; 2:
 25218                              <1> ;       jmp     (r0)
 25219                                  %include 'u9.s'        ; 29/06/2015
 25220                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
 25221                              <1> ; Last Modification: 09/12/2015
 25222                              <1> ; ----------------------------------------------------------------------------
 25223                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 25224                              <1> ; (v0.1 - Beginning: 11/07/2012)
 25225                              <1> ;
 25226                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 25227                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 25228                              <1> ; <Bell Laboratories (17/3/1972)>
 25229                              <1> ; <Preliminary Release of UNIX Implementation Document>
 25230                              <1> ;
 25231                              <1> ; Retro UNIX 8086 v1 - U9.ASM (01/09/2014) //// UNIX v1 -> u9.s
 25232                              <1> ;
 25233                              <1> ; ****************************************************************************
 25234                              <1> 
 25235                              <1> getch:
 25236                              <1> 	; 30/06/2015
 25237                              <1> 	; 18/02/2015 - Retro UNIX 386 v1 - feature only!
 25238 00006363 28C0                <1> 	sub	al, al ; 0
 25239                              <1> getch_q: ; 06/08/2015
 25240 00006365 8A25[266F0000]      <1> 	mov 	ah, [ptty] ; active (current) video page
 25241 0000636B EB06                <1>         jmp     short getc_n
 25242                              <1> 
 25243                              <1> getc: 
 25244                              <1> 	; 12/11/2015
 25245                              <1> 	; 15/09/2015
 25246                              <1> 	; 01/07/2015
 25247                              <1> 	; 30/06/2015
 25248                              <1> 	; 18/02/2015 (Retro UNIX 386 v1 - Beginning)
 25249                              <1> 	; 13/05/2013 - 04/07/2014 (Retro UNIX 8086 v1)
 25250                              <1> 	;
 25251                              <1> 	; Retro UNIX 8086 v1 modification !
 25252                              <1> 	; 
 25253                              <1> 	; 'getc' gets (next) character 
 25254                              <1> 	;	 from requested TTY (keyboard) buffer 
 25255                              <1> 	; INPUTS ->
 25256                              <1> 	;     [u.ttyn] = tty number (0 to 7) (8 is COM1, 9 is COM2)	
 25257                              <1> 	;     AL=0 -> Get (next) character from requested TTY buffer
 25258                              <1> 	;	(Keyboard buffer will point to 
 25259                              <1> 	;			next character at next call)
 25260                              <1> 	;     AL=1 -> Test a key is available in requested TTY buffer
 25261                              <1> 	;	(Keyboard buffer will point to 
 25262                              <1> 	;			current character at next call)
 25263                              <1> 	; OUTPUTS ->
 25264                              <1> 	;     (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 25265                              <1> 	;     			 ZF=0 -> AX has (current) character
 25266                              <1> 	;      AL = ascii code
 25267                              <1> 	;      AH = scan code	(AH = line status for COM1 or COM2)	 			
 25268                              <1> 	; 		        (cf=1 -> error code/flags in AH)
 25269                              <1> 	; Original UNIX V1 'getc': 
 25270                              <1> 	;		get a character off character list
 25271                              <1> 	;
 25272                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))	
 25273                              <1> 	;
 25274                              <1> 	; 30/06/20045 (32 bit modifications)
 25275                              <1> 	; 16/07/2013
 25276                              <1> 	; mov 	[getctty], ah
 25277                              <1> 	;
 25278                              <1> 
 25279 0000636D 8A25[2D700000]      <1> 	mov	ah, [u.ttyn] 	; 28/07/2013
 25280                              <1> getc_n:
 25281                              <1> 	; 30/06/2015
 25282 00006373 08E4                <1> 	or	ah, ah
 25283 00006375 740D                <1> 	jz	short getc0 
 25284 00006377 D0E4                <1> 	shl	ah, 1
 25285 00006379 0FB6DC              <1> 	movzx	ebx, ah
 25286 0000637C 81C3[286F0000]      <1> 	add	ebx, ttychr
 25287 00006382 EB05                <1> 	jmp	short getc1
 25288                              <1> getc0:
 25289 00006384 BB[286F0000]        <1> 	mov	ebx, ttychr
 25290                              <1> getc1:
 25291 00006389 668B0B              <1> 	mov	cx, [ebx] 	; ascii & scan code
 25292                              <1> 				; (by kb_int)	
 25293 0000638C 6609C9              <1> 	or	cx, cx
 25294 0000638F 7507                <1> 	jnz	short getc2
 25295 00006391 20C0                <1> 	and 	al, al
 25296 00006393 7415                <1> 	jz	short getc_s
 25297                              <1> 	;xor	ax, ax
 25298                              <1> 	; 30/11/2021
 25299 00006395 31C0                <1> 	xor	eax, eax
 25300 00006397 C3                  <1> 	retn
 25301                              <1> getc2:	
 25302 00006398 20C0                <1> 	and	al, al
 25303 0000639A 6689C8              <1> 	mov	ax, cx
 25304 0000639D 66B90000            <1> 	mov	cx, 0
 25305 000063A1 7506                <1> 	jnz	short getc3
 25306                              <1> getc_sn:
 25307 000063A3 66890B              <1> 	mov	[ebx], cx ; 0, reset
 25308 000063A6 6639C8              <1> 	cmp	ax, cx  ; zf = 0
 25309                              <1> getc3:
 25310 000063A9 C3                  <1> 	retn
 25311                              <1> getc_s:
 25312                              <1> 	; 12/11/2015
 25313                              <1> 	; 15/09/2015
 25314                              <1> 	; 01/07/2015
 25315                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 25316                              <1> 	; 16/07/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 25317                              <1> 	;
 25318                              <1> 	; tty  of the current process is not 
 25319                              <1> 	; current tty (ptty); so, current process only 
 25320                              <1> 	; can use keyboard input when its tty becomes 
 25321                              <1> 	; current tty (ptty).
 25322                              <1> 	; 'sleep' is for preventing an endless lock
 25323                              <1> 	; during this tty input request.
 25324                              <1> 	; (Because, the user is not looking at the video page
 25325                              <1> 	; of the process to undersand there is a keyboard
 25326                              <1> 	; input request.)
 25327                              <1> 	;
 25328                              <1> 	;((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 25329                              <1> 	;
 25330                              <1> 	; 05/10/2013
 25331                              <1> 	; ah = byte ptr [u.ttyn] ; (tty number)
 25332                              <1> 	;
 25333                              <1> 	; 10/10/2013
 25334                              <1> gcw0:
 25335 000063AA B10A                <1> 	mov	cl, 10 ; ch = 0
 25336                              <1> gcw1:	
 25337                              <1> 	; 12/11/2015
 25338 000063AC E8C1D9FFFF          <1> 	call intract ; jumps to 'sysexit' if [u.quit] = FFFFh
 25339                              <1> 	; 10/10/2013
 25340 000063B1 E8DAECFFFF          <1> 	call	idle
 25341 000063B6 668B03              <1> 	mov	ax, [ebx] 	; ascii & scan code
 25342                              <1> 				; (by kb_int)
 25343 000063B9 6609C0              <1> 	or	ax, ax
 25344                              <1> ;	jnz	short gcw3
 25345 000063BC 7519                <1> 	jnz	short gcw2 ; 15/09/2015
 25346                              <1> 	; 30/06/2015
 25347 000063BE FEC9                <1> 	dec	cl
 25348 000063C0 75EA                <1> 	jnz	short gcw1
 25349                              <1> 	;
 25350 000063C2 8A25[2D700000]      <1> 	mov	ah, [u.ttyn] 	; 20/10/2013
 25351                              <1> ;	; 10/12/2013
 25352                              <1> ;	cmp 	ah, [ptty]
 25353                              <1> ;	jne	short gcw2
 25354                              <1> ;	; 14/02/2014
 25355                              <1> ;	cmp	byte [u.uno], 1
 25356                              <1> ;	jna	short gcw0		
 25357                              <1> ;gcw2:
 25358 000063C8 E857EDFFFF          <1> 	call	sleep
 25359                              <1> 	;
 25360                              <1> 	; 20/09/2013
 25361 000063CD 8A25[2D700000]      <1> 	mov	ah, [u.ttyn]
 25362 000063D3 30C0                <1> 	xor 	al, al
 25363 000063D5 EB9C                <1> 	jmp	short getc_n
 25364                              <1> ;gcw3:
 25365                              <1> gcw2: 	; 15/09/2015
 25366                              <1> 	; 10/10/2013
 25367 000063D7 30C9                <1> 	xor	cl, cl
 25368 000063D9 EBC8                <1> 	jmp	short getc_sn
 25369                              <1> 
 25370                              <1> sndc:   ; <Send character>
 25371                              <1> 	;
 25372                              <1> 	; 17/11/2015
 25373                              <1> 	; 16/11/2015
 25374                              <1> 	; 11/11/2015
 25375                              <1> 	; 10/11/2015
 25376                              <1> 	; 09/11/2015
 25377                              <1> 	; 08/11/2015
 25378                              <1> 	; 07/11/2015
 25379                              <1> 	; 06/11/2015 (serial4.asm, 'sendchr')	
 25380                              <1> 	; 29/10/2015
 25381                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 25382                              <1> 	; 14/05/2013 - 28/07/2014 (Retro UNIX 8086 v1)
 25383                              <1> 	;
 25384                              <1> 	; Retro UNIX 8086 v1 feature only !
 25385                              <1> 	;
 25386                              <1> 	; ah = [u.ttyn]
 25387                              <1> 	;
 25388                              <1> 	; 30/06/2015
 25389 000063DB 80EC08              <1> 	sub	ah, 8 ; ; 0 = tty8 or 1 = tty9
 25390                              <1> 	; 07/11/2015
 25391 000063DE 0FB6DC              <1> 	movzx	ebx, ah ; serial port index (0 or 1)
 25392                              <1> sndc0:
 25393                              <1> 	; 07/11/2015
 25394 000063E1 E897EDFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 25395 000063E6 7405                <1> 	jz	short sndc1
 25396 000063E8 E885D9FFFF          <1> 	call	intract ; quit (ctrl+break) check
 25397                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 25398                              <1> sndc1:
 25399                              <1> 	; 16/11/2015
 25400 000063ED 6689C1              <1> 	mov	cx, ax	; *** al = character (to be sent)
 25401                              <1> sndcx:
 25402 000063F0 8A83[6A6F0000]      <1> 	mov	al, [ebx+schar] ; last sent character
 25403 000063F6 8AA3[686F0000]      <1> 	mov	ah, [ebx+rchar] ; last received character
 25404                              <1> 	;
 25405                              <1> 	; 17/11/2015
 25406                              <1> 	; check 'request for response' status
 25407 000063FC 80BB[646F0000]00    <1> 	cmp	byte [ebx+req_resp], 0
 25408 00006403 740A                <1> 	jz	short query
 25409                              <1> response:
 25410 00006405 FE05[676F0000]      <1> 	inc 	byte [comqr] ; query or response status
 25411 0000640B B0FF                <1> 	mov	al, 0FFh	 
 25412 0000640D EB14                <1> 	jmp	short sndc3
 25413                              <1> query:
 25414 0000640F 08C0                <1> 	or 	al, al  ; 0 = query (also end of text)
 25415 00006411 750E                <1> 	jnz 	short sndc2 ; normal character
 25416                              <1> 	;cmp 	ah, 0FFh     ; is it responded by terminal ?
 25417                              <1> 	;je	short sndc2  ; yes, already responded
 25418                              <1> 	; 16/11/2015
 25419                              <1> 	; query: request for response (again)
 25420 00006413 8883[686F0000]      <1> 	mov	[ebx+rchar], al ; 0 ; reset
 25421 00006419 FE05[676F0000]      <1> 	inc 	byte [comqr] ; query or response status
 25422 0000641F EB02                <1> 	jmp	short sndc3
 25423                              <1> sndc2:
 25424 00006421 88C8                <1> 	mov	al, cl 	; *** character (to be sent)
 25425                              <1> sndc3:
 25426 00006423 8883[6A6F0000]      <1> 	mov	[ebx+schar], al ; current character (to be sent)
 25427 00006429 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 25428                              <1> 	; 30/06/2015
 25429 0000642B E8E8D2FFFF          <1> 	call	sp_status ; get serial port status
 25430                              <1> 	; AL = Line status, AH = Modem status
 25431                              <1> 	; 07/11/2015
 25432 00006430 A880                <1> 	test	al, 80h
 25433 00006432 7504                <1> 	jnz	short sndc4
 25434 00006434 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 25435 00006436 751D                <1> 	jnz	short sndc5
 25436                              <1> sndc4: 	; Check line status again
 25437                              <1> 	; 16/11/2015
 25438 00006438 6651                <1> 	push	cx
 25439 0000643A B906000000          <1> 	mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 25440 0000643F E8D8B0FFFF          <1> 	call	WAITF
 25441 00006444 6659                <1> 	pop	cx
 25442                              <1> 	;
 25443 00006446 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 25444 00006448 E8CBD2FFFF          <1> 	call	sp_status ; get serial port status
 25445                              <1> 	; 16/11/2015
 25446                              <1> 	; 09/11/2015
 25447                              <1> 	; 08/11/2015
 25448 0000644D A880                <1> 	test	al, 80h	; time out error
 25449 0000644F 756C                <1>         jnz     short sndc7
 25450 00006451 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 25451 00006453 7468                <1>         jz	short sndc7
 25452                              <1> sndc5:  
 25453 00006455 8A83[6A6F0000]      <1> 	mov	al, [ebx+schar] ; character (to be sent)
 25454 0000645B 66BAF803            <1> 	mov	dx, 3F8h   ; data port (COM2)
 25455 0000645F 28DE                <1> 	sub	dh, bl
 25456 00006461 EE                  <1> 	out	dx, al	   ; send on serial port
 25457                              <1> 	; 10/11/2015
 25458                              <1> 	; delay for 3*30 (3*(15..80)) micro seconds
 25459                              <1> 	; (to improve text flow to the terminal)
 25460                              <1> 	; ('diskette.inc': 'WAITF')
 25461                              <1> 	; Uses port 61h, bit 4 to have CPU speed independent waiting.
 25462                              <1> 	; (refresh periods = 1 per 30 microseconds on most machines)
 25463 00006462 6651                <1> 	push	cx 
 25464 00006464 B906000000          <1> 	mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 25465 00006469 E8AEB0FFFF          <1> 	call	WAITF
 25466 0000646E 6659                <1> 	pop	cx
 25467                              <1>     	;
 25468                              <1> 	; 07/11/2015
 25469 00006470 88D8                <1> 	mov	al, bl ; al = 0 (tty8) or 1 (tty9)
 25470                              <1> 	;
 25471 00006472 E8A1D2FFFF          <1> 	call	sp_status ; get serial port status
 25472                              <1> 	; AL = Line status, AH = Modem status
 25473                              <1> 	;
 25474 00006477 E801EDFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 25475 0000647C 7405                <1> 	jz	short sndc6
 25476 0000647E E8EFD8FFFF          <1> 	call	intract ; quit (ctrl+break) check
 25477                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 25478                              <1> sndc6:
 25479 00006483 3C80                <1> 	cmp	al, 80h
 25480 00006485 7336                <1> 	jnb	short sndc7		
 25481                              <1> 	;
 25482 00006487 803D[676F0000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 25483 0000648E 7248                <1> 	jb	short sndc8 	; no, normal character
 25484 00006490 883D[676F0000]      <1> 	mov 	byte [comqr], bh ; 0 ; reset
 25485                              <1> 	; 17/11/2015
 25486 00006496 E8F5EBFFFF          <1> 	call	idle
 25487                              <1> 	;
 25488 0000649B 38BB[6A6F0000]      <1> 	cmp	[ebx+schar], bh ; 0 ; query ?
 25489 000064A1 0F877AFFFFFF        <1>         ja      sndc2       ; response (will be followed by
 25490                              <1> 			    ; a normal character)
 25491                              <1> 	; Query request must be responded by the terminal
 25492                              <1> 	; before sending a normal character !
 25493 000064A7 53                  <1> 	push	ebx
 25494 000064A8 6651                <1> 	push	cx ; *** cl = character (to be sent)
 25495 000064AA 8A25[2D700000]      <1> 	mov	ah, [u.ttyn]
 25496 000064B0 E86FECFFFF          <1> 	call	sleep ; this process will be awakened by
 25497                              <1> 		      ; received data available interrupt
 25498 000064B5 6659                <1> 	pop	cx ; *** cl = character (to be sent)
 25499 000064B7 5B                  <1> 	pop	ebx
 25500 000064B8 E933FFFFFF          <1>         jmp	sndcx
 25501                              <1> sndc7:
 25502                              <1> 	 ; 16/11/2015
 25503 000064BD 803D[676F0000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 25504 000064C4 7213                <1> 	jb	short sndc9 	; no
 25505                              <1> 	;
 25506 000064C6 88BB[686F0000]      <1> 	mov	[ebx+rchar], bh ; 0 ; reset
 25507 000064CC 88BB[6A6F0000]      <1> 	mov	[ebx+schar], bh ; 0 ; reset
 25508                              <1> 	;
 25509 000064D2 883D[676F0000]      <1> 	mov	byte [comqr], bh ; 0 ; reset  
 25510                              <1> sndc8:
 25511 000064D8 F5                  <1> 	cmc  ; jnc -> jc, jb -> jnb
 25512                              <1> sndc9:
 25513                              <1> 	; AL = Line status, AH = Modem status
 25514 000064D9 C3                  <1> 	retn
 25515                              <1> 
 25516                              <1> putc:	
 25517                              <1> 	; 13/08/2015
 25518                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 25519                              <1> 	; 15/05/2013 - 27/07/2014 (Retro UNIX 8086 v1)
 25520                              <1> 	;
 25521                              <1> 	; Retro UNIX 8086 v1 modification !
 25522                              <1> 	; 
 25523                              <1> 	; 'putc' puts a character 
 25524                              <1> 	;	 onto requested (tty) video page or
 25525                              <1> 	;	 serial port
 25526                              <1> 	; INPUTS ->
 25527                              <1> 	;     AL = ascii code of the character
 25528                              <1> 	;     AH = video page (tty) number (0 to 7)
 25529                              <1> 	;			  (8 is COM1, 9 is COM2)	
 25530                              <1> 	; OUTPUTS ->
 25531                              <1> 	;    (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 25532                              <1> 	;      			ZF=0 -> AX has (current) character
 25533                              <1> 	;     cf=0 and AH = 0 -> no error
 25534                              <1> 	;     cf=1 and AH > 0 -> error (only for COM1 and COM2)		 			
 25535                              <1> 	; 
 25536                              <1> 	; Original UNIX V1 'putc': 
 25537                              <1> 	;     put a character at the end of character list
 25538                              <1> 	;
 25539                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 25540                              <1> 	;
 25541 000064DA 80FC07              <1> 	cmp	ah, 7
 25542 000064DD 0F87F8FEFFFF        <1>         ja      sndc
 25543                              <1> 	; 30/06/2015
 25544 000064E3 0FB6DC              <1> 	movzx	ebx, ah
 25545                              <1> 	; 13/08/2015
 25546 000064E6 B407                <1> 	mov	ah, 07h ; black background, light gray character color
 25547 000064E8 E920AFFFFF          <1> 	jmp	write_tty ; 'video.inc'
 25548                              <1> 
 25549                              <1> get_cpos:
 25550                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 25551                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 25552                              <1> 	;
 25553                              <1> 	; INPUT -> bl = video page number
 25554                              <1> 	; RETURN -> dx = cursor position
 25555                              <1> 
 25556 000064ED 53                  <1> 	push	ebx
 25557 000064EE 83E30F              <1> 	and	ebx, 0Fh ; 07h ; tty0 to tty7
 25558 000064F1 D0E3                <1> 	shl	bl, 1
 25559 000064F3 81C3[166F0000]      <1> 	add	ebx, cursor_posn
 25560 000064F9 668B13              <1> 	mov	dx, [ebx]
 25561 000064FC 5B                  <1> 	pop	ebx
 25562 000064FD C3                  <1> 	retn
 25563                              <1> 
 25564                              <1> read_ac_current:
 25565                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 25566                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 25567                              <1> 	;
 25568                              <1> 	; INPUT -> bl = video page number
 25569                              <1> 	; RETURN -> ax = character (al) and attribute (ah)
 25570                              <1> 
 25571 000064FE E88BB0FFFF          <1> 	call 	find_position ; 'video.inc'
 25572                              <1> 	; dx = status port
 25573                              <1> 	; esi = cursor location/address
 25574 00006503 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
 25575 00006509 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
 25576 0000650C C3                  <1> 	retn
 25577                              <1> 
 25578                              <1> syssleep:
 25579                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
 25580                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
 25581                              <1> 	;
 25582                              <1> 	; Retro UNIX 8086 v1 feature only
 25583                              <1> 	; (INPUT -> none)
 25584                              <1> 	;
 25585 0000650D 0FB61D[49700000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 25586 00006514 8AA3[2F6D0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 25587 0000651A E805ECFFFF          <1> 	call	sleep
 25588 0000651F E96ED7FFFF          <1> 	jmp	sysret
 25589                              <1> 
 25590                              <1> vp_clr:
 25591                              <1> 	; Reset/Clear Video Page
 25592                              <1> 	;
 25593                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
 25594                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
 25595                              <1> 	;
 25596                              <1> 	; Retro UNIX 8086 v1 feature only !
 25597                              <1> 	;
 25598                              <1> 	; INPUTS -> 
 25599                              <1> 	;   BL = video page number	 
 25600                              <1> 	;
 25601                              <1> 	; OUTPUT ->
 25602                              <1> 	;   none
 25603                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
 25604                              <1> 	;
 25605                              <1> 	; 04/12/2013
 25606 00006524 28C0                <1> 	sub	al, al
 25607                              <1> 	; al = 0 (clear video page)
 25608                              <1> 	; bl = video page
 25609 00006526 B407                <1> 	mov	ah, 07h
 25610                              <1> 	; ah = 7 (attribute/color)
 25611 00006528 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
 25612 0000652B 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
 25613 0000652F E886B0FFFF          <1> 	call	scroll_up
 25614                              <1> 	; bl = video page
 25615 00006534 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
 25616 00006537 E9F5AFFFFF          <1> 	jmp 	set_cpos
 25617                              <1> 
 25618                              <1> sysmsg:
 25619                              <1> 	; 11/11/2015
 25620                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
 25621                              <1> 	; Print user-application message on user's console tty
 25622                              <1> 	;
 25623                              <1> 	; Input -> EBX = Message address
 25624                              <1> 	;	   ECX = Message length (max. 255)
 25625                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
 25626                              <1> 	;
 25627 0000653C 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
 25628 00006542 0F874AD7FFFF        <1> 	ja	sysret ; nothing to do with big message size
 25629 00006548 08C9                <1> 	or	cl, cl
 25630 0000654A 0F8442D7FFFF        <1> 	jz	sysret
 25631 00006550 20D2                <1> 	and	dl, dl
 25632 00006552 7502                <1> 	jnz	short sysmsg0
 25633 00006554 B207                <1> 	mov	dl, 07h ; default color
 25634                              <1> 		; (black background, light gray character) 
 25635                              <1> sysmsg0:
 25636 00006556 891D[1C700000]      <1> 	mov	[u.base], ebx
 25637 0000655C 8815[276F0000]      <1> 	mov	[ccolor], dl ; color attributes
 25638 00006562 89E5                <1> 	mov	ebp, esp
 25639 00006564 31DB                <1> 	xor	ebx, ebx ; 0
 25640 00006566 891D[24700000]      <1> 	mov	[u.nread], ebx ; 0
 25641                              <1> 	;
 25642 0000656C 381D[68700000]      <1> 	cmp	[u.kcall], bl ; 0
 25643 00006572 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
 25644                              <1> 	;
 25645 00006574 890D[20700000]      <1> 	mov	[u.count], ecx
 25646 0000657A 41                  <1> 	inc	ecx ; + 00h ; ASCIZZ
 25647 0000657B 29CC                <1> 	sub	esp, ecx
 25648 0000657D 89E7                <1> 	mov	edi, esp
 25649 0000657F 89E6                <1> 	mov	esi, esp
 25650 00006581 66891D[64700000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
 25651                              <1> 	; 11/11/2015
 25652 00006588 8A25[2E700000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
 25653                              <1> 	; 0 = none
 25654 0000658E FECC                <1> 	dec	ah
 25655 00006590 790C                <1> 	jns	short sysmsg1 
 25656 00006592 8A1D[49700000]      <1> 	mov	bl, [u.uno] ; process number	
 25657 00006598 8AA3[2F6D0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
 25658                              <1> sysmsg1:
 25659 0000659E 8825[2D700000]      <1> 	mov	[u.ttyn], ah
 25660                              <1> sysmsg2:
 25661 000065A4 E85EF5FFFF          <1> 	call	cpass
 25662 000065A9 7416                <1> 	jz	short sysmsg5
 25663 000065AB AA                  <1> 	stosb
 25664 000065AC 20C0                <1> 	and	al, al
 25665 000065AE 75F4                <1> 	jnz	short sysmsg2
 25666                              <1> sysmsg3:
 25667 000065B0 80FC07              <1> 	cmp	ah, 7 ; tty number
 25668 000065B3 7711                <1> 	ja	short sysmsg6 ; serial port
 25669 000065B5 E83E000000          <1> 	call	print_cmsg
 25670                              <1> sysmsg4:
 25671 000065BA 89EC                <1> 	mov	esp, ebp	
 25672 000065BC E9D1D6FFFF          <1> 	jmp	sysret
 25673                              <1> sysmsg5:
 25674 000065C1 C60700              <1> 	mov	byte [edi], 0
 25675 000065C4 EBEA                <1> 	jmp	short sysmsg3
 25676                              <1> sysmsg6:
 25677 000065C6 8A06                <1> 	mov	al, [esi]
 25678 000065C8 E80EFEFFFF          <1> 	call	sndc
 25679 000065CD 72EB                <1> 	jc	short sysmsg4
 25680 000065CF 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
 25681 000065D2 76E6                <1> 	jna	short sysmsg4
 25682 000065D4 46                  <1> 	inc 	esi
 25683 000065D5 8A25[2D700000]      <1> 	mov	ah, [u.ttyn]
 25684 000065DB EBE9                <1> 	jmp	short sysmsg6
 25685                              <1> 
 25686                              <1> sysmsgk: ; Temporary (01/07/2015)
 25687                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
 25688                              <1> 	; (ECX -character count- will not be considered)
 25689 000065DD 8B35[1C700000]      <1> 	mov	esi, [u.base]
 25690 000065E3 8A25[266F0000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
 25691 000065E9 8825[2D700000]      <1> 	mov	[u.ttyn], ah
 25692 000065EF C605[68700000]00    <1> 	mov	byte [u.kcall], 0
 25693 000065F6 EBB8                <1> 	jmp	short sysmsg3
 25694                              <1> 	
 25695                              <1> print_cmsg: 
 25696                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
 25697                              <1> 	;
 25698                              <1> 	; print message (on user's console tty) 
 25699                              <1> 	;	with requested color
 25700                              <1> 	;
 25701                              <1> 	; INPUTS:
 25702                              <1> 	;	esi = message address
 25703                              <1> 	;	[u.ttyn] = tty number (0 to 7)
 25704                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
 25705                              <1> 	;
 25706 000065F8 AC                  <1> 	lodsb
 25707                              <1> pcmsg1:
 25708 000065F9 56                  <1> 	push 	esi
 25709 000065FA 0FB61D[2D700000]    <1>         movzx   ebx, byte [u.ttyn]
 25710 00006601 8A25[276F0000]      <1> 	mov	ah, [ccolor]
 25711 00006607 E801AEFFFF          <1> 	call 	write_tty
 25712 0000660C 5E                  <1> 	pop	esi
 25713 0000660D AC                  <1> 	lodsb
 25714 0000660E 20C0                <1> 	and 	al, al  ; 0
 25715 00006610 75E7                <1> 	jnz 	short pcmsg1
 25716 00006612 C3                  <1> 	retn
 25717                              <1> 
 25718                              <1> sysgeterr:
 25719                              <1> 	; 09/12/2015
 25720                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
 25721                              <1> 	; Get last error number or page fault count
 25722                              <1> 	; (for debugging)
 25723                              <1> 	;
 25724                              <1> 	; Input -> EBX = return type
 25725                              <1> 	;	   0 = last error code (which is in 'u.error')	
 25726                              <1> 	;	   FFFFFFFFh = page fault count for running process
 25727                              <1> 	;	   FFFFFFFEh = total page fault count
 25728                              <1> 	;	   1 .. FFFFFFFDh = undefined 
 25729                              <1> 	;
 25730                              <1> 	; Output -> EAX = last error number or page fault count
 25731                              <1> 	;	   (depending on EBX input)
 25732                              <1> 	; 	
 25733 00006613 21DB                <1> 	and 	ebx, ebx
 25734 00006615 750B                <1> 	jnz	short glerr_2
 25735                              <1> glerr_0:
 25736 00006617 A1[6A700000]        <1> 	mov	eax, [u.error]
 25737                              <1> glerr_1:
 25738 0000661C A3[F46F0000]        <1> 	mov	[u.r0], eax
 25739 00006621 C3                  <1>  	retn
 25740                              <1> glerr_2:
 25741 00006622 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
 25742 00006623 74FD                <1> 	jz	short glerr_2 ; page fault count for process
 25743 00006625 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
 25744 00006626 75EF                <1> 	jnz	short glerr_0
 25745 00006628 A1[88810000]        <1> 	mov	eax, [PF_Count] ; total page fault count
 25746 0000662D EBED                <1>         jmp     short glerr_1
 25747                              <1> glerr_3:
 25748 0000662F A1[6E700000]        <1> 	mov 	eax, [u.pfcount]
 25749 00006634 EBE6                <1> 	jmp	short glerr_1
 25750                                  
 25751                                  ; 07/03/2015
 25752                                  ; Temporary Code
 25753                                  display_disks:
 25754 00006636 803D[EE690000]00        	cmp 	byte [fd0_type], 0
 25755 0000663D 7605                    	jna 	short ddsks1
 25756 0000663F E87D000000              	call	pdskm
 25757                                  ddsks1:
 25758 00006644 803D[EF690000]00        	cmp	byte [fd1_type], 0
 25759 0000664B 760C                    	jna	short ddsks2
 25760 0000664D C605[DF6B0000]31        	mov	byte [dskx], '1'
 25761 00006654 E868000000              	call	pdskm
 25762                                  ddsks2:
 25763 00006659 803D[F0690000]00        	cmp	byte [hd0_type], 0
 25764 00006660 7654                    	jna	short ddsk6
 25765 00006662 66C705[DD6B0000]68-     	mov	word [dsktype], 'hd'
 25766 0000666A 64                 
 25767 0000666B C605[DF6B0000]30        	mov	byte [dskx], '0'
 25768 00006672 E84A000000              	call	pdskm
 25769                                  ddsks3:
 25770 00006677 803D[F1690000]00        	cmp	byte [hd1_type], 0
 25771 0000667E 7636                    	jna	short ddsk6
 25772 00006680 C605[DF6B0000]31        	mov	byte [dskx], '1'
 25773 00006687 E835000000              	call	pdskm
 25774                                  ddsks4:
 25775 0000668C 803D[F2690000]00        	cmp	byte [hd2_type], 0
 25776 00006693 7621                    	jna	short ddsk6
 25777 00006695 C605[DF6B0000]32        	mov	byte [dskx], '2'
 25778 0000669C E820000000              	call	pdskm
 25779                                  ddsks5:
 25780 000066A1 803D[F3690000]00        	cmp	byte [hd3_type], 0
 25781 000066A8 760C                    	jna	short ddsk6
 25782 000066AA C605[DF6B0000]33        	mov	byte [dskx], '3'
 25783 000066B1 E80B000000              	call	pdskm
 25784                                  ddsk6:
 25785 000066B6 BE[EE6B0000]            	mov	esi, nextline
 25786 000066BB E806000000              	call	pdskml
 25787                                  pdskm_ok:
 25788 000066C0 C3                      	retn
 25789                                  pdskm:
 25790 000066C1 BE[DB6B0000]            	mov	esi, dsk_ready_msg
 25791                                  pdskml:	
 25792 000066C6 AC                      	lodsb
 25793 000066C7 08C0                    	or	al, al
 25794 000066C9 74F5                    	jz	short pdskm_ok
 25795 000066CB 56                      	push	esi
 25796 000066CC 31DB                    	xor	ebx, ebx ; 0
 25797                                  			; Video page 0 (bl=0)
 25798 000066CE B407                    	mov	ah, 07h ; Black background, 
 25799                                  			; light gray forecolor
 25800 000066D0 E838ADFFFF              	call	write_tty
 25801 000066D5 5E                      	pop	esi
 25802 000066D6 EBEE                    	jmp	short pdskml
 25803                                  
 25804 000066D8 90<rept>                align 16
 25805                                  
 25806                                  gdt:	; Global Descriptor Table
 25807                                  	; (30/07/2015, conforming cs)
 25808                                  	; (26/03/2015)
 25809                                  	; (24/03/2015, tss)
 25810                                  	; (19/03/2015)
 25811                                  	; (29/12/2013)
 25812                                  	;
 25813 000066E0 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
 25814                                  	; 18/08/2014
 25815                                  			; 8h kernel code segment, base = 00000000h		
 25816 000066E8 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
 25817                                  			; 10h kernel data segment, base = 00000000h	
 25818 000066F0 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
 25819                                  			; 1Bh user code segment, base address = 400000h ; CORE
 25820 000066F8 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
 25821                                  			; 23h user data segment, base address = 400000h ; CORE
 25822 00006700 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
 25823                                  			; Task State Segment
 25824 00006708 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
 25825                                  			       ;  no IO permission in ring 3)
 25826                                  gdt_tss0:
 25827 0000670A 0000                    	dw 0  ; TSS base address, bits 0-15 
 25828                                  gdt_tss1:
 25829 0000670C 00                      	db 0  ; TSS base address, bits 16-23 
 25830                                  	      		; 49h	
 25831 0000670D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
 25832 0000670E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
 25833                                  gdt_tss2:
 25834 0000670F 00                      	db 0  ; TSS base address, bits 24-31 
 25835                                  
 25836                                  gdt_end:
 25837                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 25838                                  					;; Type= 1 (code)/C=0/R=1/A=0
 25839                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 25840                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 25841                                  
 25842                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 25843                                  					;; Type= 0 (data)/E=0/W=1/A=0
 25844                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 25845                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 25846                                  		; W= Writeable, A= Accessed
 25847                                  	
 25848                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
 25849                                  					;; Type= 1 (code)/C=0/R=1/A=0
 25850                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 25851                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 25852                                  
 25853                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
 25854                                  					;; Type= 0 (data)/E=0/W=1/A=0
 25855                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 25856                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 25857                                  	
 25858                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
 25859                                  
 25860                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
 25861                                  		;	 = 100000h * 1000h (G=1) = 4GB
 25862                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
 25863                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
 25864                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
 25865                                  		; AVL= Available to programmers	
 25866                                  
 25867                                  gdtd:
 25868 00006710 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
 25869 00006712 [E0660000]                      dd gdt			; Address of the GDT
 25870                                  
 25871                                  	; 20/08/2014
 25872                                  idtd:
 25873 00006716 FF01                            dw idt_end - idt - 1    ; Limit (size)
 25874 00006718 [906C0000]                      dd idt			; Address of the IDT
 25875                                  
 25876                                  Align 4
 25877                                  
 25878                                  	; 21/08/2014
 25879                                  ilist:
 25880                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
 25881                                  	;
 25882                                  	; Exception list
 25883                                  	; 25/08/2014	
 25884 0000671C [24080000]              	dd	exc0	; 0h,  Divide-by-zero Error
 25885 00006720 [2B080000]              	dd	exc1	
 25886 00006724 [32080000]              	dd 	exc2	
 25887 00006728 [39080000]              	dd	exc3	
 25888 0000672C [3D080000]              	dd	exc4	
 25889 00006730 [41080000]              	dd	exc5	
 25890 00006734 [45080000]              	dd 	exc6	; 06h,  Invalid Opcode
 25891 00006738 [49080000]              	dd	exc7	
 25892 0000673C [4D080000]              	dd	exc8	
 25893 00006740 [51080000]              	dd	exc9	
 25894 00006744 [55080000]              	dd 	exc10	
 25895 00006748 [59080000]              	dd	exc11
 25896 0000674C [5D080000]              	dd	exc12
 25897 00006750 [61080000]              	dd	exc13	; 0Dh, General Protection Fault
 25898 00006754 [65080000]              	dd 	exc14	; 0Eh, Page Fault
 25899 00006758 [69080000]              	dd	exc15
 25900 0000675C [6D080000]              	dd	exc16
 25901 00006760 [71080000]              	dd	exc17
 25902 00006764 [75080000]              	dd 	exc18
 25903 00006768 [79080000]              	dd	exc19
 25904 0000676C [7D080000]              	dd 	exc20
 25905 00006770 [81080000]              	dd	exc21
 25906 00006774 [85080000]              	dd	exc22
 25907 00006778 [89080000]              	dd	exc23
 25908 0000677C [8D080000]              	dd 	exc24
 25909 00006780 [91080000]              	dd	exc25
 25910 00006784 [95080000]              	dd	exc26
 25911 00006788 [99080000]              	dd	exc27
 25912 0000678C [9D080000]              	dd 	exc28
 25913 00006790 [A1080000]              	dd	exc29
 25914 00006794 [A5080000]              	dd 	exc30
 25915 00006798 [A9080000]              	dd	exc31
 25916                                  	; Interrupt list
 25917 0000679C [5A060000]              	dd	timer_int	; INT 20h
 25918                                  		;dd	irq0	
 25919 000067A0 [630B0000]              	dd	keyb_int	; 27/08/2014
 25920                                  		;dd	irq1
 25921 000067A4 [7A070000]              	dd	irq2
 25922                                  		; COM2 int
 25923 000067A8 [7E070000]              	dd	irq3
 25924                                  		; COM1 int
 25925 000067AC [89070000]              	dd	irq4
 25926 000067B0 [94070000]              	dd	irq5
 25927                                  ;DISKETTE_INT: ;06/02/2015
 25928 000067B4 [A0260000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
 25929                                  		;dd	irq6
 25930                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
 25931                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 25932 000067B8 [100B0000]              	dd	default_irq7	; 25/02/2015
 25933                                  		;dd	irq7
 25934                                  ; Real Time Clock Interrupt
 25935 000067BC [B3090000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
 25936                                  		;dd	irq8	; INT 28h
 25937 000067C0 [A4070000]              	dd	irq9
 25938 000067C4 [A8070000]              	dd	irq10
 25939 000067C8 [AC070000]              	dd	irq11
 25940 000067CC [B0070000]              	dd	irq12
 25941 000067D0 [B4070000]              	dd	irq13
 25942                                  ;HDISK_INT1:  ;06/02/2015 	
 25943 000067D4 [DC2E0000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
 25944                                  		;dd	irq14
 25945                                  ;HDISK_INT2:  ;06/02/2015
 25946 000067D8 [032F0000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
 25947                                  		;dd	irq15	; INT 2Fh
 25948                                  		; 14/08/2015
 25949 000067DC [763B0000]              	dd	sysent		; INT 30h (system calls)
 25950                                  	
 25951                                  	;dd	ignore_int
 25952 000067E0 00000000                	dd	0
 25953                                  
 25954                                  ;;;
 25955                                  ;;; 11/03/2015
 25956                                  %include 'kybdata.s'	; KEYBOARD (BIOS) DATA
 25957                              <1> ; Retro UNIX 386 v1 Kernel - KYBDATA.INC
 25958                              <1> ; Last Modification: 11/03/2015
 25959                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
 25960                              <1> ;
 25961                              <1> ; ///////// KEYBOARD DATA ///////////////
 25962                              <1> 
 25963                              <1> ; 05/12/2014
 25964                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
 25965                              <1> ; 03/06/86  KEYBOARD BIOS
 25966                              <1> 
 25967                              <1> ;---------------------------------------------------------------------------------
 25968                              <1> ;	KEY IDENTIFICATION SCAN TABLES
 25969                              <1> ;---------------------------------------------------------------------------------
 25970                              <1> 
 25971                              <1> ;-----	TABLES FOR ALT CASE ------------
 25972                              <1> ;-----	ALT-INPUT-TABLE 
 25973 000067E4 524F50514B          <1> K30:	db	82,79,80,81,75
 25974 000067E9 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
 25975                              <1> ;-----	SUPER-SHIFT-TABLE 
 25976 000067EE 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
 25977 000067F4 161718191E1F        <1> 	db	22,23,24,25,30,31
 25978 000067FA 202122232425        <1> 	db	32,33,34,35,36,37
 25979 00006800 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
 25980 00006806 3132                <1> 	db	49,50
 25981                              <1> 
 25982                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
 25983                              <1> ;-----	KEY_TABLE 
 25984 00006808 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
 25985 00006809 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
 25986 0000680E 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
 25987                              <1> _K6L    equ     $-_K6
 25988                              <1> 
 25989                              <1> ;-----	MASK_TABLE
 25990 00006810 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
 25991 00006811 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
 25992 00006816 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
 25993                              <1> 
 25994                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
 25995 00006818 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
 25996 0000681E 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
 25997 00006824 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
 25998 0000682A 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
 25999 00006830 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
 26000 00006836 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
 26001 0000683C 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
 26002 00006842 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
 26003 00006848 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
 26004 0000684E 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
 26005                              <1> 	;				;----- FUNCTIONS ------		
 26006 00006852 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
 26007 00006858 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
 26008 0000685E 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
 26009 00006864 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
 26010 0000686A 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
 26011                              <1> 
 26012                              <1> ;-----	TABLES FOR LOWER CASE ----------
 26013 00006870 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
 26014 00006879 39302D3D0809        <1>
 26015 0000687F 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
 26016 00006888 705B5D0DFF61736466- <1>
 26017 00006891 67686A6B6C3B27      <1>
 26018 00006898 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
 26019 000068A1 6D2C2E2FFF2AFF20FF  <1>
 26020                              <1> ;-----	LC TABLE SCAN
 26021 000068AA 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
 26022 000068AF 4041424344          <1> 	db	64,65,66,67,68
 26023 000068B4 FFFF                <1> 	db	-1,-1			; NL, SL
 26024                              <1> 
 26025                              <1> ;-----	KEYPAD TABLE
 26026 000068B6 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
 26027 000068BC 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
 26028 000068C3 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
 26029                              <1> 
 26030                              <1> ;-----	TABLES FOR UPPER CASE ----------
 26031 000068C8 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
 26032 000068D1 28295F2B0800        <1>
 26033 000068D7 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
 26034 000068E0 507B7D0DFF41534446- <1>
 26035 000068E9 47484A4B4C3A22      <1>
 26036 000068F0 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
 26037 000068F9 4D3C3E3FFF2AFF20FF  <1>
 26038                              <1> ;-----	UC TABLE SCAN
 26039 00006902 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
 26040 00006907 595A5B5C5D          <1> 	db	89,90,91,92,93
 26041 0000690C FFFF                <1> 	db	-1,-1			; NL, SL
 26042                              <1> 
 26043                              <1> ;-----	NUM STATE TABLE
 26044 0000690E 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
 26045 00006917 3233302E            <1>
 26046                              <1> 	;
 26047 0000691B FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
 26048                              <1> 
 26049                              <1> Align	4
 26050                              <1> ;----------------------------------------
 26051                              <1> ;	VIDEO DISPLAY DATA AREA		;
 26052                              <1> ;----------------------------------------
 26053 00006920 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
 26054 00006921 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
 26055                              <1> 				; (29h default setting for video mode 3)
 26056                              <1> 				; Mode Select register Bits
 26057                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
 26058                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
 26059                              <1> 				;   BIT 2 - COLOR (0), BW (1)
 26060                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
 26061                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
 26062                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
 26063                              <1> 				;   BIT 6, 7 - Not Used
 26064                              <1> 
 26065                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
 26066                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
 26067                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
 26068                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
 26069                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
 26070                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
 26071                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
 26072                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
 26073                              <1> ; Mode & 37h = Video signal OFF
 26074                              <1> 			
 26075                              <1> 
 26076                              <1> ; 26/08/2014
 26077                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
 26078                              <1> ; Derived from IBM "pc-at" 
 26079                              <1> ; rombios source code (06/10/1985)
 26080                              <1> ; 'dseg.inc'
 26081                              <1> 
 26082                              <1> ;---------------------------------------;
 26083                              <1> ;	SYSTEM DATA AREA		;
 26084                              <1> ;----------------------------------------
 26085 00006922 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
 26086                              <1> 
 26087                              <1> ;----------------------------------------
 26088                              <1> ;	KEYBOARD DATA AREAS		;
 26089                              <1> ;----------------------------------------
 26090                              <1> 
 26091 00006923 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
 26092 00006924 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
 26093 00006925 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
 26094 00006926 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
 26095 00006927 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
 26096 00006928 [38690000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
 26097 0000692C [58690000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
 26098 00006930 [38690000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
 26099 00006934 [38690000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
 26100                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
 26101 00006938 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
 26102                              <1> 
 26103                              <1> ; /// End Of KEYBOARD DATA ///
 26104                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
 26105                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.INC
 26106                              <1> ; Last Modification: 11/03/2015
 26107                              <1> ;		    (Data section for 'VIDEO.INC')	
 26108                              <1> ;
 26109                              <1> ; ///////// VIDEO DATA ///////////////
 26110                              <1> 
 26111                              <1> video_params:
 26112                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
 26113                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
 26114                              <1> 	; VIDEO MODE 3
 26115 00006958 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
 26116 0000695F 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
 26117 00006964 00000000            <1> 	db	0,0,0,0
 26118                              <1> 
 26119                              <1> ; /// End Of VIDEO DATA ///
 26120                                  %include 'diskdata.s'	; DISK (BIOS) DATA (initialized)
 26121                              <1> ; Retro UNIX 386 v1 Kernel - DISKDATA.INC
 26122                              <1> ; Last Modification: 11/03/2015
 26123                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
 26124                              <1> ;
 26125                              <1> ; *****************************************************************************
 26126                              <1> 
 26127                              <1> ;----------------------------------------
 26128                              <1> ;	80286 INTERRUPT LOCATIONS	:
 26129                              <1> ;	REFERENCED BY POST & BIOS	:
 26130                              <1> ;----------------------------------------
 26131                              <1> 
 26132 00006968 [CB690000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
 26133                              <1> 
 26134                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
 26135                              <1> ;----------------------------------------------------------------
 26136                              <1> ; DISK_BASE							:
 26137                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
 26138                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
 26139                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
 26140                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
 26141                              <1> ;----------------------------------------------------------------
 26142                              <1> 
 26143                              <1> ;DISK_BASE:	
 26144                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 26145                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 26146                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 26147                              <1> ;	DB	2		; 512 BYTES/SECTOR
 26148                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
 26149                              <1> ;	db	18		; (EOT for 1.44MB diskette)
 26150                              <1> ;	DB	01BH		; GAP LENGTH
 26151                              <1> ;	DB	0FFH		; DTL
 26152                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
 26153                              <1> ;	db	06ch		; (for 1.44MB dsikette)
 26154                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
 26155                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 26156                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
 26157                              <1> 
 26158                              <1> ;----------------------------------------
 26159                              <1> ;	ROM BIOS DATA AREAS		:
 26160                              <1> ;----------------------------------------
 26161                              <1> 
 26162                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 26163                              <1> 
 26164                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
 26165                              <1> 
 26166                              <1> ;----------------------------------------
 26167                              <1> ;	DISKETTE DATA AREAS		:
 26168                              <1> ;----------------------------------------
 26169                              <1> 
 26170                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
 26171                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
 26172                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
 26173                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
 26174                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
 26175                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
 26176                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
 26177                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
 26178                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
 26179                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
 26180                              <1> 
 26181                              <1> ;----------------------------------------
 26182                              <1> ;	POST AND BIOS WORK DATA AREA	:
 26183                              <1> ;----------------------------------------
 26184                              <1> 
 26185                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
 26186                              <1> 
 26187                              <1> ;----------------------------------------
 26188                              <1> ;	TIMER DATA AREA 		:
 26189                              <1> ;----------------------------------------
 26190                              <1> 
 26191                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
 26192                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
 26193                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
 26194                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
 26195                              <1> 
 26196                              <1> ;----------------------------------------
 26197                              <1> ;	ADDITIONAL MEDIA DATA		:
 26198                              <1> ;----------------------------------------
 26199                              <1> 
 26200                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 26201                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 26202                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 26203                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 26204                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 26205                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 26206                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 26207                              <1> 
 26208                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 26209                              <1> 
 26210                              <1> ;--------------------------------------------------------
 26211                              <1> ;	DRIVE TYPE TABLE				:
 26212                              <1> ;--------------------------------------------------------
 26213                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
 26214                              <1> DR_TYPE:
 26215 0000696C 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
 26216                              <1>                 ;DW      MD_TBL1
 26217 0000696D [8A690000]          <1> 		dd	MD_TBL1
 26218 00006971 82                  <1> 		DB	02+BIT7ON
 26219                              <1> 		;DW      MD_TBL2
 26220 00006972 [97690000]          <1>                 dd      MD_TBL2
 26221 00006976 02                  <1> DR_DEFAULT:	DB	02
 26222                              <1>                 ;DW      MD_TBL3
 26223 00006977 [A4690000]          <1> 		dd      MD_TBL3
 26224 0000697B 03                  <1> 		DB	03
 26225                              <1>                 ;DW      MD_TBL4
 26226 0000697C [B1690000]          <1> 		dd      MD_TBL4
 26227 00006980 84                  <1> 		DB	04+BIT7ON
 26228                              <1>                 ;DW      MD_TBL5
 26229 00006981 [BE690000]          <1> 		dd      MD_TBL5
 26230 00006985 04                  <1> 		DB	04
 26231                              <1>                 ;DW      MD_TBL6
 26232 00006986 [CB690000]          <1> 		dd      MD_TBL6
 26233                              <1> DR_TYPE_E       equ $                   ; END OF TABLE
 26234                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
 26235                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
 26236                              <1> ;--------------------------------------------------------
 26237                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
 26238                              <1> ;--------------------------------------------------------
 26239                              <1> ;--------------------------------------------------------
 26240                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
 26241                              <1> ;--------------------------------------------------------
 26242                              <1> MD_TBL1:        
 26243 0000698A DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 26244 0000698B 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 26245 0000698C 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 26246 0000698D 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 26247 0000698E 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 26248 0000698F 2A                  <1> 	DB	02AH		; GAP LENGTH
 26249 00006990 FF                  <1> 	DB	0FFH		; DTL
 26250 00006991 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 26251 00006992 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 26252 00006993 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 26253 00006994 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 26254 00006995 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 26255 00006996 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 26256                              <1> ;--------------------------------------------------------
 26257                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
 26258                              <1> ;--------------------------------------------------------
 26259                              <1> MD_TBL2:        
 26260 00006997 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 26261 00006998 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 26262 00006999 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 26263 0000699A 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 26264 0000699B 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 26265 0000699C 2A                  <1> 	DB	02AH		; GAP LENGTH
 26266 0000699D FF                  <1> 	DB	0FFH		; DTL
 26267 0000699E 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 26268 0000699F F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 26269 000069A0 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 26270 000069A1 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 26271 000069A2 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 26272 000069A3 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
 26273                              <1> ;--------------------------------------------------------
 26274                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
 26275                              <1> ;--------------------------------------------------------
 26276                              <1> MD_TBL3:
 26277 000069A4 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 26278 000069A5 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 26279 000069A6 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 26280 000069A7 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 26281 000069A8 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
 26282 000069A9 1B                  <1> 	DB	01BH		; GAP LENGTH
 26283 000069AA FF                  <1> 	DB	0FFH		; DTL
 26284 000069AB 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
 26285 000069AC F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 26286 000069AD 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 26287 000069AE 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 26288 000069AF 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 26289 000069B0 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 26290                              <1> ;--------------------------------------------------------
 26291                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
 26292                              <1> ;--------------------------------------------------------
 26293                              <1> MD_TBL4:
 26294 000069B1 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 26295 000069B2 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 26296 000069B3 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 26297 000069B4 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 26298 000069B5 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 26299 000069B6 2A                  <1> 	DB	02AH		; GAP LENGTH
 26300 000069B7 FF                  <1> 	DB	0FFH		; DTL
 26301 000069B8 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 26302 000069B9 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 26303 000069BA 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 26304 000069BB 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 26305 000069BC 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 26306 000069BD 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 26307                              <1> ;--------------------------------------------------------
 26308                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
 26309                              <1> ;--------------------------------------------------------
 26310                              <1> MD_TBL5:
 26311 000069BE DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 26312 000069BF 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 26313 000069C0 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 26314 000069C1 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 26315 000069C2 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 26316 000069C3 2A                  <1> 	DB	02AH		; GAP LENGTH
 26317 000069C4 FF                  <1> 	DB	0FFH		; DTL
 26318 000069C5 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 26319 000069C6 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 26320 000069C7 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 26321 000069C8 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 26322 000069C9 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 26323 000069CA 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 26324                              <1> ;--------------------------------------------------------
 26325                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
 26326                              <1> ;--------------------------------------------------------
 26327                              <1> MD_TBL6:
 26328 000069CB AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
 26329 000069CC 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 26330 000069CD 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 26331 000069CE 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 26332 000069CF 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
 26333 000069D0 1B                  <1> 	DB	01BH		; GAP LENGTH
 26334 000069D1 FF                  <1> 	DB	0FFH		; DTL
 26335 000069D2 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
 26336 000069D3 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 26337 000069D4 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 26338 000069D5 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 26339 000069D6 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 26340 000069D7 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 26341                              <1> 
 26342                              <1> 
 26343                              <1> ; << diskette.inc >>
 26344                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 26345                              <1> ;
 26346                              <1> ;----------------------------------------
 26347                              <1> ;	ROM BIOS DATA AREAS		:
 26348                              <1> ;----------------------------------------
 26349                              <1> 
 26350                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 26351                              <1> 
 26352                              <1> ;----------------------------------------
 26353                              <1> ;	FIXED DISK DATA AREAS		:
 26354                              <1> ;----------------------------------------
 26355                              <1> 
 26356                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
 26357                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
 26358                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
 26359                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
 26360                              <1> 
 26361                              <1> ;----------------------------------------
 26362                              <1> ;	ADDITIONAL MEDIA DATA		:
 26363                              <1> ;----------------------------------------
 26364                              <1> 
 26365                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 26366                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
 26367                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
 26368                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
 26369                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
 26370                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 26371                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 26372                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 26373                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 26374                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 26375                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 26376                              <1> 
 26377                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 26378                              <1> ;
 26379                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 26380                              <1> 
 26381                              <1> ERR_TBL:
 26382 000069D8 E0                  <1> 	db	NO_ERR
 26383 000069D9 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
 26384 000069DD 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
 26385                              <1> 
 26386                              <1> ; 17/12/2014 (mov ax, [cfd])
 26387                              <1> ; 11/12/2014
 26388 000069E1 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
 26389                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
 26390 000069E2 01                  <1> pfd:		db 1			; previous floppy drive (for GET_PARM)
 26391                              <1> 					; (initial value of 'pfd 
 26392                              <1> 					; must be different then 'cfd' value
 26393                              <1> 					; to force updating/initializing
 26394                              <1> 					; current drive parameters) 
 26395 000069E3 90                  <1> align 2
 26396                              <1> 
 26397 000069E4 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
 26398                              <1> 			      ; (170h)
 26399 000069E6 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
 26400                              <1> 
 26401                              <1> ; 05/01/2015 
 26402 000069E8 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
 26403                              <1> 
 26404                              <1> ; *****************************************************************************
 26405                                  ;;;
 26406                                  
 26407 000069E9 90                      Align 2
 26408                                  
 26409                                  ; 12/11/2014 (Retro UNIX 386 v1)
 26410 000069EA 00                      boot_drv:    db 0 ; boot drive number (physical)
 26411                                  ; 24/11/2014
 26412 000069EB 00                      drv:	     db 0 
 26413 000069EC 00                      last_drv:    db 0 ; last hdd
 26414 000069ED 00                      hdc:         db 0  ; number of hard disk drives
 26415                                  		     ; (present/detected)
 26416                                  ;
 26417                                  ; 24/11/2014 (Retro UNIX 386 v1)
 26418                                  ; Physical drive type & flags
 26419 000069EE 00                      fd0_type:    db 0  ; floppy drive type
 26420 000069EF 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
 26421                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
 26422                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
 26423                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
 26424                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
 26425 000069F0 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
 26426 000069F1 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
 26427 000069F2 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
 26428 000069F3 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
 26429                                  		     ; bit 0 - Fixed disk access subset supported
 26430                                  		     ; bit 1 - Drive locking and ejecting
 26431                                  		     ; bit 2 - Enhanced disk drive support
 26432                                  		     ; bit 3 = Reserved (64 bit EDD support)
 26433                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
 26434                                  		     ; will interpret it as 'LBA ready'!)		
 26435                                  
 26436                                  ; 11/03/2015 - 10/07/2015
 26437 000069F4 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
 26438 000069FD 0000000000         
 26439 00006A02 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
 26440 00006A0B 0000000000         
 26441 00006A10 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
 26442 00006A19 0000000000         
 26443 00006A1E 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
 26444 00006A27 000000000000000000-
 26445 00006A30 000000000000000000-
 26446 00006A39 00                 
 26447 00006A3A 00000000000000          drv.status:    db 0,0,0,0,0,0,0
 26448 00006A41 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
 26449                                  ;
 26450                                  
 26451                                  ; 27/08/2014
 26452                                  scr_row:
 26453 00006A48 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
 26454                                  scr_col:
 26455 00006A4C 00000000                	dd 0
 26456                                  
 26457                                  ;; 14/08/2015
 26458                                  ;;msgPM:
 26459                                  ;;      db "Protected mode and paging are ENABLED ... ", 0
 26460                                  msgKVER:
 26461 00006A50 526574726F20554E49-     	db "Retro UNIX 386 v1.2 - Kernel v0.2.2.0 [30/11/2021]", 0
 26462 00006A59 58203338362076312E-
 26463 00006A62 32202D204B65726E65-
 26464 00006A6B 6C2076302E322E322E-
 26465 00006A74 30205B33302F31312F-
 26466 00006A7D 323032315D00       
 26467                                  
 26468 00006A83 90                      Align 2
 26469                                  
 26470                                  ; 20/08/2014
 26471                                    ; /* This is the default interrupt "handler" :-) */ 
 26472                                    ; Linux v0.12 (head.s)
 26473                                  int_msg:
 26474 00006A84 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
 26475 00006A8D 6E7465727275707420-
 26476 00006A96 212000             
 26477                                  
 26478 00006A99 90                      Align 2  
 26479                                  
 26480                                  ; 21/08/2014
 26481                                  timer_msg:
 26482 00006A9A 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
 26483 00006AA3 542032306829202120-
 26484 00006AAC 54696D657220496E74-
 26485 00006AB5 657272757074203A20 
 26486                                  tcountstr:
 26487 00006ABE 303030303020            	db "00000 "
 26488 00006AC4 00                      	db 0
 26489                                  
 26490 00006AC5 90                      Align 2
 26491                                  	; 21/08/2014
 26492                                  exc_msg:
 26493 00006AC6 435055206578636570-     	db "CPU exception ! "
 26494 00006ACF 74696F6E202120     
 26495                                  excnstr: 		; 25/08/2014
 26496 00006AD6 3F3F68202045495020-     	db "??h", "  EIP : "
 26497 00006ADF 3A20               
 26498                                  EIPstr: ; 29/08/2014
 26499 00006AE1 00<rept>                	times 12 db 0
 26500                                  rtc_msg:
 26501 00006AED 5265616C2054696D65-     	db "Real Time Clock - "
 26502 00006AF6 20436C6F636B202D20 
 26503                                  datestr:
 26504 00006AFF 30302F30302F303030-     	db "00/00/0000"
 26505 00006B08 30                 
 26506 00006B09 20                      	db " "
 26507                                  daystr:
 26508 00006B0A 44415920                	db "DAY "
 26509                                  timestr:	
 26510 00006B0E 30303A30303A3030                db "00:00:00"
 26511 00006B16 20                      	db " "
 26512 00006B17 00                      	db 0 
 26513                                  
 26514                                  daytmp:
 26515                                  	; 28/02/2015
 26516 00006B18 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
 26517 00006B21 4F4E20545545205745-
 26518 00006B2A 442054485520465249-
 26519 00006B33 2053415420         
 26520                                  
 26521 00006B38 FF                      ptime_seconds: db 0FFh
 26522                                  
 26523                                  	; 23/02/2015
 26524                                  	; 25/08/2014
 26525                                  ;scounter:
 26526                                  ;	db 5
 26527                                  ;	db 19
 26528                                  
 26529                                  ; 28/11/2021
 26530                                  ;; 05/11/2014
 26531                                  ;msg_out_of_memory:
 26532                                  ;	db 	07h, 0Dh, 0Ah
 26533                                  ;	db	'Insufficient memory ! (Minimum 2 MB memory is needed.)'
 26534                                  ; 	db	0Dh, 0Ah, 0
 26535                                  	;
 26536                                  setup_error_msg:
 26537 00006B39 0D0A                    	db 0Dh, 0Ah
 26538 00006B3B 4469736B2053657475-     	db 'Disk Setup Error!' 
 26539 00006B44 70204572726F7221   
 26540 00006B4C 0D0A00                  	db 0Dh, 0Ah,0
 26541                                  
 26542                                  ; 02/09/2014 (Retro UNIX 386 v1)
 26543                                  ;crt_ulc : db 0 ; upper left column (for scroll) 
 26544                                  ;	  db 0 ; upper left row (for scroll)	
 26545                                  
 26546                                  ;crt_lrc : db 79 ; lower right column (for scroll) 
 26547                                  ;	  db 24 ; lower right row (for scroll)
 26548                                  
 26549                                  
 26550                                  ; 06/11/2014 (Temporary Data)
 26551                                  ; Memory Information message
 26552                                  ; 14/08/2015
 26553                                  msg_memory_info:
 26554 00006B4F 07                      	db	07h
 26555 00006B50 0D0A                    	db	0Dh, 0Ah
 26556                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
 26557 00006B52 546F74616C206D656D-     	db	"Total memory : "
 26558 00006B5B 6F7279203A20       
 26559                                  mem_total_b_str: ; 10 digits
 26560 00006B61 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
 26561 00006B6A 302062797465730D0A 
 26562 00006B73 202020202020202020-     	db	"               ", 20h, 20h, 20h
 26563 00006B7C 202020202020202020 
 26564                                  mem_total_p_str: ; 7 digits
 26565 00006B85 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
 26566 00006B8E 616765730D0A       
 26567 00006B94 0D0A                    	db 	0Dh, 0Ah
 26568 00006B96 46726565206D656D6F-     	db	"Free memory  : "
 26569 00006B9F 727920203A20       
 26570                                  free_mem_b_str:  ; 10 digits
 26571 00006BA5 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
 26572 00006BAE 3F2062797465730D0A 
 26573 00006BB7 202020202020202020-     	db	"               ", 20h, 20h, 20h
 26574 00006BC0 202020202020202020 
 26575                                  free_mem_p_str:  ; 7 digits
 26576 00006BC9 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
 26577 00006BD2 616765730D0A       
 26578 00006BD8 0D0A00                  	db	0Dh, 0Ah, 0
 26579                                  
 26580                                  dsk_ready_msg:
 26581 00006BDB 0D0A                    	db 	0Dh, 0Ah
 26582                                  dsktype:
 26583 00006BDD 6664                    	db	'fd'
 26584                                  dskx:
 26585 00006BDF 30                      	db	'0'
 26586 00006BE0 20                      	db	20h
 26587 00006BE1 697320524541445920-     	db 	'is READY ...'
 26588 00006BEA 2E2E2E             
 26589 00006BED 00                      	db 	0
 26590                                  nextline:
 26591 00006BEE 0D0A00                  	db 	0Dh, 0Ah, 0
 26592                                  
 26593                                  ; KERNEL - SYSINIT Messages
 26594                                  ; 24/08/2015
 26595                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
 26596                                  ; 14/07/2013
 26597                                  ;kernel_init_err_msg:
 26598                                  ;	db 0Dh, 0Ah
 26599                                  ;	db 07h
 26600                                  ;	db 'Kernel initialization ERROR !'
 26601                                  ;	db 0Dh, 0Ah, 0 
 26602                                  ; 24/08/2015
 26603                                  ;;; (temporary kernel init message has been removed
 26604                                  ;;;  from 'sys_init' code)
 26605                                  ;kernel_init_ok_msg: 
 26606                                  ;	db 0Dh, 0Ah
 26607                                  ;	db 07h
 26608                                  ;	db 'Welcome to Retro UNIX 386 v1.1 Operating System !'
 26609                                  ;	db 0Dh, 0Ah
 26610                                  ;       db 'by Erdogan Tan - 04/02/2016 (v0.2.1.0)'
 26611                                  ;	db 0Dh, 0Ah, 0
 26612                                  panic_msg:
 26613 00006BF1 0D0A07                  	db 0Dh, 0Ah, 07h
 26614 00006BF4 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
 26615 00006BFD 726E656C2050616E69-
 26616 00006C06 632021             
 26617 00006C09 0D0A00                  	db 0Dh, 0Ah, 0
 26618                                  etc_init_err_msg:
 26619 00006C0C 0D0A                    	db 0Dh, 0Ah
 26620 00006C0E 07                      	db 07h
 26621 00006C0F 4552524F523A202F65-     	db 'ERROR: /etc/init !?'
 26622 00006C18 74632F696E69742021-
 26623 00006C21 3F                 
 26624 00006C22 0D0A00                  	db 0Dh, 0Ah, 0
 26625                                  
 26626                                  ; 10/05/2015
 26627                                  badsys_msg:
 26628 00006C25 0D0A                    	db 0Dh, 0Ah
 26629 00006C27 07                      	db 07h
 26630 00006C28 496E76616C69642053-     	db 'Invalid System Call !'
 26631 00006C31 797374656D2043616C-
 26632 00006C3A 6C2021             
 26633 00006C3D 0D0A                    	db 0Dh, 0Ah
 26634 00006C3F 4541583A20              	db 'EAX: '
 26635                                  bsys_msg_eax:
 26636 00006C44 303030303030303068      	db '00000000h'
 26637 00006C4D 0D0A                    	db 0Dh, 0Ah
 26638 00006C4F 4549503A20              	db 'EIP: '
 26639                                  bsys_msg_eip:
 26640 00006C54 303030303030303068      	db '00000000h' 
 26641 00006C5D 0D0A00                  	db 0Dh, 0Ah, 0
 26642                                  
 26643                                  BSYS_M_SIZE equ $ - badsys_msg
 26644                                  
 26645                                  
 26646                                  align 2
 26647                                  
 26648                                  ; EPOCH Variables
 26649                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
 26650                                  ; 09/04/2013 epoch variables
 26651                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
 26652                                  ;
 26653 00006C60 B207                    year: 	dw 1970
 26654 00006C62 0100                    month: 	dw 1
 26655 00006C64 0100                    day: 	dw 1
 26656 00006C66 0000                    hour: 	dw 0
 26657 00006C68 0000                    minute: dw 0
 26658 00006C6A 0000                    second: dw 0
 26659                                  
 26660                                  DMonth:
 26661 00006C6C 0000                    	dw 0
 26662 00006C6E 1F00                    	dw 31
 26663 00006C70 3B00                    	dw 59
 26664 00006C72 5A00                    	dw 90
 26665 00006C74 7800                    	dw 120
 26666 00006C76 9700                    	dw 151
 26667 00006C78 B500                    	dw 181
 26668 00006C7A D400                    	dw 212
 26669 00006C7C F300                    	dw 243
 26670 00006C7E 1101                    	dw 273
 26671 00006C80 3001                    	dw 304
 26672 00006C82 4E01                    	dw 334
 26673                                  
 26674                                  ; 04/11/2014 (Retro UNIX 386 v1)
 26675 00006C84 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
 26676                                  		   ;   1 and 16 MB, max. 3C00h = 15 MB.
 26677 00006C86 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
 26678                                  		   ;   between 16 MB and 4 GB.
 26679 00006C88 90<rept>                align 16
 26680                                  
 26681                                  bss_start:
 26682                                  
 26683                                  ABSOLUTE bss_start
 26684                                  
 26685                                  	; 11/03/2015
 26686                                  	; Interrupt Descriptor Table (20/08/2014)
 26687                                  idt:
 26688 00006C90 <res 00000200>          	resb	64*8 ; INT 0 to INT 3Fh
 26689                                  idt_end:
 26690                                  
 26691                                  ;alignb 4
 26692                                  
 26693                                  task_state_segment:
 26694                                  	; 24/03/2015
 26695 00006E90 <res 00000002>          tss.link:   resw 1
 26696 00006E92 <res 00000002>          	    resw 1
 26697                                  ; tss offset 4	
 26698 00006E94 <res 00000004>          tss.esp0:   resd 1
 26699 00006E98 <res 00000002>          tss.ss0:    resw 1
 26700 00006E9A <res 00000002>          	    resw 1	
 26701 00006E9C <res 00000004>          tss.esp1:   resd 1
 26702 00006EA0 <res 00000002>          tss.ss1:    resw 1
 26703 00006EA2 <res 00000002>          	    resw 1 	
 26704 00006EA4 <res 00000004>          tss.esp2:   resd 1
 26705 00006EA8 <res 00000002>          tss.ss2:    resw 1
 26706 00006EAA <res 00000002>          	    resw 1
 26707                                  ; tss offset 28
 26708 00006EAC <res 00000004>          tss.CR3:    resd 1
 26709 00006EB0 <res 00000004>          tss.eip:    resd 1
 26710 00006EB4 <res 00000004>          tss.eflags: resd 1
 26711                                  ; tss offset 40
 26712 00006EB8 <res 00000004>          tss.eax:    resd 1		 		
 26713 00006EBC <res 00000004>          tss.ecx:    resd 1
 26714 00006EC0 <res 00000004>          tss.edx:    resd 1
 26715 00006EC4 <res 00000004>          tss.ebx:    resd 1
 26716 00006EC8 <res 00000004>          tss.esp:    resd 1
 26717 00006ECC <res 00000004>          tss.ebp:    resd 1
 26718 00006ED0 <res 00000004>          tss.esi:    resd 1
 26719 00006ED4 <res 00000004>          tss.edi:    resd 1
 26720                                  ; tss offset 72
 26721 00006ED8 <res 00000002>          tss.ES:     resw 1
 26722 00006EDA <res 00000002>          	    resw 1	
 26723 00006EDC <res 00000002>          tss.CS:	    resw 1
 26724 00006EDE <res 00000002>          	    resw 1
 26725 00006EE0 <res 00000002>          tss.SS:	    resw 1
 26726 00006EE2 <res 00000002>          	    resw 1
 26727 00006EE4 <res 00000002>          tss.DS:	    resw 1
 26728 00006EE6 <res 00000002>          	    resw 1
 26729 00006EE8 <res 00000002>          tss.FS:	    resw 1
 26730 00006EEA <res 00000002>          	    resw 1
 26731 00006EEC <res 00000002>          tss.GS:	    resw 1
 26732 00006EEE <res 00000002>          	    resw 1		
 26733 00006EF0 <res 00000002>          tss.LDTR:   resw 1
 26734 00006EF2 <res 00000002>          	    resw 1
 26735                                  ; tss offset 100		
 26736 00006EF4 <res 00000002>          	    resw 1		
 26737 00006EF6 <res 00000002>          tss.IOPB:   resw 1
 26738                                  ; tss offset 104 
 26739                                  tss_end:
 26740                                  
 26741 00006EF8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
 26742                                  		  ;   (Physical address = Virtual address)	 	
 26743 00006EFC <res 00000004>          memory_size: resd 1 ; memory size in pages
 26744 00006F00 <res 00000004>          free_pages:  resd 1 ; number of free pages		
 26745 00006F04 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
 26746                                  		  ;   first free page search
 26747 00006F08 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
 26748                                  		  ;   next free page search will be
 26749                                  		  ; stopped after it. (end of M.A.T.)
 26750 00006F0C <res 00000004>          first_page:  resd 1 ;   offset value in M.A.T. which
 26751                                  		  ; first free page search
 26752                                  		  ;   will be started on it. (for user)
 26753 00006F10 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
 26754                                  
 26755                                  ;;;
 26756                                  ; 02/09/2014 (Retro UNIX 386 v1)
 26757                                  ; 04/12/2013 (Retro UNIX 8086 v1)
 26758 00006F14 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
 26759                                  			  ; NOTE: active page only
 26760 00006F16 <res 00000010>          cursor_posn: resw 8 	  ; cursor positions for video pages
 26761                                  active_page: 
 26762 00006F26 <res 00000001>          ptty: 	     resb 1 	  ; current tty
 26763                                  ; 01/07/2015
 26764 00006F27 <res 00000001>          ccolor:	     resb 1	  ; current color attributes ('sysmsg')	
 26765                                  ; 26/10/2015
 26766                                  ; 07/09/2014
 26767 00006F28 <res 00000014>          ttychr:      resw ntty+2  ; Character buffer (multiscreen)
 26768                                  
 26769                                  ; 21/08/2014
 26770 00006F3C <res 00000004>          tcount:	     resd 1
 26771                                  
 26772                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
 26773 00006F40 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
 26774                                  
 26775                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
 26776                                  ; (open mode locks for pseudo TTYs)
 26777                                  ; [ major tty locks (return error in any conflicts) ]
 26778 00006F44 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
 26779                                  
 26780                                  ; 15/04/2015 (Retro UNIX 386 v1)
 26781                                  ; 22/09/2013 (Retro UNIX 8086 v1)
 26782 00006F58 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
 26783                                  ; 15/04/2015 (Retro UNIX 386 v1)
 26784                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
 26785                                  ;; 0 means serial port is not available 
 26786                                  ;;comprm: ; 25/06/2014
 26787 00006F62 <res 00000001>          com1p:       resb 1  ;;0E3h
 26788 00006F63 <res 00000001>          com2p:       resb 1  ;;0E3h
 26789                                  
 26790                                  ; 17/11/2015
 26791                                  ; request for response (from the terminal)	
 26792 00006F64 <res 00000002>          req_resp:     resw 1 			
 26793                                  ; 07/11/2015
 26794 00006F66 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
 26795                                  		    ; (0= COM1, 1= COM2)
 26796                                  ; 09/11/2015
 26797 00006F67 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
 26798                                  ; 07/11/2015
 26799 00006F68 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
 26800 00006F6A <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
 26801                                  
 26802                                  ; 23/10/2015
 26803                                  ; SERIAL PORTS - COMMUNICATION MODES
 26804                                  ; (Retro UNIX 386 v1 feature only!)
 26805                                  ; 0 - command mode (default/initial mode)
 26806                                  ; 1 - terminal mode (Retro UNIX 386 v1 terminal, ascii chars)
 26807                                  ;;; communication modes for futre versions:  
 26808                                  ; // 2 - keyboard mode (ascii+scancode input)
 26809                                  ; // 3 - mouse mode
 26810                                  ; // 4 - device control (output) mode
 26811                                  ; VALID COMMANDS for current version:
 26812                                  ; 	'LOGIN'
 26813                                  ;  Login request: db 0FFh, 'LOGIN', 0 
 26814                                  ;	 ("Retro UNIX 386 v1 terminal requests login")
 26815                                  ;  Login response: db 0FFh, 'login', 0
 26816                                  ;	 ("login request accepted, wait for login prompt") 
 26817                                  ; When a login requests is received and acknowledged (by
 26818                                  ; serial port interrupt handler (communication procedure),
 26819                                  ; Retro UNIX 386 v1 operating system will start terminal mode
 26820                                  ; (login procedure) by changing comm. mode to 1 (terminal mode)
 26821                                  ; and then running 'etc/getty' for tty8 (COM1) or tty9 (COM2)
 26822                                  ; 
 26823                                  ; 'sys connect' system call is used to change communication mode
 26824                                  ; except 'LOGIN' command which is used to start terminal mode
 26825                                  ; by using (COM port) terminal.
 26826                                  
 26827                                  ;com1own:     resb 1 ; COM1 owner (u.uno)
 26828                                  ;com2own:     resb 1 ; COM2 owner (u.uno)
 26829                                  ;com1mode:    resb 1 ; communication mode for COM1
 26830                                  ;com1com:     resb 1 ; communication command for COM1
 26831                                  ;com2mode:    resb 1 ; communication mode for COM1
 26832                                  ;com2com      resb 1 ; communication command for COM1
 26833                                  ;com1cbufp:   resb 8 ; COM1 command buffer char pointer	
 26834                                  ;com2cbufp:   resb 8 ; COM2 command buffer char pointer	
 26835                                  ;com1cbuf:    resb 8 ; COM2 command buffer
 26836                                  ;com2cbuf:    resb 8 ; COM2 command buffer
 26837                                  
 26838                                  ; 22/08/2014 (RTC)
 26839                                  ; (Packed BCD)
 26840 00006F6C <res 00000001>          time_seconds: resb 1
 26841 00006F6D <res 00000001>          time_minutes: resb 1
 26842 00006F6E <res 00000001>          time_hours:   resb 1
 26843 00006F6F <res 00000001>          date_wday:    resb 1
 26844 00006F70 <res 00000001>          date_day:     resb 1
 26845 00006F71 <res 00000001>          date_month:   resb 1			
 26846 00006F72 <res 00000001>          date_year:    resb 1
 26847 00006F73 <res 00000001>          date_century: resb 1
 26848                                  
 26849                                  %include 'diskbss.s'	; UNINITIALIZED DISK (BIOS) DATA
 26850                              <1> ; Retro UNIX 386 v1 Kernel - DISKBSS.INC
 26851                              <1> ; Last Modification: 10/07/2015
 26852                              <1> ;	(Unnitialized Disk Parameters Data section for 'DISKIO.INC') 
 26853                              <1> ;
 26854                              <1> ; *****************************************************************************
 26855                              <1> 
 26856                              <1> alignb 2
 26857                              <1> 
 26858                              <1> ;----------------------------------------
 26859                              <1> ;	TIMER DATA AREA 		:
 26860                              <1> ;----------------------------------------
 26861                              <1> 
 26862                              <1> TIMER_LH:	; 16/02/205
 26863 00006F74 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
 26864 00006F76 <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
 26865 00006F78 <res 00000001>      <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
 26866                              <1> 
 26867                              <1> ;----------------------------------------
 26868                              <1> ;	DISKETTE DATA AREAS		:
 26869                              <1> ;----------------------------------------
 26870                              <1> 
 26871 00006F79 <res 00000001>      <1> SEEK_STATUS:	resb	1
 26872 00006F7A <res 00000001>      <1> MOTOR_STATUS:	resb	1
 26873 00006F7B <res 00000001>      <1> MOTOR_COUNT:	resb	1
 26874 00006F7C <res 00000001>      <1> DSKETTE_STATUS:	resb	1
 26875 00006F7D <res 00000007>      <1> NEC_STATUS:	resb	7
 26876                              <1> 
 26877                              <1> ;----------------------------------------
 26878                              <1> ;	ADDITIONAL MEDIA DATA		:
 26879                              <1> ;----------------------------------------
 26880                              <1> 
 26881 00006F84 <res 00000001>      <1> LASTRATE:	resb 	1
 26882 00006F85 <res 00000001>      <1> HF_STATUS:	resb 	1
 26883 00006F86 <res 00000001>      <1> HF_ERROR:	resb 	1
 26884 00006F87 <res 00000001>      <1> HF_INT_FLAG:	resb 	1
 26885 00006F88 <res 00000001>      <1> HF_CNTRL:	resb 	1
 26886 00006F89 <res 00000004>      <1> DSK_STATE:	resb 	4
 26887 00006F8D <res 00000002>      <1> DSK_TRK:	resb 	2
 26888                              <1> 
 26889                              <1> ;----------------------------------------
 26890                              <1> ;	FIXED DISK DATA AREAS		:
 26891                              <1> ;----------------------------------------
 26892                              <1> 
 26893 00006F8F <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
 26894 00006F90 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
 26895 00006F91 <res 00000001>      <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
 26896                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
 26897                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
 26898                              <1> ;port2_off	resb	1		; Hard idsk controller 2 - port offset
 26899                              <1> 
 26900 00006F92 <res 00000002>      <1> alignb 4
 26901                              <1> 
 26902                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 26903                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 26904                              <1> HF_TBL_VEC: ; 22/12/2014	
 26905 00006F94 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 26906 00006F98 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 26907 00006F9C <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
 26908 00006FA0 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
 26909                              <1> 
 26910                              <1> ; 03/01/2015
 26911 00006FA4 <res 00000001>      <1> LBAMode:     	resb	1
 26912                              <1> 
 26913                              <1> ; *****************************************************************************
 26914                                  
 26915                                  ;;; Real Mode Data (10/07/2015 - BSS)
 26916                                  
 26917                                  ;alignb 2
 26918                                  
 26919                                  %include 'ux.s' ; 12/04/2015 (unix system/user/process data)
 26920                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 26921                              <1> ; (re-write kernel for test by using previous version without a major defect)
 26922                              <1> ; ****************************************************************************
 26923                              <1> ; Retro UNIX 386 v1.2 Kernel - ux.s
 26924                              <1> ; Last Modification: 27/11/2021
 26925                              <1> ;
 26926                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 26927                              <1> ; (Modified from 
 26928                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 26929                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 26930                              <1> ; ----------------------------------------------------------------------------
 26931                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 26932                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 26933                              <1> ; <Bell Laboratories (17/3/1972)>
 26934                              <1> ; <Preliminary Release of UNIX Implementation Document>
 26935                              <1> ; (Section E10 (17/3/1972) - ux.s)
 26936                              <1> ; ****************************************************************************
 26937                              <1> 
 26938                              <1> ; 22/11/2021 (Modification in Runix v1.1 'ux.s' for runix v2 fs compatibility)
 26939                              <1> ; 18/07/2021
 26940                              <1> ; 15/07/2021
 26941                              <1> ; 12/05/2021
 26942                              <1> ; 09/05/2021
 26943                              <1> ; 06/05/2021
 26944                              <1> ; 02/05/2021
 26945                              <1> ; 26/01/2020 (NASM version of SuperBlock structure in UNIXHDCP.ASM)
 26946                              <1> 
 26947                              <1> ; 21/12/2019 (UNIXCOPY.COM, UNIXCOPY.ASM, UNIXHDCP.COM, UNIXHDCP.ASM)
 26948                              <1> ; 19/12/2019 (UNIXHDFS.COM, RUFSHDI.ASM)
 26949                              <1> ; 01/09/2019 - Retro UNIX 386 v2 SuperBlock
 26950                              <1> 
 26951                              <1> ; 14/01/2020 - Super Block modification:
 26952                              <1> ;	     - Extended sections/divisions (consequental sectors)
 26953                              <1> ;	     - (for swapping, configuration, boot space etc.)	
 26954                              <1> 
 26955                              <1> struc SB ; SuperBlock
 26956                              <1> 
 26957 00000000 <res 00000004>      <1> .Header:	resd 1
 26958                              <1> ;.HiddenSects:
 26959 00000004 <res 00000004>      <1> .BootSectAddr:	resd 1	; Hidden Sectors
 26960                              <1> ;.TotalSects:
 26961 00000008 <res 00000004>      <1> .VolumeSize:	resd 1	; Entire Volume/Partition Size (includes ext. volume)	
 26962 0000000C <res 00000004>      <1> .Version:	resd 1	
 26963 00000010 <res 00000004>      <1> .BlockSize:	resd 1	
 26964 00000014 <res 00000004>      <1> .InodeCount:	resd 1		
 26965 00000018 <res 00000004>      <1> .FreeMapAddr:	resd 1	
 26966 0000001C <res 00000004>      <1> .FreeMapSize:	resd 1	
 26967 00000020 <res 00000004>      <1> .InodeMapAddr:	resd 1	
 26968 00000024 <res 00000004>      <1> .InodeMapSize:	resd 1	
 26969 00000028 <res 00000004>      <1> .InodeTblAddr:	resd 1	
 26970 0000002C <res 00000004>      <1> .InodeTblSize:	resd 1	
 26971 00000030 <res 00000004>      <1> .FreeInodes:	resd 1	
 26972 00000034 <res 00000004>      <1> .FirstFreeIno:	resd 1	
 26973 00000038 <res 00000004>      <1> .FreeBlocks:	resd 1	
 26974 0000003C <res 00000004>      <1> .FirstFreeBlk:	resd 1	
 26975 00000040 <res 00000013>      <1> .BootSecParms:	resb 19	; v1
 26976 00000053 <res 00000005>      <1> .BSExtension:	resb 5	; v2 HDFS
 26977 00000058 <res 00000001>      <1> .Status:	resb 1	; 12/05/2021 (system modification status) (*)
 26978 00000059 <res 00000001>      <1> .Pdrv:		resb 1  ; Physical disk number (index) ; 12/05/2021 (*) 
 26979 0000005A <res 00000002>      <1> .Uno:		resw 1	; user/process number ; 12/05/2021 (*)
 26980 0000005C <res 00000004>      <1> .ModifTime:	resd 1	; (last) modification time (*)
 26981 00000060 <res 00000004>      <1> .ExtdVolTbl:	resd 1	; Extended Volume Start/Table Address
 26982 00000064 <res 00000004>      <1> .ExtdVolSize:	resd 1	; Extended Volume (swap section etc.) Size	
 26983 00000068 <res 00000001>      <1> .LBA_rw:	resb 1
 26984 00000069 <res 00000001>      <1> .ClusterSize:	resb 1
 26985 0000006A <res 00000001>      <1> .ReadOnly:	resb 1	; (SB will not be written to disk if bit 0 is 1)
 26986 0000006B <res 00000001>      <1> .Mounted:	resb 1
 26987 0000006C <res 00000004>      <1> .MountInode:	resd 1  ; double word
 26988 00000070 <res 00000001>      <1> .DevMajor:	resb 1
 26989 00000071 <res 00000001>      <1> .DevMinor:	resb 1
 26990 00000072 <res 00000001>      <1> .LongName:	resb 1
 26991 00000073 <res 00000001>      <1> .Direntry32:	resb 1
 26992                              <1> ; 18/07/2021
 26993 00000074 <res 00000004>      <1> .FileBuffer:	resd 1
 26994 00000078 <res 00000004>      <1> .ItabBuffer:	resd 1
 26995 0000007C <res 00000004>      <1> .ImapBuffer:	resd 1
 26996 00000080 <res 00000004>      <1> .FmapBuffer:	resd 1
 26997                              <1>  ; 15/07/2021
 26998 00000084 <res 00000004>      <1> .LastInode:	resd 1
 26999                              <1> ; 02/05/2021
 27000 00000088 <res 00000004>      <1> .FmapIndex:	resd 1
 27001 0000008C <res 00000004>      <1> .ImapIndex:	resd 1
 27002 00000090 <res 00000004>      <1> .ItableIndex:	resd 1
 27003 00000094 <res 00000168>      <1> .Reserved:	resb 508-148 ; 18/07/2021
 27004 000001FC <res 00000004>      <1> .Footer:	resd 1
 27005                              <1> 
 27006                              <1> endstruc
 27007                              <1> 
 27008                              <1> ; 26/01/2020 (unix386.s, ux.s)
 27009                              <1> ; 14/01/2020
 27010                              <1> SB.HiddenSects	equ SB.BootSectAddr
 27011                              <1> SB.TotalSects	equ SB.VolumeSize
 27012                              <1> 
 27013                              <1> ; 11/05/2021 (Retro UNIX 386 v2)
 27014                              <1> ; Super block status byte (byte 0 of SB.status dword)
 27015                              <1> ; 	bit 0 - superblock modified flag
 27016                              <1> ; 	bit 1 - inode map modified flag
 27017                              <1> ; 	bit 2 - free blocks map modified flag
 27018                              <1> ; 	bit 3 - inode table modified flag
 27019                              <1> ;; 	bit 4 - boot sector modified flag ; 17/08/2021
 27020                              <1> ; 17/08/2021
 27021                              <1> ;	bit 4 - file data write error (for SB.LastInode)
 27022                              <1> ;	bit 5 - inode table write error (for SB.LastInode)
 27023                              <1> ;	bit 6 - inode map write error (for SB.LastInode)
 27024                              <1> ;	bit 7 - free blocks map write error (for SB.LastInode)
 27025                              <1> 	
 27026                              <1> ; 21/12/2019
 27027                              <1> ; 19/12/2019 - Retro UNIX 386 v2 HD (071h) partition boot sector 
 27028                              <1> ;	       (UNIXHDFS.ASM)
 27029                              <1> ; 04/12/2015 (14 byte file names - Retro UNIX 386 v1.1)
 27030                              <1> ; 14/07/2015 (8 byte file names - Retro UNIX 8086 v1 & Retro UNIX 386 v1.0)
 27031                              <1> 
 27032                              <1> bsFSystemID 	equ 2  ; db 'RUFS'	
 27033                              <1> bsVolumeSerial 	equ 6  ; dd 0 ; (4 bytes)
 27034                              <1> bsFDSign	equ 10 ; db 'fd'
 27035                              <1> bsDriveNumber 	equ 12 ; db 0 ; fd0 or fd1 (0 or 1)
 27036                              <1> bsReserved 	equ 13 ; db 0 ; (512 bytes per sector)	
 27037                              <1> bsSecPerTrack	equ 14 ; db 18 ; (9 or 15)	
 27038                              <1> bsHeads		equ 15 ; db  ; 2
 27039                              <1> bsTracks	equ 16 ; dw 80 ; bsCylinders
 27040                              <1> bs_bf_inode_number equ 18 ; dw 0 ; 0 or Boot/Startup File I-Number
 27041                              <1> bsInfoEndsign	equ 20 ; db '@'
 27042                              <1> ; 21/12/2019
 27043                              <1> bsMagic		equ 20 ; db '@'
 27044                              <1> bsPartitionID	equ 21 ; db 0 ; db 71h
 27045                              <1> bsHiddenSects	equ 22 ; dd 0 ; Hidden sectors (Boot Sector LBA)
 27046                              <1> 
 27047                              <1> ; 22/11/2021 - Retro UNIX v2 I-node Flags
 27048                              <1> ; ------------------------------------------------------------------
 27049                              <1> ; UINSTALL.ASM (included in UNIXFDFS.ASM) - 23/01/2020
 27050                              <1> ; ------------------------------------------------------------------
 27051                              <1> 
 27052                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for files
 27053                              <1> ; 1000000000000000b 	IFREG - 1 = regular file (8000h)
 27054                              <1> ; 0100000000000000b	IFDIR - 1 = directory (4000h)
 27055                              <1> ; 0010000000000000b	IRSVD - 0 = reserved bit (2000h) ; Mounted flag
 27056                              <1> ; 0001000000000000b	ILARG - large file addressing bit (1000h)
 27057                              <1> ; 0000100000000000b	ISUID - set user id on exec (800h)
 27058                              <1> ; 0000010000000000b	ISGID - set group id on exec (400h)
 27059                              <1> ; 0000001000000000b	IEXTT - 1 = use extents (200h)
 27060                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
 27061                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
 27062                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
 27063                              <1> ; 0000000000100000b	read, group (20h)
 27064                              <1> ; 0000000000010000b	write, group (10h)
 27065                              <1> ; 0000000000001000b	execute, group (08h)
 27066                              <1> ; 0000000000000100b	read, others (04h)
 27067                              <1> ; 0000000000000010b	write, others (02h)
 27068                              <1> ; 0000000000000001b	execute, others (01h)
 27069                              <1> 
 27070                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for devices
 27071                              <1> ; 1000000000000000b 	IFREG - 0 = device file (8000h)
 27072                              <1> ; 0100000000000000b	IFBLK - 1 = block device (4000h)
 27073                              <1> ; 0010000000000000b	IFCHR - character special (2000h) -always 1-
 27074                              <1> ; 0001000000000000b	IFIFO - fifo special (1000h)
 27075                              <1> ; 0000100000000000b	IPIPE - pipe special (800h) ; 07/02/2020
 27076                              <1> ; 0000010000000000b	IREDIR - redirected (400h)  ; 07/02/2020
 27077                              <1> ; 0000001000000000b	IEXTR - 1 = external device driver (200h)
 27078                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
 27079                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
 27080                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
 27081                              <1> ; 0000000000100000b	read, group (20h)
 27082                              <1> ; 0000000000010000b	write, group (10h)
 27083                              <1> ; 0000000000001000b	execute, group (08h)
 27084                              <1> ; 0000000000000100b	read, others (04h)
 27085                              <1> ; 0000000000000010b	write, others (02h)
 27086                              <1> ; 0000000000000001b	execute, others (01h)
 27087                              <1> 
 27088                              <1> alignb 2
 27089                              <1> 
 27090                              <1> inode:
 27091                              <1> 	;; 11/03/2013. 
 27092                              <1> 	;;Derived from UNIX v1 source code 'inode' structure (ux).
 27093                              <1> 	;;i.
 27094                              <1> 	;
 27095                              <1> 	;i.flgs: resw 1
 27096                              <1> 	;i.nlks: resb 1
 27097                              <1> 	;i.uid:	 resb 1
 27098                              <1>         ;i.size: resw 1 ; size
 27099                              <1> 	;i.dskp: resw 8 ; 16 bytes
 27100                              <1> 	;i.ctim: resd 1
 27101                              <1> 	;i.mtim: resd 1
 27102                              <1> 	;i.rsvd: resw 1 ; Reserved (ZERO/Undefined word for UNIX v1)
 27103                              <1> 
 27104                              <1> 	; 26/01/2020
 27105                              <1> 	; Retro UNIX 386 v2.0 - Modified UNIX v7 inode model
 27106                              <1> 	;	(15/09/2029 .. 18/12/2019)
 27107                              <1> 
 27108 00006C90 <res 00000002>      <1> 	i.flgs:   resw 1	; /* mode and type of file */
 27109 00006C92 <res 00000002>      <1> 	i.nlks:	  resw 1	; /* number of links to file */
 27110 00006C94 <res 00000002>      <1> 	i.uid:	  resw 1	; /* owner's user id */  - 0 to 655535 -
 27111 00006C96 <res 00000001>      <1> 	i.gid:	  resb 1	; /* owner's group id */ - o to 255 -
 27112 00006C97 <res 00000001>      <1> 	i.size_h: resb 1	; /* number of bytes in file */ ; byte 5
 27113 00006C98 <res 00000004>      <1> 	i.size:	  resd 1 ; size	; /* number of bytes in file */
 27114 00006C9C <res 00000028>      <1> 	i.dskp:	  resd 10 ; 40 bytes ; /* disk block addresses */
 27115 00006CC4 <res 00000004>      <1> 	i.atim:	  resd 1	; /* time last accessed */
 27116 00006CC8 <res 00000004>      <1> 	i.mtim:	  resd 1	; /* time last modified */
 27117 00006CCC <res 00000004>      <1> 	i.ctim:	  resd 1	; /* time created */
 27118                              <1> 
 27119                              <1> I_SIZE	equ $ - inode
 27120                              <1> 
 27121                              <1> process:
 27122                              <1> 	; 06/05/2015
 27123                              <1> 	; 11/03/2013 - 05/02/2014
 27124                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
 27125                              <1> 	;p.
 27126                              <1> 	
 27127 00006CD0 <res 00000020>      <1>         p.pid:   resw nproc
 27128 00006CF0 <res 00000020>      <1>         p.ppid:  resw nproc
 27129 00006D10 <res 00000020>      <1>         p.break: resw nproc
 27130 00006D30 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
 27131 00006D40 <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
 27132 00006D50 <res 00000010>      <1> 	p.link:	 resb nproc
 27133 00006D60 <res 00000010>      <1> 	p.stat:	 resb nproc
 27134                              <1> 
 27135                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 fetaure only !) 
 27136 00006D70 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
 27137                              <1> 			    ; 'user' structure	
 27138                              <1> 
 27139                              <1> P_SIZE	equ $ - process
 27140                              <1> 
 27141                              <1> 
 27142                              <1> ; fsp table (original UNIX v1)
 27143                              <1> ;
 27144                              <1> ;Entry
 27145                              <1> ;          15                                      0
 27146                              <1> ;  1     |---|---------------------------------------|
 27147                              <1> ;        |r/w|       i-number of open file           |
 27148                              <1> ;        |---|---------------------------------------| 
 27149                              <1> ;        |               device number               |
 27150                              <1> ;        |-------------------------------------------|
 27151                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
 27152                              <1> ;        |-------------------------------------------| 
 27153                              <1> ;        |  flag that says    | number of processes  |
 27154                              <1> ;        |   file deleted     | that have file open  |
 27155                              <1> ;        |-------------------------------------------| 
 27156                              <1> ;  2     |                                           |
 27157                              <1> ;        |-------------------------------------------| 
 27158                              <1> ;        |                                           |
 27159                              <1> ;        |-------------------------------------------|
 27160                              <1> ;        |                                           |
 27161                              <1> ;        |-------------------------------------------|
 27162                              <1> ;        |                                           |
 27163                              <1> ;        |-------------------------------------------| 
 27164                              <1> ;  3     |                                           | 
 27165                              <1> ;        |                                           |  
 27166                              <1> ;
 27167                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
 27168                              <1> 
 27169                              <1> 
 27170                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
 27171                              <1> 
 27172                              <1> ;Entry
 27173                              <1> ;         15                    7                   0
 27174                              <1> ;  1     |-------------------------------------------|
 27175                              <1> ;        |   	     i-number of open file           |
 27176                              <1> ;        |-------------------------------------------| 
 27177                              <1> ;        |        high word of 32 bit i-number       |
 27178                              <1> ;        |-------------------------------------------|
 27179                              <1> ;        | open mode & status  |   device number     |
 27180                              <1> ;        |-------------------------------------------|
 27181                              <1> ;        |    reserved byte    |     open count      |
 27182                              <1> ;        |-------------------------------------------| 
 27183                              <1> ;        | offset pointer, i.e., r/w pointer to file |
 27184                              <1> ;        |-------------------------------------------|
 27185                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
 27186                              <1> ;        |-------------------------------------------|
 27187                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
 27188                              <1> ;        |-------------------------------------------|
 27189                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
 27190                              <1> ;        |-------------------------------------------|
 27191                              <1> ;  2     |                                           |
 27192                              <1> ;        |-------------------------------------------| 
 27193                              <1> ;        |                                           |
 27194                              <1> ;        |-------------------------------------------|
 27195                              <1> ;        |                                           |
 27196                              <1> ;        |-------------------------------------------|
 27197                              <1> ;        |                                           |
 27198                              <1> ;        |-------------------------------------------| 
 27199                              <1> ;        |                                           | 
 27200                              <1> 
 27201                              <1> ; 22/11/2021
 27202                              <1> ; 21/07/2021 - Retro UNIX 386 v2 open file struc revision
 27203                              <1> 
 27204                              <1> struc file	; open files (fsp) structure
 27205 00000000 <res 00000002>      <1>   .inode:  resw 1  ; inode number of open file (32 bit)
 27206 00000002 <res 00000002>      <1>   .i32:	   resw 1  ; higher word of inode number (reserved)
 27207 00000004 <res 00000001>      <1>   .drive:  resb 1  ; logical drive (disk) number
 27208 00000005 <res 00000001>      <1>   .flags:  resb 1  ; open mode and status
 27209 00000006 <res 00000001>      <1>   .count:  resb 1  ; number of processes that have file open
 27210                              <1>   ;.rsvd:  resb 1  ; reserved byte (for next versions)
 27211 00000007 <res 00000001>      <1>   .mnt:    resb 1  ; mnttab index+1 (0 = not mounted)
 27212 00000008 <res 00000004>      <1>   .offset: resd 1  ; file offset/pointer (64 bit) 
 27213 0000000C <res 00000004>      <1>   .o64:	   resd 1  ; higher 32 bit of file offset
 27214                              <1>  .size:  ; = 16		
 27215                              <1> endstruc
 27216                              <1> 
 27217                              <1> ; 22/11/2021
 27218                              <1> fp.size equ file.size
 27219                              <1> 
 27220                              <1> ; 22/11/2021 (16/05/2021)
 27221 00006C90 <res 00000320>      <1> fsp:	resb NFILES * fp.size ; NFILES * 16
 27222                              <1> ; 15/04/2015
 27223                              <1> ;fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
 27224 00006FB0 <res 00000020>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
 27225 00006FD0 <res 00000004>      <1> ii:	 resd 1 ; 22/11/2021 ; 32 bit inode number (high word is 0)
 27226                              <1> ; 22/11/2021
 27227 00006FD4 <res 00000001>      <1> idev:	resb 1 ; logical drive number of current inode, [ii]
 27228 00006FD5 <res 00000001>      <1> cdev:	resb 1 ; current logical drive number for current user
 27229                              <1> 
 27230                              <1> ; 18/05/2015
 27231                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
 27232                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
 27233                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
 27234                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
 27235                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
 27236                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
 27237                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
 27238                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
 27239                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
 27240                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
 27241                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
 27242 00006FD6 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
 27243                              <1> 	        ; as above, for physical drives numbers in following table
 27244 00006FD7 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
 27245                              <1> ; 15/04/2015
 27246 00006FD8 <res 00000001>      <1> active:	 resb 1 
 27247 00006FD9 <res 00000001>      <1> 	 resb 1 ; 09/06/2015
 27248 00006FDA <res 00000002>      <1> mpid:	 resw 1
 27249                              <1> ; 22/11/2021 (32 bit inode numbers)
 27250 00006FDC <res 00000004>      <1> rootdir: resd 1
 27251 00006FE0 <res 00000004>      <1> mnti:	 resd 1
 27252                              <1> 
 27253                              <1> ; 14/02/2014
 27254                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
 27255                              <1> ;		      Single level run queue
 27256                              <1> ;		      (in order to solve sleep/wakeup lock)
 27257 00006FE4 <res 00000002>      <1> runq:	 resw 1
 27258 00006FE6 <res 00000001>      <1> imod:	 resb 1
 27259 00006FE7 <res 00000001>      <1> smod:	 resb 1
 27260 00006FE8 <res 00000001>      <1> mmod:	 resb 1
 27261 00006FE9 <res 00000001>      <1> sysflg:	 resb 1
 27262                              <1> 
 27263 00006FEA <res 00000002>      <1> alignb 4
 27264                              <1> 
 27265                              <1> user:
 27266                              <1> 	; 24/10/2021
 27267                              <1> 	; 18/10/2021
 27268                              <1> 	; 10/06/2021
 27269                              <1> 	; 30/05/2021
 27270                              <1> 	; 29/05/2021
 27271                              <1> 	; 21/05/2021
 27272                              <1> 	; 20/05/2021
 27273                              <1> 	; 16/05/2021
 27274                              <1> 	; 01/05/2021
 27275                              <1> 	; 27/03/2021
 27276                              <1> 	; 17/04/2020, 28/04/2020
 27277                              <1> 	; 25/03/2020, 28/03/2020
 27278                              <1> 	; 20/03/2020, 22/03/2020, 23/03/2020
 27279                              <1> 	; 05/03/2020, 08/03/2020, 14/03/2020
 27280                              <1> 	; 07/02/2020 - Retro UNIX 386 v2
 27281                              <1> 	;
 27282                              <1> 	; 27/02/2017 - TRDOS 386
 27283                              <1> 	; 13/01/2017 - TRDOS 386
 27284                              <1> 	; 10/01/2017 - TRDOS 386
 27285                              <1> 	; 19/12/2016 - TRDOS 386	
 27286                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0) 
 27287                              <1> 	; 	       [u.pri] usage method modification
 27288                              <1> 	;
 27289                              <1> 	; 04/12/2015 - Retro UNIX 386 v1.1 (14 byte file/directory names)
 27290                              <1> 	; 18/10/2015
 27291                              <1> 	; 12/10/2015
 27292                              <1> 	; 21/09/2015
 27293                              <1> 	; 24/07/2015
 27294                              <1> 	; 16/06/2015
 27295                              <1> 	; 09/06/2015
 27296                              <1> 	; 11/05/2015
 27297                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 27298                              <1> 	; 10/10/2013
 27299                              <1> 	; 11/03/2013. 
 27300                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
 27301                              <1> 	;u.
 27302                              <1> 
 27303 00006FEC <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
 27304 00006FF0 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
 27305 00006FF4 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
 27306 00006FF8 <res 00000002>      <1> 	u.cdir:	  resw 1
 27307 00006FFA <res 00000002>      <1> 		  resw 1 ; 28/03/2020 - reserved for 32 bit inode number
 27308                              <1> 	;u.cdrv:  resw 1 ; 17/04/2020 (dword alignment) 
 27309 00006FFC <res 00000001>      <1> 	u.cdrv:   resb 1 ; 01/05/2021
 27310 00006FFD <res 00000001>      <1> 		  resb 1 ; 01/05/2021 (dword alignment)
 27311                              <1> 	;u.fp:	  resb 10 ; Retro UNIX 386 v1
 27312 00006FFE <res 0000000A>      <1> 	u.fp:	  resb OPENFILES ; Retro UNIX 386 v2 ; 28/03/2020 
 27313                              <1> 	u.fsp:	  ; 16/05/2021
 27314 00007008 <res 00000004>      <1> 	u.fofp:	  resd 1 ; 16/05/2021 (pointer to fsp entry)
 27315 0000700C <res 00000004>      <1> 	u.dirp:	  resd 1
 27316 00007010 <res 00000004>      <1> 	u.namep:  resd 1
 27317 00007014 <res 00000004>      <1> 	u.off:	  resd 1
 27318 00007018 <res 00000004>      <1> 		  resd 1 ; 08/03/2020 - Retro UNIX 386 v2 - 64 bit fptr
 27319 0000701C <res 00000004>      <1> 	u.base:	  resd 1
 27320 00007020 <res 00000004>      <1> 	u.count:  resd 1
 27321 00007024 <res 00000004>      <1> 	u.nread:  resd 1
 27322 00007028 <res 00000004>      <1> 	u.break:  resd 1 ; break
 27323                              <1> 	; 16/05/2021 (Retro UNIX 386 v2)
 27324 0000702C <res 00000001>      <1> 	u.mode:   resb 1 ; 16/05/2021 (sysread, syswrite, 'rdwr' file mode)
 27325                              <1> 	; 10/01/2017 (TRDOS 386, relocation and dword alignment)
 27326                              <1> 	; tty number (rtty, rcvt, wtty)
 27327 0000702D <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
 27328 0000702E <res 00000002>      <1> 	u.ttyp:	  resw 1 
 27329 00007030 <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
 27330                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
 27331 00007040 <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
 27332 00007041 <res 00000001>      <1> 		  resb 1 ; 17/04/2020
 27333 00007042 <res 00000001>      <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
 27334 00007043 <res 00000001>      <1> 		  resb 1 ; 17/04/2020
 27335                              <1> 	; 10/06/2021
 27336                              <1> 	;u.signal: resw 1 ; 21/05/2021 - Retro UNIX 386 v2
 27337                              <1> 	;	  resw 1 ; reserved ; 21/05/2021	
 27338 00007044 <res 00000002>      <1> 	u.intr:	  resw 1
 27339 00007046 <res 00000002>      <1> 	u.quit:	  resw 1
 27340                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
 27341                              <1> 	;u.ilgins: resw 1 ; 10/01/2017
 27342                              <1> 	;u.cdrv:  resw 1 ; cdev ; 17/04/2020 (moved to up)
 27343                              <1> 	;u.uid:	  resb 1 ; uid
 27344                              <1> 	;u.ruid:  resb 1
 27345 00007048 <res 00000001>      <1> 	u.bsys:	  resb 1
 27346 00007049 <res 00000001>      <1> 	u.uno:	  resb 1
 27347 0000704A <res 00000002>      <1>         u.uid:	  resw 1 ; uid	; 27/03/2021 - Retro UNIX 386 v2
 27348 0000704C <res 00000002>      <1> 	u.ruid:	  resw 1	; 16 bit uid
 27349 0000704E <res 00000001>      <1> 	u.gid:	  resb 1 ; gid 	; 27/03/2021 - Retro UNIX 386 v2
 27350 0000704F <res 00000001>      <1> 	u.rgid:	  resb 1
 27351                              <1> 	; 20/05/2021 - Retro UNIX 386 v2
 27352 00007050 <res 00000004>      <1> 	u.procp:  resd 1 ; /* pointer to proc structure */		
 27353 00007054 <res 00000004>      <1> 	u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
 27354 00007058 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
 27355 0000705C <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
 27356 00007060 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
 27357                              <1> 		; 24/10/2021 (32 bit value for Retro UNIX 386 v2)
 27358 00007064 <res 00000004>      <1> 	u.pcount: resd 1 ; 20/05/2015 (byte -transfer- count for page)
 27359                              <1> 	;u.pncount: resw 1 
 27360                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
 27361                              <1> 	;u.pnbase:  resd 1 
 27362                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
 27363                              <1> 			 ; 09/06/2015
 27364 00007068 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign
 27365                              <1> 		; 08/03/2020 (block device read/write flag for 'sioreg')		
 27366 00007069 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
 27367                              <1> 			 ; 24/07/2015 - 24/06/2015
 27368                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
 27369                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
 27370                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
 27371                              <1>  			 ; 24/06/2015	  	
 27372                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
 27373                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
 27374                              <1> 	; last error number
 27375 0000706A <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
 27376                              <1> 			; Retro UNIX 8086/386 v1 feature only!
 27377                              <1> 			; 21/09/2015 (debugging - page fault analyze)
 27378 0000706E <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
 27379                              <1> 		; 29/05/2021 - Retro UNIX 386 v2, 2021 (sleep, psig)
 27380 00007072 <res 00000004>      <1> 	u.signal: resd 1 ; unix signal recognition (enabling, accepting) bits	
 27381 00007076 <res 00000001>      <1> 	u.srb:	  resb 1 ; signal handling/responding method
 27382 00007077 <res 00000001>      <1> 	u.snum:	  resb 1 ; signal number (last signal number)
 27383 00007078 <res 00000001>      <1> 	u.exit:	  resb 1 ; exit code ; 30/05/2021 - Retro UNIX 386 v2
 27384 00007079 <res 00000001>      <1> 	u.s_lock: resb 1 ; signal handling (phase) lock	
 27385 0000707A <res 00000004>      <1> 	u.s_addr: resd 1 ; Signal Response Byte or signal handler (callback) address
 27386 0000707E <res 00000004>      <1> 	u.s_time: resd 1 ; signal time in unix epoch format		
 27387                              <1> 		; 19/12/2016 (TRDOS 386)	
 27388 00007082 <res 00000004>      <1> 	u.tcb:	  resd 1 ; Timer callback address/flag which will be used by timer int
 27389                              <1> 		; 13/01/2017 (TRDOS 386)
 27390 00007086 <res 00000001>      <1> 	u.t_lock: resb 1 ; Timer interrupt (callback) lock (unlocked by 'sysrele')
 27391 00007087 <res 00000001>      <1> 	u.t_mode: resb 1 ; running mode during timer interrupt (0= system, 0FFh= user)
 27392                              <1> 		; 26/02/2017 (TRDOS 386)
 27393 00007088 <res 00000001>      <1> 	u.irqc:	  resb 1  ; Count of IRQ callback services (IRQs in use)
 27394                              <1> 		; 28/02/2017 (TRDOS 386) 
 27395 00007089 <res 00000001>      <1> 	u.irqwait: resb 1 ; IRQ waiting for callback service flag (IRQ number, If > 0)
 27396 0000708A <res 00000001>      <1> 	u.r_lock:  resb 1 ; 'IRQ callback service is in progress' flag (IRQ lock)
 27397 0000708B <res 00000001>      <1> 	u.r_mode:  resb 1 ; running mode during hardware interrupt
 27398                              <1> 		; 07/02/2020 - Retro UNIX 386 v2
 27399 0000708C <res 00000001>      <1> 	u.redir:  resb 1 ; device func redirection permitted by user (if u.redir > 0)
 27400                              <1> 		; 26/02/2020 - Retro UNIX 386 v2
 27401 0000708D <res 00000001>      <1> 	u.rwm:	  resb 1  ; read & write mode for devices/drives, 0 = direct, 1 = fs r/w 
 27402                              <1> 		; 24/02/2020 - Retro UNIX 386 v2
 27403                              <1> 		; 24/10/2021 (32 bit value)
 27404 0000708E <res 00000004>      <1> 	u.scount: resd 1 ; sub byte count ; 22/03/2020 
 27405                              <1> 		; 07/03/2020 - Retro UNIX 386 v2
 27406 00007092 <res 00000002>      <1> 	u.bps:	  resw 1 ; u.bps = bytes per sector, for readi and writei
 27407 00007094 <res 00000002>      <1> 		  resw 1 ; 24/10/2021 (32 bit value for using with 32 bit registers)	
 27408                              <1> 		; 23/03/2020 - Retro UNIX 386 v2
 27409 00007096 <res 00000002>      <1> 	u.timeout: resw 1 ; timeout setting (seconds) -for 'sleep'-
 27410                              <1> 		; 28/04/2020 - Retro UNIX 386 v2
 27411 00007098 <res 00000001>      <1> 	u.lock:	  resb 1 ; Device lock flag (bit 0 is for device/disk read/write)
 27412                              <1> 		; 24/04/2020
 27413                              <1> 		; 17/04/2020 - Retro UNIX 386 v2
 27414 00007099 <res 00000001>      <1> 	u.ifs:	  resb 1 ; (current) installable file system driver index number
 27415                              <1> 		; 25/03/2020
 27416                              <1> 		; 20/03/2020
 27417                              <1> 	;u.lcount: resd 1 ; last byte count for 'writei' (for restoring write count)	
 27418                              <1> 
 27419                              <1> 		; 08/03/2020 - Retro UNIX 386 v2 ('sioreg, 'readi')
 27420                              <1> 	;u.limit: resd 1  ; disk/file size limit for block device read/write ('sioreg')			
 27421                              <1> 	;	  resd 1  ; 08/03/2020 - 64 bit limit (disk size in bytes)
 27422                              <1> 	;	; 26/02/2020 - Retro UNIX 386 v2
 27423                              <1> 	;u.sector: resd 1  ; current sector (for readi and writei, device r/w)  		
 27424                              <1> 	;u.buffer: resd 1  ; current buffer (for readi and writei, device r/w) 
 27425                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 27426                              <1> 	;u.devmm:  resw 1 ; device major (hb) and minor (lb) numbers
 27427                              <1> 	;u.zero:   resw 1 ; 14/03/2020 - Must be ZERO for current version
 27428                              <1> 		; 22/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 27429 0000709A <res 00000004>      <1> 	u.device: resd 1 ; (blk, chr) device description table (entry) address 	
 27430                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 27431 0000709E <res 00000004>      <1> 	u.function: resd 1 ; device function (read, write)
 27432                              <1> 		; 22/03/2020 - Retro UNIX 386 v2, 2020 (readi, writei)
 27433 000070A2 <res 00000004>      <1> 	u.buffer: resd 1  ; for saving buffer header address for 'poke'
 27434 000070A6 <res 00000002>      <1> 	u.inode:  resw 1  ; for saving inode number of current (device) inode
 27435 000070A8 <res 00000002>      <1> 		  resw 1  ; 18/10/2021 Retro UNIX 386 v2 - 32 bit inode number			
 27436 000070AA <res 00000001>      <1> 	u.idev:	  resb 1  ; for saving logical drv number of current (dev) inode
 27437                              <1> 		; 27/02/2017 (TRDOS 386) 
 27438 000070AB <res 00000001>      <1> 	u.fpsave: resb 1  ; TRDOS 386, 'save/restore FPU registers' flag
 27439                              <1> alignb 4
 27440                              <1> 	; !! wrong sizing in TRDOS 386 v2.0.4 (in 'ubss.s', 28/02/2017) !! 
 27441                              <1> 	;u.fpregs: resb 94 ; 94 byte area for saving and restoring FPU registers
 27442                              <1> 	; 30/05/2021 - Retro UNIX 386 v2
 27443 000070AC <res 0000006C>      <1> 	u.fpregs: resb 108 ; 108 byte area for saving and restoring FPU registers	
 27444                              <1> alignb 4
 27445                              <1> 
 27446                              <1> U_SIZE	equ $ - user
 27447                              <1> 
 27448                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
 27449 00007118 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
 27450 0000711C <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
 27451 00007120 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
 27452 00007124 <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
 27453 00007126 <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
 27454 00007128 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
 27455                              <1> 
 27456                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
 27457                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
 27458 0000712C <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
 27459 0000712D <res 00000001>      <1> rwdsk:	 resb 1 ;; Read/Write function number (diskio) - 16/06/2015
 27460 0000712E <res 00000001>      <1> mget_rw: resb 1 ; 22/11/2021 
 27461 0000712F <res 00000001>      <1> retry_count: resb 1 ; Disk I/O retry count - 11/06/2015
 27462                              <1> 
 27463                              <1> ; 22/11/2021 - Retro UNIX 386 v2 compatibility
 27464                              <1> level:	resd 0  ; level, level+1, level+2, level+3  ; for 'mget' procedure
 27465                              <1> 
 27466                              <1> ;alignb 4
 27467                              <1> 
 27468                              <1> ; 22/08/2015
 27469 00007130 <res 00000C30>      <1> buffer: resb nbuf * 520
 27470                              <1> 
 27471 00007D60 <res 00000008>      <1> sb0:	resd 2
 27472                              <1> ;s:
 27473                              <1> ; (root disk) super block buffer
 27474                              <1> systm:
 27475                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatible super block
 27476                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
 27477                              <1> 	; 11/03/2013. 
 27478                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
 27479                              <1> 	;s.
 27480                              <1> 
 27481                              <1> 	;resw 1
 27482                              <1> 	;resb 360 ; 2880 sectors ; original UNIX v1 value: 128
 27483                              <1> 	;resw 1
 27484                              <1> 	;resb 32 ; 256+40 inodes ; original UNIX v1 value: 64
 27485                              <1> 	;s.time: resd 1
 27486                              <1> 	;s.syst: resd 1
 27487                              <1>         ;s.wait_: resd 1 ; wait
 27488                              <1> 	;s.idlet: resd 1
 27489                              <1> 	;s.chrgt: resd 1
 27490                              <1> 	;s.drerr: resw 1
 27491                              <1> 
 27492                              <1> 	; 27/11/2021
 27493 00007D68 <res 00000200>      <1> 	resb 512	
 27494                              <1> 
 27495                              <1> ;S_SIZE	equ $ - systm
 27496                              <1> 
 27497                              <1> 	;resb 512-S_SIZE ; 03/06/2015	 
 27498                              <1> 
 27499 00007F68 <res 00000008>      <1> sb1:	resd 2
 27500                              <1> ; (mounted disk) super block buffer
 27501                              <1> mount:	
 27502 00007F70 <res 00000200>      <1> 	resb 512  ; 03/06/2015
 27503                              <1> 
 27504                              <1> ; 27/11/2021
 27505                              <1> ; these are will be used for disk block allocation ('alloc' proc)
 27506                              <1> free_map_offset: 
 27507 00008170 <res 00000004>      <1> 		resd 1
 27508 00008174 <res 00000004>      <1> free_map_index:	resd 1
 27509                              <1> free_map_sector:
 27510 00008178 <res 00000004>      <1> 		resd 1
 27511                              <1> ;free_map_buffer:
 27512                              <1> ;		resd 1
 27513                              <1> 
 27514                              <1> ; 27/11/2021 - temporary !
 27515 0000817C <res 00000004>      <1> s.time:		resd 1
 27516                              <1> 
 27517                              <1> ;/ ux -- unix
 27518                              <1> ;
 27519                              <1> ;systm:
 27520                              <1> ;
 27521                              <1> ;	.=.+2
 27522                              <1> ;	.=.+128.
 27523                              <1> ;	.=.+2
 27524                              <1> ;	.=.+64.
 27525                              <1> ;	s.time: .=.+4
 27526                              <1> ;	s.syst: .=.+4
 27527                              <1> ;	s.wait: .=.+4
 27528                              <1> ;	s.idlet:.=.+4
 27529                              <1> ;	s.chrgt:.=.+4
 27530                              <1> ;	s.drerr:.=.+2
 27531                              <1> ;inode:
 27532                              <1> ;	i.flgs: .=.+2
 27533                              <1> ;	i.nlks: .=.+1
 27534                              <1> ;	i.uid:  .=.+1
 27535                              <1> ;	i.size: .=.+2
 27536                              <1> ;	i.dskp: .=.+16.
 27537                              <1> ;	i.ctim: .=.+4
 27538                              <1> ;	i.mtim: .=.+4
 27539                              <1> ;	. = inode+32.
 27540                              <1> ;mount:	.=.+1024.
 27541                              <1> ;proc:
 27542                              <1> ;	p.pid:  .=.+[2*nproc]
 27543                              <1> ;	p.dska: .=.+[2*nproc]
 27544                              <1> ;	p.ppid: .=.+[2*nproc]
 27545                              <1> ;	p.break:.=.+[2*nproc]
 27546                              <1> ;	p.link: .=.+nproc
 27547                              <1> ;	p.stat: .=.+nproc
 27548                              <1> ;tty:
 27549                              <1> ;	. = .+[ntty*8.]
 27550                              <1> ;fsp:	.=.+[nfiles*8.]
 27551                              <1> ;bufp:	.=.+[nbuf*2]+6
 27552                              <1> ;sb0:	.=.+8
 27553                              <1> ;sb1:	.=.+8
 27554                              <1> ;swp:	.=.+8
 27555                              <1> ;ii:	.=.+2
 27556                              <1> ;idev:	.=.+2
 27557                              <1> ;cdev:	.=.+2
 27558                              <1> ;deverr: .=.+12.
 27559                              <1> ;active: .=.+2
 27560                              <1> ;rfap:	.=.+2
 27561                              <1> ;rkap:	.=.+2
 27562                              <1> ;tcap:	.=.+2
 27563                              <1> ;tcstate:.=.+2
 27564                              <1> ;tcerrc: .=.+2
 27565                              <1> ;mnti:	.=.+2
 27566                              <1> ;mntd:	.=.+2
 27567                              <1> ;mpid:	.=.+2
 27568                              <1> ;clockp: .=.+2
 27569                              <1> ;rootdir:.=.+2
 27570                              <1> ;toutt:	.=.+16.
 27571                              <1> ;touts: .=.+32.
 27572                              <1> ;runq:	.=.+6
 27573                              <1> ;
 27574                              <1> ;wlist:	.=.+40.
 27575                              <1> ;cc:	.=.+30.
 27576                              <1> ;cf:	.=.+31.
 27577                              <1> ;cl:	.=.+31.
 27578                              <1> ;clist:	.=.+510.
 27579                              <1> ;imod:	.=.+1
 27580                              <1> ;smod:	.=.+1
 27581                              <1> ;mmod:	.=.+1
 27582                              <1> ;uquant: .=.+1
 27583                              <1> ;sysflg: .=.+1
 27584                              <1> ;pptiflg:.=.+1
 27585                              <1> ;ttyoch: .=.+1
 27586                              <1> ; .even
 27587                              <1> ; .=.+100.; sstack:
 27588                              <1> ;buffer: .=.+[ntty*140.]
 27589                              <1> ;	.=.+[nbuf*520.]
 27590                              <1> ;
 27591                              <1> ; . = core-64.
 27592                              <1> ;user:
 27593                              <1> ;	u.sp:    .=.+2
 27594                              <1> ;	u.usp:   .=.+2
 27595                              <1> ;	u.r0:    .=.+2
 27596                              <1> ;	u.cdir:  .=.+2
 27597                              <1> ;	u.fp:    .=.+10.
 27598                              <1> ;	u.fofp:  .=.+2
 27599                              <1> ;	u.dirp:  .=.+2
 27600                              <1> ;	u.namep: .=.+2
 27601                              <1> ;	u.off:   .=.+2
 27602                              <1> ;	u.base:  .=.+2
 27603                              <1> ;	u.count: .=.+2
 27604                              <1> ;	u.nread: .=.+2
 27605                              <1> ;	u.break: .=.+2
 27606                              <1> ;	u.ttyp:  .=.+2
 27607                              <1> ;	u.dirbuf:.=.+10.
 27608                              <1> ;	u.pri:   .=.+2
 27609                              <1> ;	u.intr:  .=.+2
 27610                              <1> ;	u.quit:  .=.+2
 27611                              <1> ;	u.emt:   .=.+2
 27612                              <1> ;	u.ilgins:.=.+2
 27613                              <1> ;	u.cdev:  .=.+2
 27614                              <1> ;	u.uid:   .=.+1
 27615                              <1> ;	u.ruid:  .=.+1
 27616                              <1> ;	u.bsys:  .=.+1
 27617                              <1> ;	u.uno:   .=.+1
 27618                              <1> ;. = core
 27619                                  
 27620                                  ; 17/04/2021
 27621                                  ; (memory page swap parameters are disabled as temporary)
 27622                                  ;
 27623                                  ;; Memory (swap) Data (11/03/2015)
 27624                                  ; 09/03/2015
 27625                                  ;swpq_count: resw 1 ; count of pages on the swap que
 27626                                  ;swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
 27627                                  ;swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes).	
 27628                                  ;swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 27629                                  ;swpd_next:  resd 1 ; next free page block
 27630                                  ;swpd_last:  resd 1 ; last swap page block	
 27631                                  
 27632                                  alignb 4
 27633                                  
 27634                                  ; 10/07/2015
 27635                                  ; 28/08/2014
 27636 00008180 <res 00000004>          error_code:	resd 1
 27637                                  ; 29/08/2014
 27638 00008184 <res 00000004>          FaultOffset: 	resd 1
 27639                                  ; 21/09/2015
 27640 00008188 <res 00000004>          PF_Count:	resd 1	; total page fault count
 27641                                  		       	; (for debugging - page fault analyze)
 27642                                  		 	; 'page _fault_handler' (memory.s)
 27643                                  			; 'sysgeterr' (u9.s)
 27644                                  ;; 21/08/2015
 27645                                  ;;buffer: resb (nbuf*520) ;; sysdefs.s, ux.s
 27646                                  
 27647                                  bss_end:
 27648                                  
 27649                                  ; 27/12/2013
 27650                                  _end:  ; end of kernel code (and read only data, just before bss)
