     1                                  ; ****************************************************************************
     2                                  ; UNIX386.ASM (RETRO UNIX 386 Kernel) - v0.2.1.0
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; NASM version 2.11 (unix386.s)
     5                                  ;
     6                                  ; RETRO UNIX 386 (Retro Unix == Turkish Rational Unix)
     7                                  ; Operating System Project (v0.2) by ERDOGAN TAN (Beginning: 24/12/2013)
     8                                  ;
     9                                  ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
    10                                  ; (v0.1 - Beginning: 11/07/2012)
    11                                  ;
    12                                  ; [ Last Modification: 03/01/2016 ]
    13                                  ;
    14                                  ; Derived from UNIX Operating System (v1.0 for PDP-11) 
    15                                  ; (Original) Source Code by Ken Thompson (1971-1972)
    16                                  ; <Bell Laboratories (17/3/1972)>
    17                                  ; <Preliminary Release of UNIX Implementation Document>
    18                                  ;
    19                                  ; Derived from 'UNIX v7/x86' source code by Robert Nordier (1999)
    20                                  ; UNIX V7/x86 source code: see www.nordier.com/v7x86 for details.
    21                                  ;
    22                                  ; ****************************************************************************
    23                                  
    24                                  ; 24/12/2013
    25                                  
    26                                  ; Entering protected mode:
    27                                  ; Derived from 'simple_asm.txt' source code file and 
    28                                  ; 'The world of Protected mode' tutorial/article by Gregor Brunmar (2003)
    29                                  ; (gregor.brunmar@home.se)
    30                                  ; http://www.osdever.net/tutorials/view/the-world-of-protected-mode
    31                                  ;
    32                                  
    33                                  ; "The Real, Protected, Long mode assembly tutorial for PCs" 
    34                                  ; by Michael Chourdakis (2009) 
    35                                  ; http://www.codeproject.com/Articles/45788/
    36                                  ; http://www.michaelchourdakis.com
    37                                  ;
    38                                  
    39                                  ; Global Descriptor Table:
    40                                  ; Derived from 'head.s" source code of Linux v1.0 kernel
    41                                  ; by Linus Torvalds (1991-1992)
    42                                  ;
    43                                  
    44                                  KLOAD	equ 10000h ; Kernel loading address
    45                                  	; NOTE: Retro UNIX 8086 v1 /boot code loads kernel at 1000h:0000h 
    46                                  KCODE	equ 08h	; Code segment descriptor (ring 0)
    47                                  KDATA	equ 10h	; Data segment descriptor (ring 0)
    48                                  ; 19/03/2015
    49                                  UCODE	equ 1Bh ; 18h + 3h  (ring 3)
    50                                  UDATA	equ 23h ; 20h + 3h  (ring 3)
    51                                  ; 24/03/2015
    52                                  TSS	equ 28h	; Task state segment descriptor (ring 0)
    53                                  ; 19/03/2015
    54                                  CORE	equ 400000h  ; Start of USER's virtual/linear address space 
    55                                  		     ; (at the end of the 1st 4MB)
    56                                  ECORE	equ 0FFC00000h ; End of USER's virtual address space (4GB - 4MB)
    57                                  		     ; ULIMIT = (ECORE/4096) - 1 = 0FFBFFh (in GDT)
    58                                  
    59                                  ; 27/12/2013
    60                                  KEND    equ KLOAD + 65536 ; (28/12/2013) (end of kernel space)
    61                                  
    62                                  ; IBM PC/AT BIOS ----- 10/06/85 (postequ.inc)
    63                                  ;--------- CMOS TABLE LOCATION ADDRESS'S -------------------------------------
    64                                  CMOS_SECONDS	EQU	00H		; SECONDS (BCD)
    65                                  CMOS_MINUTES	EQU	02H		; MINUTES (BCD)	
    66                                  CMOS_HOURS	EQU	04H		; HOURS (BCD)
    67                                  CMOS_DAY_WEEK	EQU	06H		; DAY OF THE WEEK  (BCD)
    68                                  CMOS_DAY_MONTH	EQU	07H		; DAY OF THE MONTH (BCD) 
    69                                  CMOS_MONTH	EQU	08H		; MONTH (BCD)
    70                                  CMOS_YEAR	EQU	09H		; YEAR (TWO DIGITS) (BCD)
    71                                  CMOS_CENTURY	EQU	32H		; DATE CENTURY BYTE (BCD)
    72                                  CMOS_REG_A	EQU	0AH		; STATUS REGISTER A
    73                                  CMOS_REG_B	EQU	00BH		; STATUS REGISTER B  ALARM
    74                                  CMOS_REG_C	EQU	00CH		; STATUS REGISTER C  FLAGS
    75                                  CMOS_REG_D	EQU	0DH		; STATUS REGISTER D  BATTERY
    76                                  CMOS_SHUT_DOWN	EQU	0FH		; SHUTDOWN STATUS COMMAND BYTE
    77                                  ;----------------------------------------
    78                                  ;	CMOS EQUATES FOR THIS SYSTEM	;
    79                                  ;-----------------------------------------------------------------------------
    80                                  CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
    81                                  CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
    82                                  NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
    83                                  					; HIGH BIT OF CMOS LOCATION ADDRESS
    84                                  
    85                                  ; Memory Allocation Table Address
    86                                  ; 05/11/2014
    87                                  ; 31/10/2014
    88                                  MEM_ALLOC_TBL	equ	100000h		; Memory Allocation Table at the end of
    89                                  					; the 1st 1 MB memory space.
    90                                  					; (This address must be aligned
    91                                  					;  on 128 KB boundary, if it will be
    92                                  					;  changed later.)
    93                                  					; ((lower 17 bits of 32 bit M.A.T.
    94                                  					;   address must be ZERO)).
    95                                  					; ((((Reason: 32 bit allocation 
    96                                  					;     instructions, dword steps)))
    97                                  					; (((byte >> 12 --> page >> 5)))  
    98                                  ;04/11/2014	
    99                                  PDE_A_PRESENT	equ	1		; Present flag for PDE
   100                                  PDE_A_WRITE	equ 	2		; Writable (write permission) flag
   101                                  PDE_A_USER	equ	4		; User (non-system/kernel) page flag
   102                                  ;
   103                                  PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
   104                                  PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
   105                                  PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
   106                                  PTE_A_ACCESS    equ	32		; Accessed flag (bit 5) ; 09/03/2015
   107                                  
   108                                  ; 17/02/2015 (unix386.s)
   109                                  ; 10/12/2014 - 30/12/2014 (0B000h -> 9000h) (dsectrm2.s)
   110                                  DPT_SEGM equ 09000h  ; FDPT segment (EDD v1.1, EDD v3)
   111                                  ;
   112                                  HD0_DPT	 equ 0	    ; Disk parameter table address for hd0
   113                                  HD1_DPT	 equ 32	    ; Disk parameter table address for hd1
   114                                  HD2_DPT	 equ 64	    ; Disk parameter table address for hd2
   115                                  HD3_DPT	 equ 96	    ; Disk parameter table address for hd3
   116                                  
   117                                  
   118                                  ; FDPT (Phoenix, Enhanced Disk Drive Specification v1.1, v3.0)
   119                                  ;      (HDPT: Programmer's Guide to the AMIBIOS, 1993)
   120                                  ;
   121                                  FDPT_CYLS	equ 0 ; 1 word, number of cylinders
   122                                  FDPT_HDS	equ 2 ; 1 byte, number of heads
   123                                  FDPT_TT		equ 3 ; 1 byte, A0h = translated FDPT with logical values
   124                                  		      ; otherwise it is standard FDPT with physical values 	
   125                                  FDPT_PCMP	equ 5 ; 1 word, starting write precompensation cylinder
   126                                  		      ; (obsolete for IDE/ATA drives)
   127                                  FDPT_CB		equ 8 ; 1 byte, drive control byte
   128                                  			; Bits 7-6 : Enable or disable retries (00h = enable)
   129                                  			; Bit 5	: 1 = Defect map is located at last cyl. + 1
   130                                  			; Bit 4 : Reserved. Always 0
   131                                  			; Bit 3 : Set to 1 if more than 8 heads
   132                                  			; Bit 2-0 : Reserved. Alsways 0
   133                                  FDPT_LZ		equ 12 ; 1 word, landing zone (obsolete for IDE/ATA drives)
   134                                  FDPT_SPT	equ 14 ; 1 byte, sectors per track
   135                                  
   136                                  ; Floppy Drive Parameters Table (Programmer's Guide to the AMIBIOS, 1993)
   137                                  ; (11 bytes long) will be used by diskette handler/bios
   138                                  ; which is derived from IBM PC-AT BIOS (DISKETTE.ASM, 21/04/1986).						 	  		 	  
   139                                  
   140                                  [BITS 16]       ; We need 16-bit intructions for Real mode
   141                                  
   142                                  [ORG 0] 
   143                                  	; 12/11/2014
   144                                  	; Save boot drive number (that is default root drive)
   145 00000000 8816[D46D]              	mov	[boot_drv], dl ; physical drv number
   146                                  
   147                                  	; Determine installed memory
   148                                  	; 31/10/2014
   149                                  	;
   150 00000004 B801E8                  	mov	ax, 0E801h ; Get memory size 
   151 00000007 CD15                    	int	15h	   ; for large configurations
   152 00000009 7308                    	jnc	short chk_ms
   153 0000000B B488                    	mov	ah, 88h    ; Get extended memory size 
   154 0000000D CD15                    	int	15h
   155                                  	;	   
   156                                  	;mov	al, 17h	; Extended memory (1K blocks) low byte
   157                                  	;out	70h, al ; select CMOS register
   158                                  	;in	al, 71h ; read data (1 byte)
   159                                  	;mov	cl, al
   160                                  	;mov	al, 18h ; Extended memory (1K blocks) high byte
   161                                  	;out	70h, al ; select CMOS register
   162                                  	;in	al, 71h ; read data (1 byte)
   163                                  	;mov	ch, al
   164                                   	;      
   165 0000000F 89C1                    	mov	cx, ax
   166 00000011 31D2                    	xor	dx, dx
   167                                  chk_ms:
   168 00000013 890E[D06D]              	mov	[mem_1m_1k], cx
   169 00000017 8916[D26D]              	mov	[mem_16m_64k], dx
   170                                  	; 05/11/2014
   171                                  	;and	dx, dx
   172                                  	;jz	short L2
   173 0000001B 81F90004                        cmp     cx, 1024
   174 0000001F 7315                    	jnb	short L0
   175                                  		 ; insufficient memory_error	
   176                                  		 ; Minimum 2 MB memory is needed... 
   177                                  	; 05/11/2014
   178                                  	; (real mode error printing)
   179 00000021 FB                      	sti
   180 00000022 BE[496C]                	mov	si, msg_out_of_memory
   181 00000025 BB0700                  	mov	bx, 7
   182 00000028 B40E                    	mov	ah, 0Eh	; write tty
   183                                  oom_1:
   184 0000002A AC                      	lodsb
   185 0000002B 08C0                    	or	al, al
   186 0000002D 7404                    	jz	short oom_2
   187 0000002F CD10                    	int	10h
   188 00000031 EBF7                    	jmp	short oom_1
   189                                  oom_2:
   190 00000033 F4                              hlt
   191 00000034 EBFD                    	jmp	short oom_2
   192                                  
   193                                  L0:
   194                                  %include 'diskinit.inc' ; 07/03/2015
   195                              <1> ; Retro UNIX 386 v1 Kernel - DISKINIT.INC
   196                              <1> ; Last Modification: 10/07/2015
   197                              <1> 
   198                              <1> ; DISK I/O SYSTEM INITIALIZATION - Erdogan Tan (Retro UNIX 386 v1 project)
   199                              <1> 
   200                              <1> ; ///////// DISK I/O SYSTEM STRUCTURE INITIALIZATION ///////////////
   201                              <1> 
   202                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
   203                              <1> ;L0:
   204                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
   205                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
   206 00000036 BA7F00              <1> 	mov	dx, 7Fh
   207                              <1> L1:	
   208 00000039 FEC2                <1> 	inc	dl
   209 0000003B B441                <1> 	mov	ah, 41h ; Check extensions present
   210                              <1> 			; Phoenix EDD v1.1 - EDD v3
   211 0000003D BBAA55              <1> 	mov	bx, 55AAh
   212 00000040 CD13                <1> 	int 	13h
   213 00000042 721A                <1> 	jc	short L2
   214 00000044 81FB55AA            <1> 	cmp	bx, 0AA55h
   215 00000048 7514                <1> 	jne	short L2
   216 0000004A FE06[D76D]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
   217 0000004E 8816[D66D]          <1>         mov     [last_drv], dl  ; last hard disk number
   218 00000052 BB[5A6D]            <1> 	mov	bx, hd0_type - 80h
   219 00000055 01D3                <1> 	add	bx, dx	 
   220 00000057 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
   221                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
   222                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
   223                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
   224                              <1>                          ;            (EDD) ready (DPTE ready)
   225                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
   226                              <1>                          ;            (EDD-3)
   227                              <1> 			 ; Bit 4 to 15 - 0, Reserved
   228 00000059 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
   229 0000005C 72DB                <1> 	jb	short L1
   230                              <1> L2:
   231                              <1> 	; 23/11/2014
   232                              <1> 	; 19/11/2014
   233 0000005E 30D2                <1> 	xor	dl, dl  ; 0
   234 00000060 66BE[D86D0000]      <1> 	mov	esi, fd0_type
   235                              <1> L3:
   236                              <1> 	; 14/01/2015
   237 00000066 8816[D56D]          <1> 	mov	[drv], dl
   238                              <1> 	;
   239 0000006A B408                <1> 	mov 	ah, 08h ; Return drive parameters
   240 0000006C CD13                <1> 	int	13h	
   241 0000006E 7215                <1> 	jc	short L4
   242                              <1> 		; BL = drive type (for floppy drives)
   243                              <1> 		; DL = number of floppy drives
   244                              <1> 		;		
   245                              <1> 		; ES:DI = Address of DPT from BIOS
   246                              <1> 		;
   247 00000070 67881E              <1> 	mov	[esi], bl ;  Drive type
   248                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
   249                              <1> 	; 14/01/2015
   250 00000073 E8BE02              <1> 	call	set_disk_parms
   251                              <1> 	; 10/12/2014
   252 00000076 6681FE[D86D0000]    <1> 	cmp	esi, fd0_type
   253 0000007D 7706                <1> 	ja	short L4
   254 0000007F 6646                <1> 	inc	esi ; fd1_type
   255 00000081 B201                <1> 	mov	dl, 1
   256 00000083 EBE1                <1> 	jmp	short L3
   257                              <1> L4:
   258                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
   259 00000085 B27F                <1> 	mov	dl, 7Fh
   260                              <1> 	; 24/12/2014 (Temporary)
   261 00000087 803E[D76D]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
   262 0000008C 0F879000            <1>         ja      L10       ; yes, all fixed disk operations
   263                              <1> 			  ; will be performed according to
   264                              <1> 			  ; present EDD specification
   265                              <1> L6:
   266 00000090 FEC2                <1> 	inc 	dl
   267 00000092 8816[D56D]          <1>         mov     [drv], dl
   268 00000096 8816[D66D]          <1>         mov     [last_drv], dl ; 14/01/2015
   269 0000009A B408                <1> 	mov 	ah, 08h ; Return drive parameters
   270 0000009C CD13                <1> 	int	13h	; (conventional function)
   271 0000009E 0F829901            <1>         jc      L13	; fixed disk drive not ready
   272 000000A2 8816[D76D]          <1>         mov     [hdc], dl ; number of drives
   273                              <1> 	;; 14/01/2013
   274                              <1> 	;;push	cx
   275 000000A6 E88B02              <1> 	call	set_disk_parms
   276                              <1> 	;;pop	cx
   277                              <1> 	;
   278                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   279 000000A9 8A16[D56D]          <1>         mov     dl, [drv]
   280 000000AD BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   281 000000B0 80FA80              <1> 	cmp	dl, 80h
   282 000000B3 7603                <1> 	jna	short L7
   283 000000B5 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   284                              <1> L7:	
   285 000000B8 31C0                <1> 	xor	ax, ax
   286 000000BA 8ED8                <1> 	mov	ds, ax
   287 000000BC 8B37                <1>         mov     si, [bx]
   288 000000BE 8B4702              <1>         mov     ax, [bx+2] 
   289 000000C1 8ED8                <1> 	mov	ds, ax
   290 000000C3 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   291 000000C6 0F856D01            <1>         jne     L12 ; invalid FDPT
   292 000000CA BF0000              <1> 	mov	di, HD0_DPT
   293 000000CD 80FA80              <1> 	cmp	dl, 80h
   294 000000D0 7603                <1> 	jna	short L8
   295 000000D2 BF2000              <1> 	mov	di, HD1_DPT 
   296                              <1> L8:
   297                              <1> 	; 30/12/2014
   298 000000D5 B80090              <1> 	mov	ax, DPT_SEGM
   299 000000D8 8EC0                <1> 	mov	es, ax
   300                              <1> 	; 24/12/2014
   301 000000DA B90800              <1> 	mov	cx, 8
   302 000000DD F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   303 000000DF 8CC8                <1> 	mov	ax, cs
   304 000000E1 8ED8                <1> 	mov	ds, ax
   305                              <1> 	; 02/02/2015
   306 000000E3 8A0E[D56D]          <1>         mov     cl, [drv]
   307 000000E7 88CB                <1> 	mov	bl, cl
   308 000000E9 B8F001              <1> 	mov	ax, 1F0h
   309 000000EC 80E301              <1> 	and	bl, 1
   310 000000EF 7406                <1> 	jz	short L9
   311 000000F1 C0E304              <1> 	shl	bl, 4
   312 000000F4 2D8000              <1> 	sub	ax, 1F0h-170h
   313                              <1> L9:
   314 000000F7 AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   315 000000F8 050602              <1> 	add	ax, 206h
   316 000000FB AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   317 000000FC 88D8                <1> 	mov	al, bl
   318 000000FE 04A0                <1> 	add	al, 0A0h
   319 00000100 AA                  <1> 	stosb	; Device/Head Register upper nibble
   320                              <1> 	;
   321 00000101 FE06[D56D]          <1> 	inc	byte [drv]
   322 00000105 BB[5A6D]            <1> 	mov	bx, hd0_type - 80h
   323 00000108 01CB                <1> 	add	bx, cx
   324 0000010A 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   325 0000010D A0[D76D]            <1> 	mov	al, [hdc]
   326 00000110 FEC8                <1> 	dec	al
   327 00000112 0F842501            <1>         jz      L13
   328 00000116 80FA80              <1> 	cmp	dl, 80h
   329 00000119 0F8673FF            <1>         jna     L6
   330 0000011D E91B01              <1>         jmp     L13
   331                              <1> L10:
   332 00000120 FEC2                <1> 	inc 	dl
   333                              <1> 	; 25/12/2014
   334 00000122 8816[D56D]          <1> 	mov	[drv], dl
   335 00000126 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   336 00000128 CD13                <1> 	int	13h	; (conventional function)
   337 0000012A 0F820D01            <1>         jc      L13
   338                              <1> 	; 14/01/2015
   339 0000012E 8A16[D56D]          <1> 	mov	dl, [drv]
   340 00000132 52                  <1> 	push	dx
   341 00000133 51                  <1> 	push	cx
   342 00000134 E8FD01              <1> 	call	set_disk_parms
   343 00000137 59                  <1> 	pop	cx
   344 00000138 5A                  <1> 	pop	dx
   345                              <1> 	;
   346 00000139 66BE[5C810000]      <1> 	mov	esi, _end ; 30 byte temporary buffer address 	
   347                              <1> 			 ; at the '_end' of kernel.
   348 0000013F 67C7061E00          <1> 	mov	word [esi], 30
   349 00000144 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   350 00000146 CD13                <1> 	int	13h
   351 00000148 0F82EF00            <1>         jc      L13
   352                              <1> 	; 14/01/2015
   353 0000014C 6629DB              <1> 	sub	ebx, ebx
   354 0000014F 88D3                <1> 	mov	bl, dl
   355 00000151 80EB80              <1> 	sub	bl, 80h
   356 00000154 6681C3[DA6D0000]    <1> 	add	ebx, hd0_type
   357 0000015B 678A03              <1> 	mov 	al, [ebx]
   358 0000015E 0C80                <1> 	or	al, 80h
   359 00000160 678803              <1> 	mov 	[ebx], al	
   360 00000163 6681EB[D86D0000]    <1> 	sub	ebx, hd0_type - 2 ; 15/01/2015
   361 0000016A 6681C3[246E0000]    <1> 	add	ebx, drv.status
   362 00000171 678803              <1> 	mov	[ebx], al
   363 00000174 66678B4610          <1> 	mov	eax, [esi+16]
   364                              <1> 	; 28/02/2015
   365 00000179 6621C0              <1> 	and 	eax, eax
   366 0000017C 7416                <1> 	jz	short L10_A0h 
   367                              <1> 			; 'CHS only' disks on EDD system 
   368                              <1> 			;  are reported with ZERO disk size
   369 0000017E 6681EB[246E0000]    <1> 	sub	ebx, drv.status
   370 00000185 66C1E302            <1> 	shl	ebx, 2
   371 00000189 6681C3[086E0000]    <1> 	add	ebx, drv.size ; disk size (in sectors)
   372 00000190 66678903            <1> 	mov	[ebx], eax
   373                              <1> L10_A0h: ; Jump here to fix a ZERO (LBA) disk size problem 
   374                              <1> 	 ; for CHS disks (28/02/2015)
   375                              <1> 	; 30/12/2014
   376 00000194 BF0000              <1> 	mov	di, HD0_DPT
   377 00000197 88D0                <1> 	mov	al, dl
   378 00000199 83E003              <1> 	and 	ax, 3
   379 0000019C C0E005              <1> 	shl	al, 5 ; *32
   380 0000019F 01C7                <1> 	add 	di, ax
   381 000001A1 B80090              <1> 	mov	ax, DPT_SEGM
   382 000001A4 8EC0                <1> 	mov	es, ax
   383                              <1> 	;
   384 000001A6 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   385 000001A8 88CC                <1> 	mov	ah, cl	
   386 000001AA C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   387 000001AD 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   388 000001AE AB                  <1> 	stosw		
   389 000001AF 88F0                <1> 	mov	al, dh	; max. head number
   390 000001B1 FEC0                <1> 	inc	al
   391 000001B3 AA                  <1> 	stosb		; logical heads (limits 256)
   392 000001B4 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   393 000001B6 AA                  <1> 	stosb
   394 000001B7 8A440C              <1> 	mov	al, [si+12]
   395 000001BA AA                  <1> 	stosb		 ; physical sectors per track
   396 000001BB 31C0                <1>  	xor	ax, ax
   397                              <1> 	;dec	ax	 ; 02/01/2015 
   398 000001BD AB                  <1> 	stosw		 ; precompensation (obsolete)
   399                              <1> 	;xor	al, al	 ; 02/01/2015	
   400 000001BE AA                  <1> 	stosb		 ; reserved
   401 000001BF B008                <1> 	mov	al, 8	 ; drive control byte
   402                              <1> 		         ; (do not disable retries, 
   403                              <1> 			 ; more than 8 heads)
   404 000001C1 AA                  <1> 	stosb
   405 000001C2 8B4404              <1> 	mov	ax, [si+4]
   406 000001C5 AB                  <1> 	stosw		 ; physical number of cylinders	
   407                              <1> 	;push	ax	 ; 02/01/2015
   408 000001C6 8A4408              <1> 	mov	al, [si+8]
   409 000001C9 AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   410 000001CA 29C0                <1> 	sub 	ax, ax
   411                              <1> 	;pop	ax	 ; 02/01/2015	
   412 000001CC AB                  <1> 	stosw		 ; landing zone (obsolete)
   413 000001CD 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   414 000001CF 243F                <1> 	and 	al, 3Fh	
   415 000001D1 AA                  <1> 	stosb
   416                              <1> 	;sub	al, al	 ; checksum
   417                              <1> 	;stosb
   418                              <1> 	;
   419 000001D2 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   420 000001D5 AD                  <1> 	lodsw
   421 000001D6 50                  <1> 	push	ax	 ; (BIOS) DPTE offset
   422 000001D7 AD                  <1> 	lodsw
   423 000001D8 50                  <1> 	push	ax	 ; (BIOS) DPTE segment
   424                              <1> 	;
   425                              <1> 	; checksum calculation
   426 000001D9 89FE                <1> 	mov	si, di
   427 000001DB 06                  <1> 	push	es
   428 000001DC 1F                  <1> 	pop	ds
   429                              <1> 	;mov	cx, 16
   430 000001DD B90F00              <1> 	mov 	cx, 15
   431 000001E0 29CE                <1> 	sub	si, cx
   432 000001E2 30E4                <1> 	xor	ah, ah
   433                              <1> 	;del	cl
   434                              <1> L11:		
   435 000001E4 AC                  <1> 	lodsb
   436 000001E5 00C4                <1> 	add	ah, al
   437 000001E7 E2FB                <1> 	loop	L11
   438                              <1> 	;
   439 000001E9 88E0                <1> 	mov	al, ah
   440 000001EB F6D8                <1> 	neg	al	; -x+x = 0
   441 000001ED AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   442                              <1> 	;
   443 000001EE 1F                  <1> 	pop	ds	; (BIOS) DPTE segment
   444 000001EF 5E                  <1> 	pop	si	; (BIOS) DPTE offset	
   445                              <1> 	;
   446                              <1> 	; 23/02/2015
   447 000001F0 57                  <1> 	push	di
   448                              <1> 	; ES:DI points to DPTE (FDPTE) location
   449                              <1> 	;mov	cx, 8
   450 000001F1 B108                <1> 	mov	cl, 8
   451 000001F3 F3A5                <1> 	rep	movsw	
   452                              <1> 	;
   453                              <1> 	; 23/02/2015
   454                              <1> 	; (P)ATA drive and LBA validation
   455                              <1> 	; (invalidating SATA drives and setting
   456                              <1> 	; CHS type I/O for old type fixed disks)
   457 000001F5 5B                  <1> 	pop	bx
   458 000001F6 8CC8                <1> 	mov	ax, cs
   459 000001F8 8ED8                <1> 	mov	ds, ax
   460 000001FA 268B07              <1> 	mov	ax, [es:bx]
   461 000001FD 3DF001              <1> 	cmp	ax, 1F0h
   462 00000200 7418                <1> 	je	short L11a
   463 00000202 3D7001              <1> 	cmp	ax, 170h
   464 00000205 7413                <1> 	je	short L11a
   465                              <1> 	; invalidation 
   466                              <1> 	; (because base port address is not 1F0h or 170h)
   467 00000207 30FF                <1> 	xor	bh, bh
   468 00000209 88D3                <1> 	mov	bl, dl
   469 0000020B 80EB80              <1> 	sub	bl, 80h
   470 0000020E C687[DA6D]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   471 00000213 808F[266E]F0        <1>         or      byte [bx+drv.status+2], 0F0h ; (failure sign)
   472 00000218 EB14                <1> 	jmp	short L11b
   473                              <1> L11a:	
   474                              <1> 	; LBA validation
   475 0000021A 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   476 0000021E A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   477 00000220 750C                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   478                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   479 00000222 28FF                <1> 	sub	bh, bh
   480 00000224 88D3                <1> 	mov	bl, dl
   481 00000226 80EB80              <1> 	sub	bl, 80h ; 26/02/2015
   482 00000229 80A7[266E]FE        <1>         and     byte [bx+drv.status+2], 0FEh ; clear bit 0
   483                              <1> 				; bit 0 = LBA ready bit
   484                              <1> 	; 'diskio' procedure will check this bit !
   485                              <1> L11b:
   486 0000022E 3A16[D66D]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   487 00000232 7307                <1>         jnb     short L13
   488 00000234 E9E9FE              <1>         jmp     L10
   489                              <1> L12:
   490                              <1> 	; Restore data registers
   491 00000237 8CC8                <1> 	mov	ax, cs
   492 00000239 8ED8                <1> 	mov	ds, ax	
   493                              <1> L13:
   494                              <1> 	; 13/12/2014
   495 0000023B 0E                  <1> 	push	cs
   496 0000023C 07                  <1> 	pop	es
   497                              <1> L14:
   498 0000023D B411                <1> 	mov 	ah, 11h
   499 0000023F CD16                <1> 	int 	16h
   500 00000241 7406                <1> 	jz 	short L15 ; no keys in keyboard buffer
   501 00000243 B010                <1> 	mov	al, 10h
   502 00000245 CD16                <1> 	int 	16h
   503 00000247 EBF4                <1> 	jmp 	short L14
   504                              <1> L15:
   505                              <1> ; //////
   506                              <1> 	; 24/11/2014
   507                              <1> 	; 19/11/2014
   508                              <1> 	; 14/11/2014
   509                              <1> 	; Temporary code for disk searching code check
   510                              <1> 	;
   511                              <1> 	; This code will show existing (usable) drives and also
   512                              <1> 	; will show EDD interface support status for hard disks		
   513                              <1> 	; (If status bit 7 is 1, Identify Device info is ready,
   514                              <1> 	; no need to get it again in protected mode...) 
   515                              <1> 	;	
   516                              <1> 	; 13/11/2014
   517 00000249 BB0700              <1> 	mov	bx, 7
   518 0000024C B40E                <1> 	mov	ah, 0Eh
   519 0000024E A0[D86D]            <1> 	mov	al, [fd0_type]
   520 00000251 20C0                <1> 	and	al, al
   521 00000253 743D                <1> 	jz	short L15a
   522 00000255 88C2                <1> 	mov	dl, al
   523 00000257 B046                <1> 	mov	al, 'F'
   524 00000259 CD10                <1> 	int 	10h
   525 0000025B B044                <1> 	mov	al, 'D'
   526 0000025D CD10                <1> 	int 	10h
   527 0000025F B030                <1> 	mov	al, '0'
   528 00000261 CD10                <1> 	int 	10h
   529 00000263 B020                <1> 	mov	al, ' '
   530 00000265 CD10                <1> 	int	10h
   531 00000267 E8B300              <1> 	call	L15c
   532 0000026A B020                <1> 	mov	al, ' '
   533 0000026C CD10                <1> 	int	10h
   534                              <1> 	;
   535 0000026E A0[D96D]            <1> 	mov	al, [fd1_type]
   536 00000271 20C0                <1> 	and	al, al
   537 00000273 741D                <1> 	jz	short L15a
   538 00000275 88C2                <1> 	mov	dl, al
   539 00000277 B046                <1> 	mov	al, 'F'
   540 00000279 CD10                <1> 	int 	10h
   541 0000027B B044                <1> 	mov	al, 'D'
   542 0000027D CD10                <1> 	int 	10h
   543 0000027F B031                <1> 	mov	al, '1'
   544 00000281 CD10                <1> 	int 	10h
   545 00000283 B020                <1> 	mov	al, ' '
   546 00000285 CD10                <1> 	int	10h
   547 00000287 E89300              <1> 	call	L15c
   548 0000028A B020                <1> 	mov	al, ' '
   549 0000028C CD10                <1> 	int	10h
   550 0000028E B020                <1> 	mov	al, ' '
   551 00000290 CD10                <1> 	int	10h
   552                              <1> L15a:
   553 00000292 A0[DA6D]            <1> 	mov	al, [hd0_type]
   554 00000295 20C0                <1> 	and	al, al
   555 00000297 7479                <1> 	jz	short L15b
   556 00000299 88C2                <1> 	mov	dl, al
   557 0000029B B048                <1> 	mov	al, 'H'
   558 0000029D CD10                <1> 	int 	10h
   559 0000029F B044                <1> 	mov	al, 'D'
   560 000002A1 CD10                <1> 	int 	10h
   561 000002A3 B030                <1> 	mov	al, '0'
   562 000002A5 CD10                <1> 	int 	10h
   563 000002A7 B020                <1> 	mov	al, ' '
   564 000002A9 CD10                <1> 	int 	10h
   565 000002AB E86F00              <1> 	call	L15c
   566 000002AE B020                <1> 	mov	al, ' '
   567 000002B0 CD10                <1> 	int	10h
   568                              <1> 	;
   569 000002B2 A0[DB6D]            <1> 	mov	al, [hd1_type]
   570 000002B5 20C0                <1> 	and	al, al
   571 000002B7 7459                <1> 	jz	short L15b
   572 000002B9 88C2                <1> 	mov	dl, al
   573 000002BB B048                <1> 	mov	al, 'H'
   574 000002BD CD10                <1> 	int 	10h
   575 000002BF B044                <1> 	mov	al, 'D'
   576 000002C1 CD10                <1> 	int 	10h
   577 000002C3 B031                <1> 	mov	al, '1'
   578 000002C5 CD10                <1> 	int 	10h
   579 000002C7 B020                <1> 	mov	al, ' '
   580 000002C9 CD10                <1> 	int 	10h
   581 000002CB E84F00              <1> 	call	L15c
   582 000002CE B020                <1> 	mov	al, ' '
   583 000002D0 CD10                <1> 	int	10h
   584                              <1> 	;
   585 000002D2 A0[DC6D]            <1> 	mov	al, [hd2_type]
   586 000002D5 20C0                <1> 	and	al, al
   587 000002D7 7439                <1> 	jz	short L15b
   588 000002D9 88C2                <1> 	mov	dl, al
   589 000002DB B048                <1> 	mov	al, 'H'
   590 000002DD CD10                <1> 	int 	10h
   591 000002DF B044                <1> 	mov	al, 'D'
   592 000002E1 CD10                <1> 	int 	10h
   593 000002E3 B032                <1> 	mov	al, '2'
   594 000002E5 CD10                <1> 	int 	10h
   595 000002E7 B020                <1> 	mov	al, ' '
   596 000002E9 CD10                <1> 	int 	10h
   597 000002EB E82F00              <1> 	call	L15c
   598 000002EE B020                <1> 	mov	al, ' '
   599 000002F0 CD10                <1> 	int	10h
   600                              <1> 	;
   601 000002F2 A0[DD6D]            <1> 	mov	al, [hd3_type]
   602 000002F5 20C0                <1> 	and	al, al
   603 000002F7 7419                <1> 	jz	short L15b
   604 000002F9 88C2                <1> 	mov	dl, al
   605 000002FB B048                <1> 	mov	al, 'H'
   606 000002FD CD10                <1> 	int 	10h
   607 000002FF B044                <1> 	mov	al, 'D'
   608 00000301 CD10                <1> 	int 	10h
   609 00000303 B033                <1> 	mov	al, '3'
   610 00000305 CD10                <1> 	int 	10h
   611 00000307 B020                <1> 	mov	al, ' '
   612 00000309 CD10                <1> 	int 	10h
   613 0000030B E80F00              <1> 	call	L15c
   614 0000030E B020                <1> 	mov	al, ' '
   615 00000310 CD10                <1> 	int	10h
   616                              <1> 	;
   617                              <1> L15b:
   618 00000312 B00D                <1> 	mov	al, 0Dh
   619 00000314 CD10                <1> 	int 	10h	
   620 00000316 B00A                <1> 	mov	al, 0Ah
   621 00000318 CD10                <1> 	int 	10h
   622                              <1> 	;;xor	ah, ah
   623                              <1> 	;;int 	16h	
   624                              <1> 	;
   625 0000031A E99A00              <1>         jmp     L16  ; jmp short L16
   626                              <1>         ;
   627                              <1> L15c:
   628 0000031D 88D6                <1> 	mov	dh, dl
   629 0000031F C0EE04              <1> 	shr	dh, 4
   630 00000322 80C630              <1> 	add	dh, 30h
   631 00000325 80E20F              <1> 	and	dl, 15
   632 00000328 80C230              <1> 	add	dl, 30h
   633 0000032B 88F0                <1> 	mov	al, dh
   634 0000032D CD10                <1> 	int	10h
   635 0000032F 88D0                <1> 	mov	al, dl
   636 00000331 CD10                <1> 	int	10h
   637 00000333 C3                  <1> 	retn
   638                              <1> 	;
   639                              <1> 	; end of temporary code for disk searching code check
   640                              <1> 
   641                              <1> ; //////
   642                              <1> 
   643                              <1> set_disk_parms:
   644                              <1> 	; 10/07/2015
   645                              <1> 	; 14/01/2015
   646                              <1> 	;push	ebx
   647 00000334 6629DB              <1> 	sub	ebx, ebx
   648 00000337 8A1E[D56D]          <1> 	mov	bl, [drv]
   649 0000033B 80FB80              <1> 	cmp	bl, 80h
   650 0000033E 7203                <1> 	jb	short sdp0
   651 00000340 80EB7E              <1> 	sub	bl, 7Eh
   652                              <1> sdp0:	
   653 00000343 6681C3[246E0000]    <1> 	add	ebx, drv.status
   654 0000034A 67C60380            <1>   	mov	byte [ebx], 80h ; 'Present' flag
   655                              <1> 	;
   656 0000034E 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   657 00000350 88CC                <1> 	mov	ah, cl ; 
   658 00000352 C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   659 00000355 6681EB[246E0000]    <1> 	sub	ebx, drv.status
   660 0000035C D0E3                <1> 	shl	bl, 1
   661 0000035E 6681C3[DE6D0000]    <1> 	add	ebx, drv.cylinders
   662 00000365 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   663 00000366 678903              <1> 	mov	[ebx], ax
   664 00000369 50                  <1> 	push	ax ; ** cylinders
   665 0000036A 6681EB[DE6D0000]    <1> 	sub	ebx, drv.cylinders
   666 00000371 6681C3[EC6D0000]    <1> 	add	ebx, drv.heads
   667 00000378 30E4                <1> 	xor	ah, ah
   668 0000037A 88F0                <1> 	mov	al, dh ; heads
   669 0000037C 40                  <1> 	inc	ax
   670 0000037D 678903              <1> 	mov	[ebx], ax
   671 00000380 6681EB[EC6D0000]    <1>         sub     ebx, drv.heads
   672 00000387 6681C3[FA6D0000]    <1>         add     ebx, drv.spt
   673 0000038E 30ED                <1> 	xor	ch, ch
   674 00000390 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   675 00000393 67890B              <1> 	mov	[ebx], cx
   676 00000396 6681EB[FA6D0000]    <1>         sub     ebx, drv.spt
   677 0000039D 66D1E3              <1> 	shl	ebx, 1
   678 000003A0 6681C3[086E0000]    <1> 	add	ebx, drv.size ; disk size (in sectors)
   679                              <1> 	; LBA size = cylinders * heads * secpertrack
   680 000003A7 F7E1                <1> 	mul	cx 
   681 000003A9 89C2                <1> 	mov	dx, ax	; heads*spt					
   682 000003AB 58                  <1> 	pop	ax ; ** cylinders
   683 000003AC 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   684 000003AD F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   685 000003AF 678903              <1> 	mov	[ebx], ax
   686 000003B2 67895302            <1> 	mov	[ebx+2], dx
   687                              <1> 	;
   688                              <1> 	;pop	ebx
   689 000003B6 C3                  <1> 	retn
   690                              <1> 
   691                              <1> ;align 2
   692                              <1> 
   693                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   694                              <1> ;heads	  :  dw 0, 0, 0, 0, 0, 0
   695                              <1> ;spt	  :  dw 0, 0, 0, 0, 0, 0
   696                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   697                              <1> 
   698                              <1> ;last_drv:
   699                              <1> ;	db  0
   700                              <1> ;drv_status:
   701                              <1> ;	db  0,0,0,0,0,0
   702                              <1> ;	db 0
   703                              <1> 
   704                              <1> 
   705                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   706                              <1> 
   707                              <1> L16:
   708                                  
   709                                  	; 10/11/2014
   710 000003B7 FA                           	cli	; Disable interrupts (clear interrupt flag)
   711                                  		; Reset Interrupt MASK Registers (Master&Slave)
   712                                  	;mov	al, 0FFh	; mask off all interrupts
   713                                  	;out	21h, al		; on master PIC (8259)
   714                                  	;jmp 	$+2  ; (delay)
   715                                  	;out	0A1h, al	; on slave PIC (8259)
   716                                  	;
   717                                  	; Disable NMI 
   718 000003B8 B080                    	mov   	al, 80h 
   719 000003BA E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   720                                  	;23/02/2015
   721 000003BC 90                      	nop			;
   722                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   723                                  				; for preventing unknown state (!?)
   724                                  	;
   725                                   	; 20/08/2014
   726                                  	; Moving the kernel 64 KB back (to physical address 0)
   727                                  	; DS = CS = 1000h
   728                                  	; 05/11/2014
   729 000003BD 31C0                    	xor	ax, ax
   730 000003BF 8EC0                    	mov	es, ax ; ES = 0
   731                                  	;
   732 000003C1 B90040                  	mov	cx, (KEND - KLOAD)/4
   733 000003C4 31F6                    	xor	si, si
   734 000003C6 31FF                    	xor	di, di
   735 000003C8 F366A5                  	rep	movsd
   736                                  	;
   737 000003CB 06                      	push	es ; 0
   738 000003CC 68[D003]                	push	L17
   739 000003CF CB                      	retf
   740                                  	;
   741                                  L17:
   742                                  	; Turn off the floppy drive motor
   743 000003D0 BAF203                          mov     dx, 3F2h
   744 000003D3 EE                              out     dx, al ; 0 ; 31/12/2013
   745                                  
   746                                  	; Enable access to memory above one megabyte
   747                                  L18:
   748 000003D4 E464                    	in	al, 64h
   749 000003D6 A802                    	test	al, 2
   750 000003D8 75FA                            jnz     short L18
   751 000003DA B0D1                    	mov	al, 0D1h	; Write output port
   752 000003DC E664                    	out	64h, al
   753                                  L19:
   754 000003DE E464                    	in	al, 64h
   755 000003E0 A802                    	test	al, 2
   756 000003E2 75FA                            jnz     short L19
   757 000003E4 B0DF                    	mov	al, 0DFh	; Enable A20 line
   758 000003E6 E660                    	out	60h, al
   759                                  ;L20:
   760                                  	;
   761                                  	; Load global descriptor table register
   762                                  
   763                                          ;mov     ax, cs
   764                                          ;mov     ds, ax
   765                                  
   766 000003E8 2E0F0116[8068]                  lgdt    [cs:gdtd]
   767                                  
   768 000003EE 0F20C0                          mov     eax, cr0
   769                                  	; or 	eax, 1
   770 000003F1 40                      	inc     ax
   771 000003F2 0F22C0                  	mov     cr0, eax
   772                                  
   773                                  	; Jump to 32 bit code
   774                                  	
   775 000003F5 66                      	db 66h 			; Prefix for 32-bit
   776 000003F6 EA                      	db 0EAh 		; Opcode for far jump
   777 000003F7 [FD030000]              	dd StartPM 		; Offset to start, 32-bit
   778                                  				; (1000h:StartPM = StartPM + 10000h)
   779 000003FB 0800                    	dw KCODE		; This is the selector for CODE32_DESCRIPTOR,
   780                                  				; assuming that StartPM resides in code32
   781                                  
   782                                  [BITS 32] 
   783                                  
   784                                  StartPM:
   785                                  	; Kernel Base Address = 0 ; 30/12/2013
   786 000003FD 66B81000                	mov ax, KDATA           ; Save data segment identifier
   787 00000401 8ED8                            mov ds, ax              ; Move a valid data segment into DS register
   788 00000403 8EC0                           	mov es, ax              ; Move data segment into ES register
   789 00000405 8EE0                           	mov fs, ax              ; Move data segment into FS register
   790 00000407 8EE8                          	mov gs, ax              ; Move data segment into GS register
   791 00000409 8ED0                            mov ss, ax              ; Move data segment into SS register
   792 0000040B BC00000900                      mov esp, 90000h         ; Move the stack pointer to 090000h
   793                                  
   794                                  clear_bss: ; Clear uninitialized data area
   795                                  	; 11/03/2015
   796 00000410 31C0                    	xor  eax, eax ; 0
   797 00000412 B9C7040000              	mov  ecx, (bss_end - bss_start)/4
   798                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   799 00000417 BF[406E0000]            	mov  edi, bss_start	
   800 0000041C F3AB                    	rep  stosd  		
   801                                  
   802                                  memory_init:
   803                                  	; Initialize memory allocation table and page tables
   804                                  	; 16/11/2014
   805                                  	; 15/11/2014
   806                                  	; 07/11/2014
   807                                  	; 06/11/2014
   808                                  	; 05/11/2014
   809                                  	; 04/11/2014
   810                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   811                                  	;
   812                                  ;	xor	eax, eax
   813                                  ;	xor 	ecx, ecx
   814 0000041E B108                    	mov	cl, 8
   815 00000420 BF00001000              	mov	edi, MEM_ALLOC_TBL	
   816 00000425 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   817                                  				   ; for the first 1 MB memory
   818                                  	;
   819 00000427 668B0D[D06D0000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   820                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   821 0000042E 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   822 00000432 890D[B0700000]          	mov	[free_pages], ecx
   823 00000438 668B15[D26D0000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   824                                  				   ; between 16 MB and 4 GB.	
   825 0000043F 6609D2                  	or	dx, dx
   826 00000442 7413                    	jz	short mi_0
   827                                  	;
   828 00000444 6689D0                  	mov	ax, dx
   829 00000447 C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   830 0000044A 0105[B0700000]          	add	[free_pages], eax
   831 00000450 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   832 00000455 EB07                    	jmp	short mi_1
   833                                  mi_0:
   834 00000457 6689C8                  	mov	ax, cx
   835 0000045A 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   836                                  mi_1:
   837 0000045E A3[AC700000]            	mov	[memory_size], eax ; Total available memory in pages
   838                                  				   ; 1 alloc. tbl. bit = 1 memory page
   839                                  				   ; 32 allocation bits = 32 mem. pages   
   840                                  	;
   841 00000463 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   842 00000468 C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   843                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   844                                  				   ;  --> x M.A.T. pages, if y = 0
   845 0000046B 66A3[C0700000]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   846 00000471 C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   847                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   848 00000474 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   849                                  	; Set/Calculate Kernel's Page Directory Address
   850 00000476 81C300001000            	add	ebx, MEM_ALLOC_TBL
   851 0000047C 891D[A8700000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   852                                  				   ; just after the last M.A.T. page
   853                                  	;
   854 00000482 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   855 00000485 A3[B8700000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   856                                  	;			   ; (allocation status search must be 
   857                                  				   ; stopped after here)	
   858 0000048A 31C0                    	xor	eax, eax
   859 0000048C 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   860 0000048D 6651                    	push	cx
   861 0000048F C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   862                                  				   ; count of 32 allocation bits
   863 00000492 F3AB                    	rep	stosd
   864 00000494 6659                    	pop	cx
   865 00000496 40                      	inc	eax		   ; 0	
   866 00000497 80E11F                  	and	cl, 31		   ; remain bits
   867 0000049A 7412                    	jz	short mi_4
   868 0000049C 8907                    	mov	[edi], eax	   ; reset	
   869                                  mi_2:
   870 0000049E 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   871 000004A1 FEC9                    	dec	cl
   872 000004A3 7404                    	jz	short mi_3
   873 000004A5 FEC0                    	inc	al
   874 000004A7 EBF5                    	jmp	short mi_2
   875                                  mi_3:
   876 000004A9 28C0                    	sub	al, al	   	   ; 0
   877 000004AB 83C704                  	add	edi, 4		   ; 15/11/2014
   878                                  mi_4:
   879 000004AE 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   880 000004B1 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   881                                  	;	
   882 000004B3 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   883                                  	;	
   884 000004B8 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   885 000004BA 7406                    	jz	short mi_5	  ; jump if EDI points to 
   886                                  				  ;         end of first 16 MB	
   887 000004BC D1E9                    	shr	ecx, 1		  ; convert to dword count
   888 000004BE D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   889 000004C0 F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   890                                  				  ; (memory hole under 16 MB)
   891                                  mi_5:
   892 000004C2 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   893 000004C5 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   894 000004C7 9C                      	pushf			  ; 16/11/2014		
   895 000004C8 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   896 000004C9 F3AB                    	rep	stosd
   897 000004CB 40                      	inc	eax		  ; 0
   898 000004CC 9D                      	popf			  ; 16/11/2014
   899 000004CD 7305                    	jnc	short mi_6
   900 000004CF 6648                    	dec	ax		  ; eax = 0000FFFFh
   901 000004D1 AB                      	stosd
   902 000004D2 6640                    	inc	ax		  ; 0		
   903                                  mi_6:
   904 000004D4 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   905 000004D6 730A                    	jnb	short mi_7	  ; end of memory allocation table
   906                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   907 000004D8 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   908 000004DA 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   909 000004DC D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   910 000004DE D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   911 000004E0 F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   912                                  mi_7:
   913                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   914 000004E2 BA00001000              	mov	edx, MEM_ALLOC_TBL
   915                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   916                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   917 000004E7 668B0D[C0700000]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   918 000004EE 89D7                    	mov	edi, edx
   919 000004F0 C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   920                                  				  ; byte offset in M.A.T.
   921                                  				  ; (1 M.A.T. byte points to 
   922                                  				  ;	      32768 bytes)
   923                                  				  ; Note: MEM_ALLOC_TBL address 
   924                                  				  ; must be aligned on 128 KB 
   925                                  				  ; boundary!
   926 000004F3 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   927                                  	; eax = 0
   928 000004F5 290D[B0700000]          	sub	[free_pages], ecx ; 07/11/2014
   929                                  mi_8:
   930 000004FB 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   931                                  	;dec	bl
   932 000004FE FEC9                    	dec	cl
   933 00000500 7404                    	jz	short mi_9
   934 00000502 FEC0                    	inc	al
   935 00000504 EBF5                    	jmp	short mi_8
   936                                  mi_9:
   937                                  	;
   938                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   939                                  	;		(allocate pages for system page tables)
   940                                  
   941                                  	; edx = MEM_ALLOC_TBL
   942 00000506 8B0D[AC700000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   943 0000050C 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   944 00000512 C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   945                                  				 ; page table count (PDE count)
   946                                  	;
   947 00000515 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   948                                  	;
   949 00000516 41                      	inc	ecx		 ; +1 for kernel page directory	
   950                                  	;
   951 00000517 290D[B0700000]          	sub	[free_pages], ecx ; 07/11/2014
   952                                  	;
   953 0000051D 8B35[A8700000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   954 00000523 C1EE0C                  	shr	esi, 12		 ; convert to page number
   955                                  mi_10:
   956 00000526 89F0                    	mov	eax, esi	 ; allocation bit offset		 
   957 00000528 89C3                    	mov	ebx, eax
   958 0000052A C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   959 0000052D 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   960                                  				 ;   to align on dword boundary
   961 00000530 83E01F                  	and	eax, 31		 ; set allocation bit position 
   962                                  				 ;  (bit 0 to bit 31)
   963                                  	;
   964 00000533 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   965                                  	;
   966 00000535 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   967                                  	;
   968 00000538 46                      	inc	esi		 ; next page table
   969 00000539 E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   970                                  				 ; (ecx = page table count + 1)		
   971                                  	;
   972 0000053B 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
   973                                  	;
   974                                  	; Initialize Kernel Page Directory and Kernel Page Tables
   975                                  	;
   976                                  	; Initialize Kernel's Page Directory
   977 0000053C 8B3D[A8700000]          	mov	edi, [k_page_dir]
   978 00000542 89F8                    	mov	eax, edi
   979 00000544 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
   980                                  		     	      ; supervisor + read&write + present
   981 00000546 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
   982                                  mi_11:
   983 00000548 0500100000              	add	eax, 4096	; Add page size (PGSZ)
   984                                  			        ; EAX points to next page table
   985 0000054D AB                      	stosd
   986 0000054E E2F8                    	loop	mi_11
   987 00000550 29C0                    	sub	eax, eax	; Empty PDE
   988 00000552 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
   989 00000556 29D1                    	sub	ecx, edx
   990 00000558 7402                    	jz	short mi_12
   991 0000055A F3AB                    	rep	stosd 		; clear remain (empty) PDEs
   992                                  	;
   993                                  	; Initialization of Kernel's Page Directory is OK, here.
   994                                  mi_12:
   995                                  	; Initialize Kernel's Page Tables
   996                                  	;
   997                                  	; (EDI points to address of page table 0)
   998                                  	; eax = 0
   999 0000055C 8B0D[AC700000]          	mov	ecx, [memory_size] ; memory size in pages
  1000 00000562 89CA                    	mov	edx, ecx	; (***)
  1001 00000564 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
  1002                                  			     ; supervisor + read&write + present 	
  1003                                  mi_13:
  1004 00000566 AB                      	stosd
  1005 00000567 0500100000              	add	eax, 4096	
  1006 0000056C E2F8                    	loop	mi_13	
  1007 0000056E 6681E2FF03              	and	dx, 1023	; (***)
  1008 00000573 740B                    	jz	short mi_14
  1009 00000575 66B90004                	mov	cx, 1024	
  1010 00000579 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
  1011 0000057C 31C0                    	xor	eax, eax
  1012 0000057E F3AB                    	rep	stosd		; clear remain (empty) PTEs 
  1013                                  				; of the last page table
  1014                                  mi_14:
  1015                                  	;  Initialization of Kernel's Page Tables is OK, here.
  1016                                  	;
  1017 00000580 89F8                    	mov	eax, edi	; end of the last page table page
  1018                                  			        ; (beginging of user space pages)
  1019 00000582 C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
  1020 00000585 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
  1021                                  				; aligning on dword boundary	
  1022                                  	 
  1023 00000587 A3[BC700000]            	mov	[first_page], eax
  1024 0000058C A3[B4700000]            	mov	[next_page], eax ; The first free page pointer
  1025                                  				 ; for user programs
  1026                                  				 ; (Offset in Mem. Alloc. Tbl.)	
  1027                                  	;
  1028                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
  1029                                  	;
  1030                                  	
  1031                                  	; Enable paging
  1032                                  	;
  1033 00000591 A1[A8700000]                    mov     eax, [k_page_dir]
  1034 00000596 0F22D8                  	mov	cr3, eax
  1035 00000599 0F20C0                  	mov	eax, cr0
  1036 0000059C 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
  1037 000005A1 0F22C0                  	mov	cr0, eax
  1038                                          ;jmp    KCODE:StartPMP
  1039                                  
  1040 000005A4 EA                      	db 0EAh 		; Opcode for far jump
  1041 000005A5 [AB050000]                      dd StartPMP		; 32 bit offset
  1042 000005A9 0800                    	dw KCODE		; kernel code segment descriptor
  1043                                  
  1044                                  
  1045                                  StartPMP:
  1046                                  	; 06/11//2014
  1047                                  	; Clear video page 0
  1048                                  	;
  1049                                  	; Temporary Code
  1050                                  	;
  1051 000005AB B9E8030000              	mov	ecx, 80*25/2
  1052 000005B0 BF00800B00              	mov	edi, 0B8000h
  1053 000005B5 31C0                    	xor	eax, eax	; black background, black fore color
  1054 000005B7 F3AB                    	rep	stosd
  1055                                  	
  1056                                  	; 19/08/2014
  1057                                  	; Kernel Base Address = 0
  1058                                  	; It is mapped to (physically) 0 in the page table.
  1059                                  	; So, here is exactly 'StartPMP' address.
  1060                                  	;
  1061                                  	;;mov	ah, 4Eh	; Red background, yellow forecolor
  1062                                  	;;mov	esi, msgPM
  1063                                  	;; 14/08/2015 (kernel version message will appear
  1064                                  	;;	       when protected mode and paging is enabled)
  1065 000005B9 B40B                    	mov	ah, 0Bh ; Black background, light cyan forecolor
  1066 000005BB BE[616B0000]            	mov	esi, msgKVER
  1067 000005C0 BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
  1068                                  	; 20/08/2014
  1069 000005C5 E896010000              	call	printk
  1070                                  
  1071                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
  1072                                  	; // Set IRQ offsets
  1073                                  	;
  1074                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
  1075                                  	;
  1076                                  					;; ICW1
  1077 000005CA B011                    	mov	al, 11h			; Initialization sequence
  1078 000005CC E620                    	out	20h, al			; 	8259A-1
  1079                                  	; jmp 	$+2
  1080 000005CE E6A0                    	out	0A0h, al		; 	8259A-2
  1081                                  					;; ICW2
  1082 000005D0 B020                    	mov	al, 20h			; Start of hardware ints (20h)
  1083 000005D2 E621                    	out	21h, al			;	for 8259A-1
  1084                                  	; jmp 	$+2
  1085 000005D4 B028                    	mov	al, 28h			; Start of hardware ints (28h)
  1086 000005D6 E6A1                    	out	0A1h, al		; 	for 8259A-2
  1087                                  					;
  1088 000005D8 B004                    	mov	al, 04h			;; ICW3
  1089 000005DA E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
  1090                                  	; jmp 	$+2
  1091 000005DC B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
  1092 000005DE E6A1                    	out	0A1h, al		;
  1093                                  					;; ICW4
  1094 000005E0 B001                    	mov	al, 01h	 		;
  1095 000005E2 E621                    	out	21h, al			; 	8086 mode, normal EOI	
  1096                                  	; jmp 	$+2
  1097 000005E4 E6A1                    	out	0A1h, al		;	for both chips.
  1098                                  
  1099                                  	;mov	al, 0FFh	; mask off all interrupts for now
  1100                                  	;out	21h, al
  1101                                  	;; jmp 	$+2
  1102                                  	;out	0A1h, al
  1103                                  
  1104                                  	; 02/04/2015
  1105                                  	; 26/03/2015 System call (INT 30h) modification
  1106                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
  1107                                  	;
  1108                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
  1109                                  	;  setup_idt:
  1110                                  	;
  1111                                          ;; 16/02/2015
  1112                                  	;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1113                                  	; 21/08/2014 (timer_int)
  1114 000005E6 BE[8C680000]            	mov	esi, ilist
  1115 000005EB 8D3D[406E0000]          	lea	edi, [idt]
  1116                                  	; 26/03/2015
  1117 000005F1 B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
  1118                                  	; 02/04/2015
  1119 000005F6 BB00000800              	mov	ebx,  80000h
  1120                                  rp_sidt1:
  1121 000005FB AD                      	lodsd
  1122 000005FC 89C2                    	mov	edx, eax
  1123 000005FE 66BA008E                	mov	dx, 8E00h
  1124 00000602 6689C3                  	mov	bx, ax
  1125 00000605 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
  1126                                         			        ; /* interrupt gate - dpl=0, present */
  1127 00000607 AB                      	stosd	; selector & offset bits 0-15 	
  1128 00000608 89D0                    	mov	eax, edx
  1129 0000060A AB                      	stosd	; attributes & offset bits 16-23
  1130 0000060B E2EE                    	loop	rp_sidt1
  1131 0000060D B110                    	mov	cl, 16        ; 16 software interrupts (INT 30h to INT 3Fh)
  1132                                  rp_sidt2:
  1133 0000060F AD                      	lodsd
  1134 00000610 21C0                    	and	eax, eax
  1135 00000612 7413                    	jz	short rp_sidt3
  1136 00000614 89C2                    	mov	edx, eax
  1137 00000616 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1138 0000061A 6689C3                  	mov	bx, ax
  1139 0000061D 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1140 0000061F AB                      	stosd
  1141 00000620 89D0                    	mov	eax, edx
  1142 00000622 AB                      	stosd
  1143 00000623 E2EA                    	loop	rp_sidt2
  1144 00000625 EB16                    	jmp	short sidt_OK
  1145                                  rp_sidt3:
  1146 00000627 B8[8A0A0000]            	mov	eax, ignore_int
  1147 0000062C 89C2                    	mov	edx, eax
  1148 0000062E 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1149 00000632 6689C3                  	mov	bx, ax
  1150 00000635 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1151                                  rp_sidt4:
  1152 00000637 AB                      	stosd
  1153 00000638 92                      	xchg	eax, edx
  1154 00000639 AB                      	stosd
  1155 0000063A 92                      	xchg	edx, eax
  1156 0000063B E2FA                    	loop	rp_sidt4
  1157                                  sidt_OK: 
  1158 0000063D 0F011D[86680000]        	lidt 	[idtd]
  1159                                  	;
  1160                                  	; TSS descriptor setup ; 24/03/2015
  1161 00000644 B8[40700000]            	mov	eax, task_state_segment
  1162 00000649 66A3[7A680000]          	mov	[gdt_tss0], ax
  1163 0000064F C1C010                  	rol	eax, 16
  1164 00000652 A2[7C680000]            	mov	[gdt_tss1], al
  1165 00000657 8825[7F680000]          	mov	[gdt_tss2], ah
  1166 0000065D 66C705[A6700000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
  1167 00000665 00                 
  1168                                  		; 
  1169                                  		; IO Map Base address (When this address points
  1170                                  		; to end of the TSS, CPU does not use IO port 
  1171                                  		; permission bit map for RING 3 IO permissions, 
  1172                                  		; access to any IO ports in ring 3 will be forbidden.)
  1173                                   		;
  1174                                  	;mov	[tss.esp0], esp ; TSS offset 4
  1175                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
  1176 00000666 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
  1177                                  			 ; occurs (or a system call -software INT- is requested)
  1178                                  			 ; while cpu running in ring 3 (in user mode).				
  1179                                  			 ; (Kernel stack pointer and segment will be loaded
  1180                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
  1181 0000066A 0F00D8                  	ltr	ax  ; Load task register
  1182                                  	;
  1183                                  esp0_set0:
  1184                                  	; 30/07/2015
  1185 0000066D 8B0D[AC700000]          	mov 	ecx, [memory_size] ; memory size in pages
  1186 00000673 C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
  1187 00000676 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
  1188                                  			  ; (kernel mode virtual address)
  1189 0000067C 7605                    	jna	short esp0_set1
  1190                                  	;
  1191                                  	; If available memory > CORE (end of the 1st 4 MB)
  1192                                  	; set stack pointer to CORE
  1193                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
  1194                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
  1195 0000067E B900004000              	mov	ecx, CORE
  1196                                  esp0_set1:
  1197 00000683 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
  1198                                  esp0_set_ok:
  1199                                  	; 30/07/2015 (**tss.esp0**) 
  1200 00000685 8925[44700000]          	mov	[tss.esp0], esp
  1201 0000068B 66C705[48700000]10-             mov     word [tss.ss0], KDATA
  1202 00000693 00                 
  1203                                  	; 14/08/2015
  1204                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
  1205                                  	;
  1206                                  	;cli	; Disable interrupts (for CPU)
  1207                                  	;    (CPU will not handle hardware interrupts, except NMI!)
  1208                                  	;
  1209 00000694 30C0                    	xor	al, al		; Enable all hardware interrupts!
  1210 00000696 E621                    	out	21h, al		; (IBM PC-AT compatibility)
  1211 00000698 EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
  1212 0000069A E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
  1213                                  				; (Even if related hardware component
  1214                                  				;  does not exist!)
  1215                                  	; Enable NMI 
  1216 0000069C B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
  1217 0000069E E670                    	out  	70h, al
  1218                                  	; 23/02/2015
  1219 000006A0 90                      	nop
  1220 000006A1 E471                    	in	al, 71h		; read in 71h just after writing out to 70h
  1221                                  				; for preventing unknown state (!?)
  1222                                  	;
  1223                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
  1224                                  	;
  1225                                  	; 02/09/2014
  1226 000006A3 6631DB                  	xor	bx, bx
  1227 000006A6 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
  1228 000006AA E8920F0000              	call	set_cpos
  1229                                  	;
  1230                                  	; 06/11/2014
  1231                                  	; Temporary Code
  1232                                  	;
  1233 000006AF E8C1110000              	call	memory_info
  1234                                  	; 14/08/2015
  1235                                  	;call getch ; 28/02/2015
  1236                                  drv_init:
  1237 000006B4 FB                      	sti	; Enable Interrupts 
  1238                                  	; 06/02/2015
  1239 000006B5 8B15[DA6D0000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
  1240 000006BB 668B1D[D86D0000]        	mov	bx, [fd0_type] ; fd0, fd1
  1241                                  	; 22/02/2015
  1242 000006C2 6621DB                  	and	bx, bx
  1243 000006C5 751B                    	jnz	short di1
  1244                                  	;
  1245 000006C7 09D2                    	or 	edx, edx
  1246 000006C9 7529                    	jnz	short di2
  1247                                  	;
  1248                                  setup_error:
  1249 000006CB BE[856C0000]            	mov 	esi, setup_error_msg
  1250                                  psem:	
  1251 000006D0 AC                      	lodsb
  1252 000006D1 08C0                    	or	al, al
  1253                                  	;jz	short haltx ; 22/02/2015
  1254 000006D3 7426                    	jz	short di3
  1255 000006D5 56                      	push	esi
  1256 000006D6 31DB                    	xor	ebx, ebx ; 0
  1257                                  			; Video page 0 (bl=0)
  1258 000006D8 B407                    	mov	ah, 07h ; Black background, 
  1259                                  			; light gray forecolor
  1260 000006DA E83E0E0000              	call	write_tty
  1261 000006DF 5E                      	pop	esi
  1262 000006E0 EBEE                    	jmp	short psem
  1263                                  
  1264                                  di1:
  1265                                  	; supress 'jmp short T6'
  1266                                  	;  (activate fdc motor control code)
  1267 000006E2 66C705[E1070000]90-     	mov	word [T5], 9090h ; nop
  1268 000006EA 90                 
  1269                                  	;
  1270                                  	;mov	ax, int_0Eh	; IRQ 6 handler
  1271                                  	;mov	di, 0Eh*4	; IRQ 6 vector
  1272                                  	;stosw
  1273                                  	;mov 	ax, cs
  1274                                  	;stosw
  1275                                  	;; 16/02/2015
  1276                                          ;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1277                                  	;
  1278 000006EB E8D6200000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
  1279                                  	;
  1280 000006F0 09D2                    	or	edx, edx
  1281 000006F2 7407                            jz      short di3
  1282                                  di2:
  1283 000006F4 E813210000              	call   	DISK_SETUP	; Initialize Fixed Disks
  1284 000006F9 72D0                            jc      short setup_error
  1285                                  di3:
  1286 000006FB E849110000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
  1287                                  	;
  1288 00000700 E8A5600000              	call	display_disks ; 07/03/2015  (Temporary)
  1289                                  ;haltx:
  1290                                  	; 14/08/2015
  1291                                  	;call	getch ; 22/02/2015
  1292 00000705 FB                      	sti	; Enable interrupts (for CPU)
  1293                                  	; 14/08/2015
  1294 00000706 B9FFFFFF0F              	mov 	ecx, 0FFFFFFFh	
  1295                                  md_info_msg_wait:
  1296 0000070B 51                      	push 	ecx
  1297 0000070C B001                    	mov	al, 1
  1298 0000070E 8A25[D6700000]          	mov 	ah, [ptty] ; active (current) video page
  1299 00000714 E8CD5D0000              	call	getc_n
  1300 00000719 59                      	pop	ecx
  1301 0000071A 7502                    	jnz	short md_info_msg_ok
  1302 0000071C E2ED                    	loop	md_info_msg_wait
  1303                                  md_info_msg_ok:
  1304                                  	; 30/06/2015
  1305 0000071E E800310000              	call	sys_init
  1306                                  	;
  1307                                  	;jmp 	cpu_reset ; 22/02/2015
  1308                                  hang:  
  1309                                  	; 23/02/2015
  1310                                  	;sti			; Enable interrupts
  1311 00000723 F4                      	hlt
  1312                                  	;
  1313                                  	;nop
  1314                                  	;; 03/12/2014
  1315                                  	;; 28/08/2014
  1316                                  	;mov	ah, 11h
  1317                                  	;call	getc
  1318                                  	;jz      _c8
  1319                                  	;
  1320                                  	; 23/02/2015
  1321                                  	; 06/02/2015
  1322                                  	; 07/09/2014
  1323 00000724 31DB                    	xor	ebx, ebx
  1324 00000726 8A1D[D6700000]          	mov	bl, [ptty]	; active_page
  1325 0000072C 89DE                    	mov	esi, ebx
  1326 0000072E 66D1E6                  	shl 	si, 1
  1327 00000731 81C6[D8700000]          	add	esi, ttychr
  1328 00000737 668B06                  	mov	ax, [esi]
  1329 0000073A 6621C0                  	and	ax, ax
  1330                                  	;jz	short _c8
  1331 0000073D 74E4                    	jz	short hang
  1332 0000073F 66C7060000              	mov	word [esi], 0
  1333 00000744 80FB03                  	cmp	bl, 3		; Video page 3
  1334                                  	;jb	short _c8
  1335 00000747 72DA                    	jb	short hang
  1336                                  	;	
  1337                                  	; 02/09/2014
  1338 00000749 B40E                    	mov	ah, 0Eh		; Yellow character 
  1339                                  				; on black background
  1340                                  	; 07/09/2014
  1341                                  nxtl:
  1342 0000074B 6653                    	push	bx
  1343                                  	;
  1344                                  	;xor	bx, bx		; bl = 0 (video page 0)
  1345                                  				; bh = 0 (video mode)
  1346                                  				; Retro UNIX 386 v1 - Video Mode 0
  1347                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
  1348 0000074D 6650                    	push	ax
  1349 0000074F E8C90D0000              	call 	write_tty
  1350 00000754 6658                    	pop	ax
  1351 00000756 665B                    	pop	bx ; 07/09/2014
  1352 00000758 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
  1353                                  	;jne	short _c8
  1354 0000075A 75C7                    	jne	short hang
  1355 0000075C B00A                    	mov	al, 0Ah		; next line
  1356 0000075E EBEB                    	jmp	short nxtl
  1357                                  	
  1358                                  ;_c8:
  1359                                  ;	; 25/08/2014
  1360                                  ;	cli				; Disable interrupts
  1361                                  ;	mov	al, [scounter + 1]
  1362                                  ;	and	al, al
  1363                                  ;	jnz	hang
  1364                                  ;	call	rtc_p
  1365                                  ;	jmp     hang
  1366                                  
  1367                                  
  1368                                  	; 27/08/2014
  1369                                  	; 20/08/2014
  1370                                  printk:
  1371                                          ;mov    edi, [scr_row]
  1372                                  pkl:
  1373 00000760 AC                      	lodsb
  1374 00000761 08C0                    	or 	al, al
  1375 00000763 7404                    	jz	short pkr
  1376 00000765 66AB                    	stosw
  1377 00000767 EBF7                    	jmp	short pkl
  1378                                  pkr:
  1379 00000769 C3                      	retn
  1380                                  
  1381                                  ; 25/07/2015
  1382                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
  1383                                  ; 17/02/2015
  1384                                  ; 06/02/2015 (unix386.s)
  1385                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
  1386                                  ;
  1387                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
  1388                                  ;
  1389                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
  1390                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
  1391                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
  1392                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
  1393                                  ;									       :
  1394                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
  1395                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
  1396                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
  1397                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
  1398                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
  1399                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
  1400                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
  1401                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
  1402                                  ;-------------------------------------------------------------------------------
  1403                                  ;
  1404                                  
  1405                                  timer_int:	; IRQ 0
  1406                                  ;int_08h:	; Timer
  1407                                  	; 14/10/2015
  1408                                  	; Here, we are simulating system call entry (for task switch)
  1409                                  	; (If multitasking is enabled, 
  1410                                  	; 'clock' procedure may jump to 'sysrelease')
  1411 0000076A 1E                      	push	ds
  1412 0000076B 06                      	push	es
  1413 0000076C 0FA0                    	push	fs
  1414 0000076E 0FA8                    	push	gs
  1415 00000770 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1416 00000771 66B91000                	mov     cx, KDATA
  1417 00000775 8ED9                            mov     ds, cx
  1418 00000777 8EC1                            mov     es, cx
  1419 00000779 8EE1                            mov     fs, cx
  1420 0000077B 8EE9                            mov     gs, cx
  1421                                  	;
  1422 0000077D 0F20D9                  	mov	ecx, cr3
  1423 00000780 890D[1F080000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1424                                  	;
  1425 00000786 3B0D[A8700000]          	cmp 	ecx, [k_page_dir]
  1426 0000078C 741F                    	je	short T3
  1427                                  	;
  1428                                  	; timer interrupt has been occurred while OS is in user mode
  1429 0000078E A3[80740000]            	mov 	[u.r0], eax
  1430 00000793 89E1                    	mov	ecx, esp
  1431 00000795 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1432 00000798 890D[78740000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1433 0000079E 8925[7C740000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1434                                  	;
  1435 000007A4 8B0D[A8700000]          	mov	ecx, [k_page_dir]
  1436 000007AA 0F22D9                  	mov	cr3, ecx
  1437                                  T3:
  1438 000007AD FB                      	sti				; INTERRUPTS BACK ON
  1439 000007AE 66FF05[24710000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
  1440 000007B5 7507                    	JNZ	short T4		; GO TO TEST_DAY
  1441 000007B7 66FF05[26710000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
  1442                                  T4:					; TEST_DAY
  1443 000007BE 66833D[26710000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
  1444 000007C6 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1445 000007C8 66813D[24710000]B0-     	CMP	word [TIMER_LOW],0B0H
  1446 000007D0 00                 
  1447 000007D1 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1448                                  
  1449                                  ;-----	TIMER HAS GONE 24 HOURS
  1450                                  	;;SUB	AX,AX
  1451                                  	;MOV	[TIMER_HIGH],AX
  1452                                  	;MOV	[TIMER_LOW],AX
  1453 000007D3 29C0                    	sub	eax, eax
  1454 000007D5 A3[24710000]            	mov	[TIMER_LH], eax
  1455                                  	;	
  1456 000007DA C605[28710000]01        	MOV	byte [TIMER_OFL],1
  1457                                  
  1458                                  ;-----	TEST FOR DISKETTE TIME OUT
  1459                                  
  1460                                  T5:
  1461                                  	; 23/12/2014
  1462 000007E1 EB1D                    	jmp	short T6		; will be replaced with nop, nop
  1463                                  					; (9090h) if a floppy disk
  1464                                  					; is detected.
  1465                                  	;mov	al,[CS:MOTOR_COUNT]
  1466 000007E3 A0[2B710000]            	mov	al, [MOTOR_COUNT]
  1467 000007E8 FEC8                    	dec	al
  1468                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1469 000007EA A2[2B710000]            	mov	[MOTOR_COUNT], al
  1470                                  	;mov	[ORG_MOTOR_COUNT], al
  1471 000007EF 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
  1472 000007F1 B0F0                    	mov 	al,0F0h
  1473                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
  1474 000007F3 2005[2A710000]          	and	[MOTOR_STATUS], al
  1475                                  	;and	[ORG_MOTOR_STATUS], al
  1476 000007F9 B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
  1477                                  					; bit 2 = enable controller
  1478                                  					;	1 = normal operation
  1479                                  					;	0 = reset	
  1480                                  					; bit 0, 1 = drive select
  1481                                  					; bit 4-7 = motor running bits 
  1482 000007FB 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
  1483 000007FF EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
  1484                                  T6:	
  1485                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
  1486                                  					; TIMER TICK INTERRUPT
  1487                                  	;;inc	word [wait_count] ;;27/02/2015
  1488                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
  1489                                  	;;;;cli
  1490                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
  1491 00000800 FF15[1B080000]          	call	[x_timer] ; 14/05/2015
  1492                                  T7:
  1493                                  	; 14/10/2015
  1494 00000806 B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  1495 00000808 FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  1496 00000809 E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  1497                                  	;
  1498 0000080B A1[1F080000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1499 00000810 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1500                                  	;
  1501 00000813 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1502                                  	;
  1503 00000814 0FA9                    	pop	gs
  1504 00000816 0FA1                    	pop	fs
  1505 00000818 07                      	pop	es
  1506 00000819 1F                      	pop	ds
  1507 0000081A CF                      	iretd	; return from interrupt
  1508                                  
  1509                                  
  1510                                  ; ////////////////
  1511                                  
  1512                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
  1513                                  x_timer:
  1514 0000081B [23080000]              	dd 	u_timer			; 14/05/2015
  1515                                  	;dd	clock
  1516                                  
  1517                                  ; 14/10/2015
  1518 0000081F 00000000                cr3reg: dd 0
  1519                                  
  1520                                  	; 06/02/2015
  1521                                  	; 07/09/2014
  1522                                  	; 21/08/2014
  1523                                  u_timer:
  1524                                  ;timer_int:	; IRQ 0
  1525                                  	; 06/02/2015
  1526                                  	;push	eax
  1527                                  	;push	edx
  1528                                  	;push	ecx
  1529                                  	;push	ebx
  1530                                  	;push	ds
  1531                                  	;push	es
  1532                                  	;mov	eax, KDATA
  1533                                  	;mov	ds, ax
  1534                                  	;mov	es, ax
  1535 00000823 FF05[EC700000]          	inc	dword [tcount]
  1536 00000829 BB[D26B0000]            	mov	ebx, tcountstr + 4
  1537 0000082E 66A1[EC700000]          	mov	ax, [tcount]
  1538 00000834 B90A000000              	mov	ecx, 10
  1539                                  rp_divtcnt:
  1540 00000839 31D2                    	xor	edx, edx
  1541 0000083B F7F1                    	div	ecx
  1542 0000083D 80C230                  	add	dl, 30h
  1543 00000840 8813                    	mov	[ebx], dl
  1544 00000842 6609C0                  	or	ax, ax
  1545 00000845 7403                    	jz	short print_lzero
  1546 00000847 4B                      	dec	ebx
  1547 00000848 EBEF                    	jmp	short rp_divtcnt
  1548                                  print_lzero:
  1549 0000084A 81FB[CE6B0000]          	cmp	ebx, tcountstr
  1550 00000850 7606                    	jna	short print_tcount
  1551 00000852 4B                      	dec	ebx
  1552 00000853 C60330                   	mov	byte [ebx], 30h
  1553 00000856 EBF2                    	jmp	short print_lzero
  1554                                  print_tcount:
  1555 00000858 56                      	push	esi
  1556 00000859 57                      	push	edi
  1557 0000085A BE[AA6B0000]            	mov	esi, timer_msg ; Timer interrupt message
  1558                                  	; 07/09/2014
  1559 0000085F 66BB0100                	mov	bx, 1		; Video page 1
  1560                                  ptmsg:
  1561 00000863 AC                      	lodsb
  1562 00000864 08C0                    	or	al, al
  1563 00000866 740F                    	jz	short ptmsg_ok
  1564 00000868 56                      	push	esi
  1565 00000869 6653                    	push	bx
  1566 0000086B B42F                            mov     ah,  2Fh ; Green background, white forecolor
  1567 0000086D E8AB0C0000              	call 	write_tty
  1568 00000872 665B                    	pop	bx
  1569 00000874 5E                      	pop	esi
  1570 00000875 EBEC                    	jmp	short ptmsg
  1571                                  	;; 27/08/2014
  1572                                  	;mov     edi, 0B8000h + 0A0h ; Row 1
  1573                                  	;call	printk
  1574                                  	;
  1575                                  ptmsg_ok:
  1576                                  	; 07/09/2014
  1577 00000877 6631D2                  	xor	dx, dx		; column 0, row 0
  1578 0000087A E8C20D0000              	call	set_cpos	; set cursor position to 0,0 
  1579                                  	; 23/02/2015
  1580                                  	; 25/08/2014
  1581                                  	;mov	ebx, scounter		; (seconds counter)
  1582                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1583                                  ;	dec	byte [scounter+1]
  1584                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1585                                  ;	jns	short u_timer_retn
  1586                                  	; 26/02/2015
  1587                                  ;	call	rtc_p
  1588                                  ;	mov	ebx, scounter		; (seconds counter)
  1589                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1590                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1591                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1592                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1593                                  ;	mov	byte [ebx], 5
  1594                                  ;	inc	byte [ebx+1] ; 19
  1595                                  ;;timer_eoi:
  1596                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1597                                  ;;	out	20h, al	; 8259 PORT
  1598                                  	;
  1599                                  ;u_timer_retn:  ; 06/02/2015
  1600 0000087F 5F                      	pop	edi
  1601 00000880 5E                      	pop	esi
  1602                                  	;pop	es
  1603                                  	;pop	ds
  1604                                  	;pop	ebx
  1605                                  	;pop	ecx
  1606                                  	;pop	edx
  1607                                  	;pop	eax
  1608                                  	;iret
  1609 00000881 C3                      	retn	; 06/02/2015
  1610                                  
  1611                                  	; 28/08/2014
  1612                                  irq0:
  1613 00000882 6A00                            push 	dword 0
  1614 00000884 EB48                    	jmp	short which_irq
  1615                                  irq1:
  1616 00000886 6A01                            push 	dword 1
  1617 00000888 EB44                    	jmp	short which_irq
  1618                                  irq2:
  1619 0000088A 6A02                            push 	dword 2
  1620 0000088C EB40                    	jmp	short which_irq
  1621                                  irq3:
  1622                                  	; 20/11/2015
  1623                                  	; 24/10/2015
  1624 0000088E 2EFF15[7B3F0000]        	call	dword [cs:com2_irq3]
  1625 00000895 6A03                    	push 	dword 3
  1626 00000897 EB35                    	jmp	short which_irq
  1627                                  irq4:
  1628                                  	; 20/11/2015
  1629                                  	; 24/10/2015
  1630 00000899 2EFF15[773F0000]        	call	dword [cs:com1_irq4]
  1631 000008A0 6A04                            push 	dword 4
  1632 000008A2 EB2A                    	jmp	short which_irq
  1633                                  irq5:
  1634 000008A4 6A05                            push 	dword 5
  1635 000008A6 EB26                    	jmp	short which_irq
  1636                                  irq6:
  1637 000008A8 6A06                            push 	dword 6
  1638 000008AA EB22                    	jmp	short which_irq
  1639                                  irq7:
  1640 000008AC 6A07                            push 	dword 7
  1641 000008AE EB1E                    	jmp	short which_irq
  1642                                  irq8:
  1643 000008B0 6A08                            push 	dword 8
  1644 000008B2 EB1A                    	jmp	short which_irq
  1645                                  irq9:
  1646 000008B4 6A09                            push 	dword 9
  1647 000008B6 EB16                    	jmp	short which_irq
  1648                                  irq10:
  1649 000008B8 6A0A                            push 	dword 10
  1650 000008BA EB12                    	jmp	short which_irq
  1651                                  irq11:
  1652 000008BC 6A0B                            push 	dword 11
  1653 000008BE EB0E                    	jmp	short which_irq
  1654                                  irq12:
  1655 000008C0 6A0C                            push 	dword 12
  1656 000008C2 EB0A                    	jmp	short which_irq
  1657                                  irq13:
  1658 000008C4 6A0D                            push 	dword 13
  1659 000008C6 EB06                    	jmp	short which_irq
  1660                                  irq14:
  1661 000008C8 6A0E                            push 	dword 14
  1662 000008CA EB02                    	jmp	short which_irq
  1663                                  irq15:
  1664 000008CC 6A0F                            push 	dword 15
  1665                                  	;jmp	short which_irq
  1666                                  
  1667                                  	; 19/10/2015
  1668                                  	; 29/08/2014
  1669                                  	; 21/08/2014
  1670                                  which_irq:
  1671 000008CE 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1672 000008D1 53                      	push	ebx
  1673 000008D2 56                      	push	esi
  1674 000008D3 57                      	push	edi
  1675 000008D4 1E                      	push 	ds
  1676 000008D5 06                      	push 	es
  1677                                  	;
  1678 000008D6 88C3                    	mov	bl, al
  1679                                  	;
  1680 000008D8 B810000000              	mov	eax, KDATA
  1681 000008DD 8ED8                    	mov	ds, ax
  1682 000008DF 8EC0                    	mov	es, ax
  1683                                  	; 19/10/2015
  1684 000008E1 FC                      	cld
  1685                                          ; 27/08/2014
  1686 000008E2 8105[596B0000]A000-             add     dword [scr_row], 0A0h
  1687 000008EA 0000               
  1688                                  	;
  1689 000008EC B417                    	mov	ah, 17h	; blue (1) background, 
  1690                                  			; light gray (7) forecolor
  1691 000008EE 8B3D[596B0000]                  mov     edi, [scr_row]
  1692 000008F4 B049                    	mov	al, 'I'
  1693 000008F6 66AB                    	stosw
  1694 000008F8 B052                    	mov	al, 'R'
  1695 000008FA 66AB                    	stosw
  1696 000008FC B051                    	mov	al, 'Q'
  1697 000008FE 66AB                    	stosw
  1698 00000900 B020                    	mov	al, ' '
  1699 00000902 66AB                    	stosw
  1700 00000904 88D8                    	mov	al, bl
  1701 00000906 3C0A                    	cmp	al, 10
  1702 00000908 7208                    	jb	short iix
  1703 0000090A B031                    	mov	al, '1'
  1704 0000090C 66AB                    	stosw
  1705 0000090E 88D8                    	mov	al, bl
  1706 00000910 2C0A                    	sub	al, 10
  1707                                  iix:
  1708 00000912 0430                    	add	al, '0'
  1709 00000914 66AB                    	stosw
  1710 00000916 B020                    	mov	al, ' '
  1711 00000918 66AB                    	stosw
  1712 0000091A B021                    	mov	al, '!'
  1713 0000091C 66AB                    	stosw
  1714 0000091E B020                    	mov	al, ' '
  1715 00000920 66AB                    	stosw
  1716                                  	; 23/02/2015
  1717 00000922 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1718 00000925 0F868D010000            	jna	iiret
  1719 0000092B B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1720 0000092D E6A0                    	out	0A0h, al ; the 2nd 8259
  1721 0000092F E984010000              	jmp     iiret
  1722                                  	;
  1723                                  	; 22/08/2014
  1724                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1725                                  	;out	20h, al	; 8259 PORT
  1726                                  	;
  1727                                  	;pop	es
  1728                                  	;pop	ds
  1729                                  	;pop	edi
  1730                                  	;pop	esi
  1731                                  	;pop	ebx
  1732                                  	;pop 	eax
  1733                                  	;iret
  1734                                  
  1735                                  	; 02/04/2015
  1736                                  	; 25/08/2014
  1737                                  exc0:
  1738 00000934 6A00                            push 	dword 0
  1739 00000936 E990000000                      jmp     cpu_except
  1740                                  exc1:
  1741 0000093B 6A01                            push 	dword 1
  1742 0000093D E989000000                      jmp     cpu_except
  1743                                  exc2:
  1744 00000942 6A02                            push 	dword 2
  1745 00000944 E982000000                      jmp     cpu_except
  1746                                  exc3:
  1747 00000949 6A03                            push 	dword 3
  1748 0000094B EB7E                            jmp     cpu_except
  1749                                  exc4:
  1750 0000094D 6A04                            push 	dword 4
  1751 0000094F EB7A                            jmp     cpu_except
  1752                                  exc5:
  1753 00000951 6A05                            push 	dword 5
  1754 00000953 EB76                            jmp     cpu_except
  1755                                  exc6:
  1756 00000955 6A06                            push 	dword 6
  1757 00000957 EB72                            jmp     cpu_except
  1758                                  exc7:
  1759 00000959 6A07                            push 	dword 7
  1760 0000095B EB6E                            jmp     cpu_except
  1761                                  exc8:
  1762                                  	; [esp] = Error code
  1763 0000095D 6A08                            push 	dword 8
  1764 0000095F EB5C                            jmp     cpu_except_en
  1765                                  exc9:
  1766 00000961 6A09                            push 	dword 9
  1767 00000963 EB66                            jmp     cpu_except
  1768                                  exc10:
  1769                                  	; [esp] = Error code
  1770 00000965 6A0A                            push 	dword 10
  1771 00000967 EB54                            jmp     cpu_except_en
  1772                                  exc11:
  1773                                  	; [esp] = Error code
  1774 00000969 6A0B                            push 	dword 11
  1775 0000096B EB50                            jmp     cpu_except_en
  1776                                  exc12:
  1777                                  	; [esp] = Error code
  1778 0000096D 6A0C                            push 	dword 12
  1779 0000096F EB4C                            jmp     cpu_except_en
  1780                                  exc13:
  1781                                  	; [esp] = Error code
  1782 00000971 6A0D                            push 	dword 13
  1783 00000973 EB48                            jmp     cpu_except_en
  1784                                  exc14:
  1785                                  	; [esp] = Error code
  1786 00000975 6A0E                            push 	dword 14
  1787 00000977 EB44                    	jmp	short cpu_except_en
  1788                                  exc15:
  1789 00000979 6A0F                            push 	dword 15
  1790 0000097B EB4E                            jmp     cpu_except
  1791                                  exc16:
  1792 0000097D 6A10                            push 	dword 16
  1793 0000097F EB4A                            jmp     cpu_except
  1794                                  exc17:
  1795                                  	; [esp] = Error code
  1796 00000981 6A11                            push 	dword 17
  1797 00000983 EB38                    	jmp	short cpu_except_en
  1798                                  exc18:
  1799 00000985 6A12                            push 	dword 18
  1800 00000987 EB42                    	jmp	short cpu_except
  1801                                  exc19:
  1802 00000989 6A13                            push 	dword 19
  1803 0000098B EB3E                    	jmp	short cpu_except
  1804                                  exc20:
  1805 0000098D 6A14                            push 	dword 20
  1806 0000098F EB3A                    	jmp	short cpu_except
  1807                                  exc21:
  1808 00000991 6A15                            push 	dword 21
  1809 00000993 EB36                    	jmp	short cpu_except
  1810                                  exc22:
  1811 00000995 6A16                            push 	dword 22
  1812 00000997 EB32                    	jmp	short cpu_except
  1813                                  exc23:
  1814 00000999 6A17                            push 	dword 23
  1815 0000099B EB2E                    	jmp	short cpu_except
  1816                                  exc24:
  1817 0000099D 6A18                            push 	dword 24
  1818 0000099F EB2A                    	jmp	short cpu_except
  1819                                  exc25:
  1820 000009A1 6A19                            push 	dword 25
  1821 000009A3 EB26                    	jmp	short cpu_except
  1822                                  exc26:
  1823 000009A5 6A1A                            push 	dword 26
  1824 000009A7 EB22                    	jmp	short cpu_except
  1825                                  exc27:
  1826 000009A9 6A1B                            push 	dword 27
  1827 000009AB EB1E                    	jmp	short cpu_except
  1828                                  exc28:
  1829 000009AD 6A1C                            push 	dword 28
  1830 000009AF EB1A                    	jmp	short cpu_except
  1831                                  exc29:
  1832 000009B1 6A1D                            push 	dword 29
  1833 000009B3 EB16                    	jmp	short cpu_except
  1834                                  exc30:
  1835 000009B5 6A1E                            push 	dword 30
  1836 000009B7 EB04                    	jmp	short cpu_except_en
  1837                                  exc31:
  1838 000009B9 6A1F                            push 	dword 31
  1839 000009BB EB0E                            jmp     short cpu_except
  1840                                  
  1841                                  	; 19/10/2015
  1842                                  	; 19/09/2015
  1843                                  	; 01/09/2015
  1844                                  	; 28/08/2015
  1845                                  	; 28/08/2014
  1846                                  cpu_except_en:
  1847 000009BD 87442404                	xchg	eax, [esp+4] ; Error code
  1848 000009C1 36A3[50810000]          	mov	[ss:error_code], eax
  1849 000009C7 58                      	pop	eax  ; Exception number
  1850 000009C8 870424                  	xchg	eax, [esp]
  1851                                  		; eax = eax before exception
  1852                                  		; [esp] -> exception number
  1853                                  		; [esp+4] -> EIP to return
  1854                                  	; 19/10/2015
  1855                                  	; 19/09/2015
  1856                                  	; 01/09/2015
  1857                                  	; 28/08/2015
  1858                                  	; 29/08/2014
  1859                                  	; 28/08/2014
  1860                                  	; 25/08/2014
  1861                                  	; 21/08/2014
  1862                                  cpu_except:	; CPU Exceptions
  1863 000009CB FC                      	cld
  1864 000009CC 870424                  	xchg	eax, [esp] 
  1865                                  		; eax = Exception number
  1866                                  		; [esp] = eax (before exception)	
  1867 000009CF 53                      	push	ebx
  1868 000009D0 56                      	push	esi
  1869 000009D1 57                      	push	edi
  1870 000009D2 1E                      	push 	ds
  1871 000009D3 06                      	push 	es
  1872                                  	; 28/08/2015
  1873 000009D4 66BB1000                	mov	bx, KDATA
  1874 000009D8 8EDB                    	mov	ds, bx
  1875 000009DA 8EC3                    	mov	es, bx
  1876 000009DC 0F20DB                  	mov	ebx, cr3
  1877 000009DF 53                      	push	ebx ; (*) page directory
  1878                                  	; 19/10/2015
  1879 000009E0 FC                      	cld
  1880                                  	; 25/03/2015
  1881 000009E1 8B1D[A8700000]          	mov	ebx, [k_page_dir]
  1882 000009E7 0F22DB                  	mov	cr3, ebx
  1883                                  	; 28/08/2015
  1884 000009EA 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1885 000009ED 7512                    	jne	short cpu_except_nfp
  1886 000009EF E815290000              	call	page_fault_handler
  1887 000009F4 21C0                    	and 	eax, eax
  1888 000009F6 0F84B8000000                    jz	iiretp ; 01/09/2015
  1889 000009FC B80E000000              	mov	eax, 0Eh ; 14
  1890                                  cpu_except_nfp:
  1891                                  	; 02/04/2015
  1892 00000A01 BB[23070000]            	mov	ebx, hang
  1893 00000A06 875C241C                	xchg	ebx, [esp+28]
  1894                                  		; EIP (points to instruction which faults)
  1895                                  	  	; New EIP (hang)
  1896 00000A0A 891D[54810000]          	mov	[FaultOffset], ebx
  1897 00000A10 C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1898 00000A18 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1899                                  	;
  1900 00000A20 88C4                    	mov	ah, al
  1901 00000A22 240F                    	and	al, 0Fh
  1902 00000A24 3C09                    	cmp	al, 9
  1903 00000A26 7602                    	jna	short h1ok
  1904 00000A28 0407                    	add	al, 'A'-':'
  1905                                  h1ok:
  1906 00000A2A D0EC                    	shr	ah, 1
  1907 00000A2C D0EC                    	shr	ah, 1
  1908 00000A2E D0EC                    	shr	ah, 1
  1909 00000A30 D0EC                    	shr	ah, 1
  1910 00000A32 80FC09                  	cmp	ah, 9
  1911 00000A35 7603                    	jna	short h2ok
  1912 00000A37 80C407                  	add	ah, 'A'-':'
  1913                                  h2ok:	
  1914 00000A3A 86E0                    	xchg 	ah, al	
  1915 00000A3C 66053030                	add	ax, '00'
  1916 00000A40 66A3[E66B0000]          	mov	[excnstr], ax
  1917                                  	;
  1918                                  	; 29/08/2014
  1919 00000A46 A1[54810000]            	mov	eax, [FaultOffset]
  1920 00000A4B 51                      	push	ecx
  1921 00000A4C 52                      	push	edx
  1922 00000A4D 89E3                    	mov	ebx, esp
  1923                                  	; 28/08/2015
  1924 00000A4F B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1925                                  			  ; to hexadecimal string
  1926                                  	;mov	ecx, 10	    ; divisor to convert	
  1927                                  			    ; binary number to decimal string
  1928                                  b2d1:
  1929 00000A54 31D2                    	xor	edx, edx
  1930 00000A56 F7F1                    	div	ecx
  1931 00000A58 6652                    	push	dx
  1932 00000A5A 39C8                    	cmp	eax, ecx
  1933 00000A5C 73F6                    	jnb	short b2d1
  1934 00000A5E BF[F16B0000]            	mov	edi, EIPstr ; EIP value
  1935                                  			    ; points to instruction which faults	
  1936                                  	; 28/08/2015
  1937 00000A63 89C2                    	mov	edx, eax
  1938                                  b2d2:
  1939                                  	;add	al, '0'
  1940 00000A65 8A82[31190000]          	mov	al, [edx+hexchrs]
  1941 00000A6B AA                      	stosb		    ; write hexadecimal digit to its place	
  1942 00000A6C 39E3                    	cmp	ebx, esp
  1943 00000A6E 7606                    	jna	short b2d3
  1944 00000A70 6658                    	pop	ax
  1945 00000A72 88C2                    	mov	dl, al
  1946 00000A74 EBEF                    	jmp	short b2d2
  1947                                  b2d3:
  1948 00000A76 B068                    	mov 	al, 'h' ; 28/08/2015
  1949 00000A78 AA                      	stosb
  1950 00000A79 B020                    	mov	al, 20h	    ; space
  1951 00000A7B AA                      	stosb
  1952 00000A7C 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  1953 00000A7E AA                      	stosb
  1954                                  	;
  1955 00000A7F 5A                      	pop	edx
  1956 00000A80 59                      	pop	ecx
  1957                                  	;
  1958 00000A81 B44F                    	mov	ah, 4Fh	; red (4) background, 
  1959                                  			; white (F) forecolor
  1960 00000A83 BE[D66B0000]            	mov	esi, exc_msg ; message offset
  1961                                  	;
  1962 00000A88 EB11                    	jmp	short piemsg
  1963                                  	;
  1964                                          ;add    dword [scr_row], 0A0h
  1965                                          ;mov    edi, [scr_row]
  1966                                          ;
  1967                                  	;call 	printk
  1968                                  	;
  1969                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1970                                  	;out	20h, al	; 8259 PORT
  1971                                  	;
  1972                                  	;pop	es
  1973                                  	;pop	ds
  1974                                  	;pop	edi
  1975                                  	;pop	esi
  1976                                  	;pop 	eax
  1977                                  	;iret
  1978                                  	
  1979                                  	; 28/08/2015
  1980                                  	; 23/02/2015
  1981                                  	; 20/08/2014
  1982                                  ignore_int:
  1983 00000A8A 50                      	push	eax
  1984 00000A8B 53                      	push	ebx ; 23/02/2015
  1985 00000A8C 56                      	push	esi
  1986 00000A8D 57                      	push	edi
  1987 00000A8E 1E                      	push 	ds
  1988 00000A8F 06                      	push 	es
  1989                                  	; 28/08/2015
  1990 00000A90 0F20D8                  	mov	eax, cr3
  1991 00000A93 50                      	push	eax ; (*) page directory
  1992                                  	;
  1993 00000A94 B467                    	mov	ah, 67h	; brown (6) background, 
  1994                                  			; light gray (7) forecolor
  1995 00000A96 BE[946B0000]            	mov	esi, int_msg ; message offset
  1996                                  piemsg:
  1997                                          ; 27/08/2014
  1998 00000A9B 8105[596B0000]A000-             add     dword [scr_row], 0A0h
  1999 00000AA3 0000               
  2000 00000AA5 8B3D[596B0000]                  mov     edi, [scr_row]
  2001                                          ;
  2002 00000AAB E8B0FCFFFF              	call 	printk
  2003                                  	;
  2004                                  	; 23/02/2015
  2005 00000AB0 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2006 00000AB2 E6A0                    	out	0A0h, al ; the 2nd 8259
  2007                                  iiretp: ; 01/09/2015
  2008                                  	; 28/08/2015
  2009 00000AB4 58                      	pop	eax ; (*) page directory
  2010 00000AB5 0F22D8                  	mov	cr3, eax
  2011                                  	;
  2012                                  iiret:
  2013                                  	; 22/08/2014
  2014 00000AB8 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2015 00000ABA E620                    	out	20h, al	; 8259 PORT
  2016                                  	;
  2017 00000ABC 07                      	pop	es
  2018 00000ABD 1F                      	pop	ds
  2019 00000ABE 5F                      	pop	edi
  2020 00000ABF 5E                      	pop	esi
  2021 00000AC0 5B                      	pop	ebx ; 29/08/2014
  2022 00000AC1 58                      	pop 	eax
  2023 00000AC2 CF                      	iretd
  2024                                  
  2025                                  	; 26/02/2015
  2026                                  	; 07/09/2014
  2027                                  	; 25/08/2014
  2028                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  2029                                  	; 22/08/2014
  2030 00000AC3 50                      	push	eax
  2031 00000AC4 53                      	push	ebx ; 29/08/2014
  2032 00000AC5 56                      	push	esi
  2033 00000AC6 57                      	push	edi
  2034 00000AC7 1E                      	push 	ds
  2035 00000AC8 06                      	push 	es
  2036                                  	;
  2037 00000AC9 B810000000              	mov	eax, KDATA
  2038 00000ACE 8ED8                    	mov	ds, ax
  2039 00000AD0 8EC0                    	mov	es, ax
  2040                                  	;
  2041                                  	; 25/08/2014
  2042 00000AD2 E884000000              	call	rtc_p
  2043                                  	;
  2044                                  	; 22/02/2015 - dsectpm.s
  2045                                  	; [ source: http://wiki.osdev.org/RTC ]
  2046                                  	; read status register C to complete procedure
  2047                                  	;(it is needed to get a next IRQ 8) 
  2048 00000AD7 B00C                    	mov	al, 0Ch ; 
  2049 00000AD9 E670                    	out	70h, al ; select register C
  2050 00000ADB 90                      	nop
  2051 00000ADC E471                    	in	al, 71h ; just throw away contents
  2052                                  	; 22/02/2015
  2053 00000ADE B020                    	MOV	AL,EOI		; END OF INTERRUPT
  2054 00000AE0 E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  2055                                  	;
  2056 00000AE2 EBD4                    	jmp	short iiret	
  2057                                  
  2058                                  	; 22/08/2014
  2059                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  2060                                  	; (INT 1Ah)
  2061                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  2062                                  time_of_day:
  2063 00000AE4 E866010000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  2064 00000AE9 726F                            jc      short rtc_retn 
  2065 00000AEB B000                    	mov	al, CMOS_SECONDS
  2066 00000AED E845010000              	call	CMOS_READ
  2067 00000AF2 A2[1C710000]            	mov	[time_seconds], al 
  2068 00000AF7 B002                    	mov	al, CMOS_MINUTES
  2069 00000AF9 E839010000              	call	CMOS_READ
  2070 00000AFE A2[1D710000]            	mov	[time_minutes], al 
  2071 00000B03 B004                    	mov	al, CMOS_HOURS
  2072 00000B05 E82D010000              	call	CMOS_READ
  2073 00000B0A A2[1E710000]                    mov     [time_hours], al
  2074 00000B0F B006                    	mov	al, CMOS_DAY_WEEK 
  2075 00000B11 E821010000              	call	CMOS_READ
  2076 00000B16 A2[1F710000]            	mov	[date_wday], al
  2077 00000B1B B007                     	mov	al, CMOS_DAY_MONTH
  2078 00000B1D E815010000              	call	CMOS_READ
  2079 00000B22 A2[20710000]            	mov	[date_day], al
  2080 00000B27 B008                    	mov	al, CMOS_MONTH
  2081 00000B29 E809010000              	call	CMOS_READ
  2082 00000B2E A2[21710000]            	mov	[date_month], al
  2083 00000B33 B009                    	mov	al, CMOS_YEAR
  2084 00000B35 E8FD000000              	call	CMOS_READ
  2085 00000B3A A2[22710000]            	mov	[date_year], al
  2086 00000B3F B032                    	mov	al, CMOS_CENTURY
  2087 00000B41 E8F1000000              	call	CMOS_READ
  2088 00000B46 A2[23710000]            	mov	[date_century], al
  2089                                  	;
  2090 00000B4B B000                    	mov	al, CMOS_SECONDS
  2091 00000B4D E8E5000000              	call 	CMOS_READ
  2092 00000B52 3A05[1C710000]          	cmp	al, [time_seconds]
  2093 00000B58 758A                    	jne	short time_of_day
  2094                                  
  2095                                  rtc_retn:
  2096 00000B5A C3                      	retn
  2097                                  
  2098                                  rtc_p:	
  2099                                  	; 07/09/2014
  2100                                  	; 29/08/2014
  2101                                  	; 27/08/2014
  2102                                  	; 25/08/2014
  2103                                   	; Print Real Time Clock content
  2104                                  	;
  2105                                  	;
  2106 00000B5B E884FFFFFF              	call	time_of_day
  2107 00000B60 72F8                    	jc	short rtc_retn
  2108                                  	;
  2109 00000B62 3A05[486C0000]          	cmp	al, [ptime_seconds]
  2110 00000B68 74F0                            je      short rtc_retn ; 29/08/2014
  2111                                  	;
  2112 00000B6A A2[486C0000]            	mov	[ptime_seconds], al
  2113                                  	;
  2114 00000B6F A0[23710000]            	mov	al, [date_century]
  2115 00000B74 E8F1000000              	call	bcd_to_ascii
  2116 00000B79 66A3[156C0000]          	mov	[datestr+6], ax
  2117 00000B7F A0[22710000]            	mov	al, [date_year]
  2118 00000B84 E8E1000000              	call	bcd_to_ascii
  2119 00000B89 66A3[176C0000]          	mov	[datestr+8], ax
  2120 00000B8F A0[21710000]            	mov	al, [date_month]
  2121 00000B94 E8D1000000              	call	bcd_to_ascii
  2122 00000B99 66A3[126C0000]          	mov	[datestr+3], ax
  2123 00000B9F A0[20710000]            	mov	al, [date_day]
  2124 00000BA4 E8C1000000              	call	bcd_to_ascii
  2125 00000BA9 66A3[0F6C0000]          	mov	[datestr], ax
  2126                                  	;
  2127 00000BAF 0FB61D[1F710000]        	movzx	ebx, byte [date_wday]
  2128 00000BB6 C0E302                  	shl 	bl, 2
  2129 00000BB9 81C3[286C0000]          	add	ebx, daytmp
  2130 00000BBF 8B03                    	mov	eax, [ebx]
  2131 00000BC1 A3[1A6C0000]            	mov	[daystr], eax
  2132                                  	;
  2133 00000BC6 A0[1E710000]            	mov	al, [time_hours]
  2134 00000BCB E89A000000              	call	bcd_to_ascii
  2135 00000BD0 66A3[1E6C0000]          	mov	[timestr], ax
  2136 00000BD6 A0[1D710000]            	mov	al, [time_minutes]
  2137 00000BDB E88A000000              	call	bcd_to_ascii
  2138 00000BE0 66A3[216C0000]          	mov	[timestr+3], ax
  2139 00000BE6 A0[1C710000]            	mov	al, [time_seconds]
  2140 00000BEB E87A000000              	call	bcd_to_ascii
  2141 00000BF0 66A3[246C0000]          	mov	[timestr+6], ax
  2142                                  	;		
  2143 00000BF6 BE[FD6B0000]            	mov	esi, rtc_msg ; message offset
  2144                                  	; 23/02/2015
  2145 00000BFB 52                      	push	edx
  2146 00000BFC 51                      	push	ecx
  2147                                  	; 07/09/2014
  2148 00000BFD 66BB0200                	mov	bx, 2		; Video page 2
  2149                                  prtmsg:
  2150 00000C01 AC                      	lodsb
  2151 00000C02 08C0                    	or	al, al
  2152 00000C04 740F                    	jz	short prtmsg_ok
  2153 00000C06 56                      	push	esi
  2154 00000C07 6653                    	push	bx
  2155 00000C09 B43F                            mov	ah, 3Fh	; cyan (6) background, 
  2156                                  			; white (F) forecolor
  2157 00000C0B E80D090000              	call 	write_tty
  2158 00000C10 665B                    	pop	bx
  2159 00000C12 5E                      	pop	esi
  2160 00000C13 EBEC                    	jmp	short prtmsg
  2161                                  	;
  2162                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  2163                                  	;call	printk
  2164                                  prtmsg_ok:
  2165                                  	; 07/09/2014
  2166 00000C15 6631D2                  	xor	dx, dx		; column 0, row 0
  2167 00000C18 E8240A0000              	call	set_cpos	; set curspor position to 0,0 
  2168                                  	; 23/02/2015
  2169 00000C1D 59                      	pop	ecx
  2170 00000C1E 5A                      	pop	edx
  2171 00000C1F C3                      	retn
  2172                                  
  2173                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2174                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2175                                  default_irq7:
  2176 00000C20 6650                    	push	ax
  2177 00000C22 B00B                    	mov	al, 0Bh  ; In-Service register
  2178 00000C24 E620                    	out	20h, al
  2179 00000C26 EB00                            jmp short $+2
  2180 00000C28 EB00                    	jmp short $+2
  2181 00000C2A E420                    	in	al, 20h
  2182 00000C2C 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  2183 00000C2E 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  2184 00000C30 B020                            mov     al, 20h ; EOI
  2185 00000C32 E620                    	out	20h, al 
  2186                                  irq7_iret:
  2187 00000C34 6658                    	pop	ax
  2188 00000C36 CF                      	iretd
  2189                                  	
  2190                                  	; 22/08/2014
  2191                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
  2192                                  CMOS_READ:
  2193 00000C37 9C                      	pushf		; SAVE INTERRUPT ENABLE STATUS AND FLAGS
  2194 00000C38 D0C0                    	rol	al, 1	; MOVE NMI BIT TO LOW POSITION
  2195 00000C3A F9                      	stc		; FORCE NMI BIT ON IN CARRY FLAG
  2196 00000C3B D0D8                    	rcr	al, 1	; HIGH BIT ON TO DISABLE NMI - OLD IN CY
  2197 00000C3D FA                      	cli		; DISABLE INTERRUPTS
  2198 00000C3E E670                    	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
  2199 00000C40 90                      	nop		; I/O DELAY
  2200 00000C41 E471                    	in	al, CMOS_DATA	; READ THE REQUESTED CMOS LOCATION
  2201 00000C43 6650                    	push	ax	; SAVE (AH) REGISTER VALUE AND CMOS BYTE
  2202                                  	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
  2203                                  		     ; ----- 10/06/85 (test4.asm)
  2204 00000C45 B01E                    	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
  2205                                  	;mov	al, CMOS_REG_D*2 ; GET ADDRESS OF DEFAULT LOCATION
  2206 00000C47 D0D8                    	rcr	al, 1	; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
  2207 00000C49 E670                    	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
  2208 00000C4B 6658                    	pop	ax	; RESTORE (AH) AND (AL), CMOS BYTE
  2209 00000C4D 9D                      	popf	
  2210 00000C4E C3                      	retn		; RETURN WITH FLAGS RESTORED
  2211                                  
  2212                                  	; 22/08/2014
  2213                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
  2214                                  UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
  2215 00000C4F 51                      	push	ecx
  2216 00000C50 B9FFFF0000              	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
  2217                                  		; mov cx, 800	
  2218                                  UPD_10:
  2219 00000C55 B00A                    	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
  2220 00000C57 FA                      	cli				; NO TIMER INTERRUPTS DURING UPDATES
  2221 00000C58 E8DAFFFFFF              	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
  2222 00000C5D A880                    	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
  2223 00000C5F 7406                    	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
  2224 00000C61 FB                      	sti				; ALLOW INTERRUPTS WHILE WAITING
  2225 00000C62 E2F1                    	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
  2226 00000C64 31C0                    	xor	eax, eax		; CLEAR RESULTS IF ERROR
  2227                                  		; xor ax, ax
  2228 00000C66 F9                      	stc				; SET CARRY FOR ERROR
  2229                                  UPD_90:
  2230 00000C67 59                      	pop	ecx			; RESTORE CALLERS REGISTER
  2231 00000C68 FA                      	cli				; INTERRUPTS OFF DURING SET
  2232 00000C69 C3                      	retn				; RETURN WITH CY FLAG SET
  2233                                  
  2234                                  bcd_to_ascii:
  2235                                  	; 25/08/2014
  2236                                  	; INPUT ->
  2237                                  	;	al = Packed BCD number
  2238                                  	; OUTPUT ->
  2239                                  	;	ax  = ASCII word/number
  2240                                  	;
  2241                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  2242                                  	;
  2243 00000C6A D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  2244                                  					; AH = AL / 10h
  2245                                  					; AL = AL MOD 10h
  2246 00000C6C 660D3030                	or ax,'00'                      ; Make it ASCII based
  2247                                  
  2248 00000C70 86E0                            xchg ah, al 
  2249                                  	
  2250 00000C72 C3                      	retn	
  2251                                  	
  2252                                  
  2253                                  %include 'keyboard.inc' ; 07/03/2015
  2254                              <1> ; Retro UNIX 386 v1 Kernel - KEYBOARD.INC
  2255                              <1> ; Last Modification: 17/10/2015
  2256                              <1> ;		    (Keyboard Data is in 'KYBDATA.INC')	
  2257                              <1> ;
  2258                              <1> ; ///////// KEYBOARD FUNCTIONS (PROCEDURES) ///////////////
  2259                              <1> 
  2260                              <1> ; 30/06/2015
  2261                              <1> ; 11/03/2015
  2262                              <1> ; 28/02/2015
  2263                              <1> ; 25/02/2015
  2264                              <1> ; 20/02/2015
  2265                              <1> ; 18/02/2015
  2266                              <1> ; 03/12/2014
  2267                              <1> ; 07/09/2014
  2268                              <1> ; KEYBOARD INTERRUPT HANDLER
  2269                              <1> ; (kb_int - Retro UNIX 8086 v1 - U0.ASM, 30/06/2014)
  2270                              <1> 
  2271                              <1> ;getch:
  2272                              <1> ;	; 18/02/2015
  2273                              <1> ;	; This routine will be replaced with Retro UNIX 386
  2274                              <1> ;	; version of Retro UNIX 8086 getch (tty input)
  2275                              <1> ;	; routine, later... (multi tasking ability)
  2276                              <1> ;	; 28/02/2015
  2277                              <1> ;	sti	; enable interrupts
  2278                              <1> ;	;
  2279                              <1> ;	;push	esi
  2280                              <1> ;	;push	ebx
  2281                              <1> ;	;xor	ebx, ebx
  2282                              <1> ;	;mov	bl, [ptty]  ; active_page
  2283                              <1> ;	;mov	esi, ebx
  2284                              <1> ;	;shl 	si, 1
  2285                              <1> ;	;add	esi, ttychr
  2286                              <1> ;getch_1:
  2287                              <1> ;	;mov	ax, [esi]
  2288                              <1> ;	mov	ax, [ttychr] ; video page 0 (tty0)
  2289                              <1> ;	and	ax, ax
  2290                              <1> ;	jz	short getch_2
  2291                              <1> ;	mov	word [ttychr], 0
  2292                              <1> ;	;mov	word [esi], 0
  2293                              <1> ;	;pop	ebx
  2294                              <1> ;	;pop	esi
  2295                              <1> ;	retn
  2296                              <1> ;getch_2:
  2297                              <1> ;	hlt	; not proper for multi tasking!
  2298                              <1> ;		; (temporary halt for now)
  2299                              <1> ;		; 'sleep' on tty 
  2300                              <1> ;		; will (must) be located here		
  2301                              <1> ;	nop
  2302                              <1> ;	jmp	short getch_1
  2303                              <1> 
  2304                              <1> keyb_int:
  2305                              <1> 	; 30/06/2015
  2306                              <1> 	; 25/02/2015
  2307                              <1> 	; 20/02/2015
  2308                              <1> 	; 03/12/2014 (getc_int - INT 16h modifications)
  2309                              <1> 	; 07/09/2014 - Retro UNIX 386 v1
  2310                              <1> 	; 30/06/2014
  2311                              <1> 	; 10/05/2013	
  2312                              <1>       	; Retro Unix 8086 v1 feature only!
  2313                              <1> 	; 03/03/2014
  2314                              <1> 	
  2315 00000C73 1E                  <1> 	push	ds
  2316 00000C74 53                  <1> 	push	ebx
  2317 00000C75 50                  <1> 	push	eax
  2318                              <1> 	;
  2319 00000C76 66B81000            <1> 	mov	ax, KDATA
  2320 00000C7A 8ED8                <1> 	mov	ds, ax
  2321                              <1> 	;
  2322 00000C7C 9C                  <1> 	pushfd
  2323 00000C7D 0E                  <1> 	push	cs
  2324 00000C7E E823020000          <1> 	call	kb_int  ; int_09h
  2325                              <1> 	;
  2326 00000C83 B411                <1> 	mov	ah, 11h	 ; 03/12/2014	
  2327                              <1> 	;call	getc
  2328 00000C85 E856000000          <1> 	call	int_16h ; 30/06/2015
  2329 00000C8A 7450                <1> 	jz	short keyb_int4
  2330                              <1> 	;
  2331 00000C8C B410                <1> 	mov	ah, 10h	 ; 03/12/2014
  2332                              <1> 	;call	getc
  2333 00000C8E E84D000000          <1> 	call	int_16h ; 30/06/2015
  2334                              <1> 	;
  2335                              <1> 	; 20/02/2015
  2336 00000C93 0FB61D[D6700000]    <1>         movzx   ebx, byte [ptty]  ; active_page
  2337                              <1> 	;
  2338 00000C9A 20C0                <1> 	and 	al, al
  2339 00000C9C 751E                <1> 	jnz	short keyb_int1
  2340                              <1> 	;
  2341 00000C9E 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  2342 00000CA1 7219                <1> 	jb	short keyb_int1
  2343 00000CA3 80FC6F              <1> 	cmp	ah, 6Fh  ; ALT + F8 key	
  2344 00000CA6 7714                <1> 	ja	short keyb_int1
  2345                              <1> 	;
  2346 00000CA8 88D8                <1> 	mov	al, bl
  2347 00000CAA 0468                <1> 	add	al, 68h
  2348 00000CAC 38E0                <1> 	cmp	al, ah
  2349 00000CAE 7409                <1> 	je	short keyb_int0
  2350 00000CB0 88E0                <1> 	mov	al, ah
  2351 00000CB2 2C68                <1> 	sub	al, 68h
  2352 00000CB4 E8510B0000          <1> 	call	tty_sw
  2353                              <1> 	;movzx	ebx, [ptty]  ; active_page
  2354                              <1> keyb_int0: ; 30/06/2015
  2355 00000CB9 6631C0              <1> 	xor	ax, ax
  2356                              <1> keyb_int1:
  2357 00000CBC D0E3                <1> 	shl	bl, 1
  2358 00000CBE 81C3[D8700000]      <1> 	add	ebx, ttychr
  2359                              <1> 	;
  2360 00000CC4 6609C0              <1> 	or	ax, ax
  2361 00000CC7 7406                <1> 	jz	short keyb_int2
  2362                              <1> 	;
  2363 00000CC9 66833B00            <1> 	cmp 	word [ebx], 0
  2364 00000CCD 7703                <1>         ja      short keyb_int3 
  2365                              <1> keyb_int2:
  2366 00000CCF 668903              <1>         mov	[ebx], ax  ; Save ascii code
  2367                              <1> 				; and scan code of the character
  2368                              <1> 				; for current tty (or last tty
  2369                              <1> 				; just before tty switch).
  2370                              <1> keyb_int3:
  2371 00000CD2 A0[D6700000]        <1>         mov     al, [ptty]
  2372 00000CD7 E81F480000          <1> 	call	wakeup
  2373                              <1> 	;
  2374                              <1> keyb_int4:
  2375 00000CDC 58                  <1> 	pop	eax
  2376 00000CDD 5B                  <1> 	pop	ebx
  2377 00000CDE 1F                  <1> 	pop	ds
  2378 00000CDF CF                  <1> 	iret
  2379                              <1> 
  2380                              <1> ; 18/02/2015
  2381                              <1> ; REMINDER: Only 'keyb_int' (IRQ 9) must call getc.
  2382                              <1> ; 'keyb_int' always handles 'getc' at 1st and puts the
  2383                              <1> ; scancode and ascii code of the character 
  2384                              <1> ; in the tty input (ttychr) buffer. 
  2385                              <1> ; Test procedures must call 'getch' for tty input
  2386                              <1> ; otherwise, 'getc' will not be able to return to the caller
  2387                              <1> ; due to infinite (key press) waiting loop.
  2388                              <1> ; 
  2389                              <1> ; 03/12/2014
  2390                              <1> ; 26/08/2014
  2391                              <1> ; KEYBOARD I/O
  2392                              <1> ; (INT_16h - Retro UNIX 8086 v1 - U9.ASM, 30/06/2014)
  2393                              <1> 
  2394                              <1> ;NOTE: 'k0' to 'k7' are name of OPMASK registers.
  2395                              <1> ;	(The reason of using '_k' labels!!!) (27/08/2014)    
  2396                              <1> ;NOTE: 'NOT' keyword is '~' unary operator in NASM.
  2397                              <1> ;	('NOT LC_HC' --> '~LC_HC') (bit reversing operator)
  2398                              <1> 
  2399                              <1> int_16h: ; 30/06/2015
  2400                              <1> ;getc:
  2401 00000CE0 9C                  <1> 	pushfd	; 28/08/2014
  2402 00000CE1 0E                  <1> 	push 	cs
  2403 00000CE2 E801000000          <1> 	call 	getc_int
  2404 00000CE7 C3                  <1> 	retn	
  2405                              <1> 
  2406                              <1> getc_int:
  2407                              <1> 	; 28/02/2015
  2408                              <1> 	; 03/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2409                              <1> 	;	      instead of pc-at bios - 1985-)
  2410                              <1> 	; 28/08/2014 (_k1d)
  2411                              <1> 	; 30/06/2014
  2412                              <1> 	; 03/03/2014
  2413                              <1> 	; 28/02/2014
  2414                              <1> 	; Derived from "KEYBOARD_IO_1" procedure of IBM "pc-xt-286" 
  2415                              <1> 	; rombios source code (21/04/1986)
  2416                              <1> 	;	 'keybd.asm', INT 16H, KEYBOARD_IO
  2417                              <1> 	;
  2418                              <1> 	; KYBD --- 03/06/86  KEYBOARD BIOS
  2419                              <1> 	;
  2420                              <1> 	;--- INT 16 H -----------------------------------------------------------------
  2421                              <1> 	; KEYBOARD I/O								      :
  2422                              <1> 	;	THESE ROUTINES PROVIDE READ KEYBOARD SUPPORT			      :
  2423                              <1> 	; INPUT									      :
  2424                              <1> 	;	(AH)= 00H  READ THE NEXT ASCII CHARACTER ENTERED FROM THE KEYBOARD,   :
  2425                              <1> 	;		   RETURN THE RESULT IN (AL), SCAN CODE IN (AH).              :
  2426                              <1> 	;		   THIS IS THE COMPATIBLE READ INTERFACE, EQUIVALENT TO THE   :
  2427                              <1> 	;                  STANDARD PC OR PCAT KEYBOARD				      :	
  2428                              <1> 	;-----------------------------------------------------------------------------:
  2429                              <1> 	;	(AH)= 01H  SET THE ZERO FLAG TO INDICATE IF AN ASCII CHARACTER IS     :
  2430                              <1> 	;		   AVAILABLE TO BE READ FROM THE KEYBOARD BUFFER.	      :
  2431                              <1> 	;		   (ZF)= 1 -- NO CODE AVAILABLE			              :
  2432                              <1> 	;		   (ZF)= 0 -- CODE IS AVAILABLE  (AX)= CHARACTER              :
  2433                              <1> 	;		   IF (ZF)= 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS :
  2434                              <1> 	;		   IN (AX), AND THE ENTRY REMAINS IN THE BUFFER.              :
  2435                              <1> 	;		   THIS WILL RETURN ONLY PC/PCAT KEYBOARD COMPATIBLE CODES    :
  2436                              <1> 	;-----------------------------------------------------------------------------:	
  2437                              <1> 	;	(AH)= 02H  RETURN THE CURRENT SHIFT STATUS IN AL REGISTER             :
  2438                              <1> 	;		   THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE        :
  2439                              <1> 	;		   EQUATES FOR @KB_FLAG		                              :
  2440                              <1> 	;-----------------------------------------------------------------------------:	
  2441                              <1> 	;	(AH)= 03H  SET TYPAMATIC RATE AND DELAY                               :
  2442                              <1> 	;	      (AL) = 05H                                                      :
  2443                              <1> 	;	      (BL) = TYPAMATIC RATE (BITS 5 - 7 MUST BE RESET TO 0)           :
  2444                              <1> 	;		       							      :
  2445                              <1> 	;                     REGISTER     RATE      REGISTER     RATE                :
  2446                              <1> 	;                      VALUE     SELECTED     VALUE     SELECTED              :
  2447                              <1> 	;                     --------------------------------------------            :
  2448                              <1> 	;			00H        30.0        10H        7.5                 :
  2449                              <1> 	;			01H        26.7        11H        6.7                 :
  2450                              <1> 	;			02H        24.0        12H        6.0                 :
  2451                              <1> 	;			03H        21.8        13H        5.5                 :
  2452                              <1> 	;			04H        20.0        14H        5.0                 :
  2453                              <1> 	;			05H        18.5        15H        4.6                 :
  2454                              <1> 	;			06H        17.1        16H        4.3                 :
  2455                              <1> 	;			07H        16.0        17H        4.0                 :
  2456                              <1> 	;			08H        15.0        18H        3.7                 :
  2457                              <1> 	;			09H        13.3        19H        3.3                 :
  2458                              <1> 	;			0AH        12.0        1AH        3.0                 :
  2459                              <1> 	;			0BH        10.9        1BH        2.7                 :
  2460                              <1>         ;			0CH        10.0        1CH        2.5                 :
  2461                              <1> 	;			0DH         9.2        1DH        2.3                 :
  2462                              <1> 	;			0EH         8.6        1EH        2.1                 :
  2463                              <1> 	;			0FH         8.0        1FH        2.0                 :
  2464                              <1> 	;									      :
  2465                              <1> 	;	      (BH) = TYPAMATIC DELAY  (BITS 2 - 7 MUST BE RESET TO 0)         :
  2466                              <1> 	;		       							      :
  2467                              <1> 	;                     REGISTER     DELAY                                      :
  2468                              <1> 	;                      VALUE       VALUE                                      :
  2469                              <1> 	;                     ------------------                                      :
  2470                              <1> 	;			00H        250 ms                                     :
  2471                              <1> 	;			01H        500 ms                                     :
  2472                              <1> 	;			02H        750 ms                                     :
  2473                              <1> 	;			03H       1000 ms                                     :
  2474                              <1> 	;-----------------------------------------------------------------------------:
  2475                              <1> 	;	(AH)= 05H  PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD    :
  2476                              <1> 	;		   BUFFER AS IF STRUCK FROM KEYBOARD                          :
  2477                              <1> 	;		   ENTRY:  (CL) = ASCII CHARACTER		              :
  2478                              <1> 	;		           (CH) = SCAN CODE                                   :
  2479                              <1> 	;		   EXIT:   (AH) = 00H = SUCCESSFUL OPERATION                  :
  2480                              <1> 	;		           (AL) = 01H = UNSUCCESSFUL - BUFFER FULL            :
  2481                              <1> 	;		   FLAGS:  CARRY IF ERROR                                     :
  2482                              <1> 	;-----------------------------------------------------------------------------:		
  2483                              <1> 	;	(AH)= 10H  EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD,         :
  2484                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=0                            :
  2485                              <1> 	;-----------------------------------------------------------------------------:
  2486                              <1> 	;	(AH)= 11H  EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,           :
  2487                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=1                            :
  2488                              <1> 	;-----------------------------------------------------------------------------:	
  2489                              <1> 	;	(AH)= 12H  RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER            :
  2490                              <1> 	;		   AL = BITS FROM KB_FLAG, AH = BITS FOR LEFT AND RIGHT       :
  2491                              <1> 	;		   CTL AND ALT KEYS FROM KB_FLAG_1 AND KB_FLAG_3              :
  2492                              <1> 	; OUTPUT					                              :
  2493                              <1> 	;	AS NOTED ABOVE, ONLY (AX) AND FLAGS CHANGED	                      :
  2494                              <1> 	;	ALL REGISTERS RETAINED		                                      :
  2495                              <1> 	;------------------------------------------------------------------------------
  2496                              <1> 	
  2497 00000CE8 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2498 00000CE9 1E                  <1> 	push	ds			; SAVE CURRENT DS
  2499 00000CEA 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
  2500                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
  2501 00000CEB 66BB1000            <1>         mov     bx, KDATA 
  2502 00000CEF 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
  2503 00000CF1 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
  2504 00000CF3 7439                <1> 	jz	short _K1		; ASCII_READ
  2505 00000CF5 FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
  2506 00000CF7 7452                <1>         jz      short _K2               ; ASCII_STATUS
  2507 00000CF9 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
  2508 00000CFB 0F8485000000        <1>         jz      _K3                     ; SHIFT STATUS
  2509 00000D01 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
  2510 00000D03 0F8484000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
  2511 00000D09 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
  2512 00000D0C 0F84A1000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
  2513                              <1> _KIO1:	
  2514 00000D12 80EC0B              <1> 	sub	ah, 11			; AH =  10H
  2515 00000D15 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
  2516 00000D17 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
  2517 00000D19 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
  2518 00000D1B FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
  2519 00000D1D 7449                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
  2520                              <1> _KIO_EXIT:
  2521                              <1> 	;pop	ecx			; RECOVER REGISTER
  2522 00000D1F 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2523 00000D20 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2524 00000D21 CF                  <1> 	iretd				; INVALID COMMAND, EXIT
  2525                              <1> 
  2526                              <1> 	;-----	ASCII CHARACTER
  2527                              <1> _K1E:	
  2528 00000D22 E8B9000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
  2529 00000D27 E82E010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2530 00000D2C EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
  2531                              <1> _K1:	
  2532 00000D2E E8AD000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
  2533 00000D33 E82D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2534 00000D38 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
  2535                              <1> _K1A:
  2536 00000D3A EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
  2537                              <1> 
  2538                              <1> 	;-----	ASCII STATUS
  2539                              <1> _K2E:	
  2540 00000D3C E8EA000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
  2541 00000D41 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2542 00000D43 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2543 00000D44 E811010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2544 00000D49 EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
  2545                              <1> _K2:	
  2546 00000D4B E8DB000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
  2547 00000D50 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2548 00000D52 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2549 00000D53 E80D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2550 00000D58 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
  2551 00000D5A 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
  2552 00000D5B E880000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
  2553 00000D60 EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
  2554                              <1> _K2A:
  2555 00000D62 9D                  <1> 	popf				; RESTORE ZF FROM TEST
  2556                              <1> _K2B:
  2557                              <1> 	;pop	ecx			; RECOVER REGISTER
  2558 00000D63 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2559 00000D64 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2560 00000D65 CA0400              <1> 	retf	4			; THROW AWAY (e)FLAGS
  2561                              <1> 
  2562                              <1> 	;-----	SHIFT STATUS
  2563                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
  2564 00000D68 8A25[946A0000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2565 00000D6E 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2566                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2567                              <1> 	;shl	ah, cl			; BIT 7 POSITION
  2568 00000D71 C0E405              <1>         shl	ah, 5
  2569 00000D74 A0[946A0000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2570 00000D79 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2571 00000D7B 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2572 00000D7D A0[966A0000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2573 00000D82 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2574 00000D84 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2575                              <1> _K3:
  2576 00000D86 A0[936A0000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2577 00000D8B EB92                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2578                              <1> 
  2579                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
  2580                              <1> _K300:
  2581 00000D8D 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
  2582 00000D8F 758E                <1> 	jne	short _KIO_EXIT		; NO, RETURN
  2583 00000D91 F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
  2584 00000D94 7589                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2585 00000D96 F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
  2586 00000D99 7584                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2587 00000D9B B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
  2588 00000D9D E8B6060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2589                              <1> 	;mov	cx, 5			; SHIFT COUNT
  2590                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
  2591 00000DA2 C0E705              <1> 	shl	bh, 5
  2592 00000DA5 88D8                <1> 	mov	al, bl			; PUT IN RATE
  2593 00000DA7 08F8                <1> 	or	al, bh			; AND DELAY
  2594 00000DA9 E8AA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2595 00000DAE E96CFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
  2596                              <1> 
  2597                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
  2598                              <1> _K500:
  2599 00000DB3 56                  <1> 	push	esi			; SAVE SI (esi)
  2600 00000DB4 FA                  <1> 	cli				; 
  2601 00000DB5 8B1D[A46A0000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
  2602 00000DBB 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
  2603 00000DBD E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
  2604 00000DC2 3B1D[A06A0000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
  2605 00000DC8 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
  2606 00000DCA 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
  2607 00000DCD 891D[A46A0000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
  2608 00000DD3 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
  2609 00000DD5 EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
  2610                              <1> _K502:
  2611 00000DD7 B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
  2612                              <1> _K504:
  2613 00000DD9 FB                  <1> 	sti				
  2614 00000DDA 5E                  <1> 	pop	esi			; RECOVER SI (esi)
  2615 00000DDB E93FFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
  2616                              <1> 
  2617                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
  2618                              <1> _K1S:
  2619 00000DE0 FA                  <1> 	cli	; 03/12/2014
  2620 00000DE1 8B1D[A06A0000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2621 00000DE7 3B1D[A46A0000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2622                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
  2623 00000DED 750F                <1> 	jne	short _k1x ; 03/12/2014
  2624                              <1> 	;
  2625                              <1> 	; 03/12/2014
  2626                              <1> 	; 28/08/2014
  2627                              <1> 	; PERFORM OTHER FUNCTION ?? here !
  2628                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
  2629                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
  2630                              <1> _K1T:                                   ; ASCII READ
  2631 00000DEF FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
  2632 00000DF0 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
  2633                              <1> _K1U:	
  2634 00000DF1 FA                  <1> 	cli				; INTERRUPTS BACK OFF
  2635 00000DF2 8B1D[A06A0000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2636 00000DF8 3B1D[A46A0000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2637                              <1> _k1x:
  2638 00000DFE 53                  <1> 	push	ebx			; SAVE ADDRESS		
  2639 00000DFF 9C                  <1> 	pushf				; SAVE FLAGS
  2640 00000E00 E80B070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2641 00000E05 8A1D[956A0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2642 00000E0B 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2643 00000E0D 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
  2644 00000E10 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
  2645 00000E12 E8A5060000          <1> 	call	SND_LED1
  2646 00000E17 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2647                              <1> _K1V:
  2648 00000E18 9D                  <1> 	popf				; RESTORE FLAGS
  2649 00000E19 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2650 00000E1A 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
  2651                              <1> 	;
  2652 00000E1C 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
  2653 00000E1F E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
  2654 00000E24 891D[A06A0000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
  2655 00000E2A C3                  <1> 	retn				; RETURN
  2656                              <1> 
  2657                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
  2658                              <1> _K2S:
  2659 00000E2B FA                  <1> 	cli				; INTERRUPTS OFF
  2660 00000E2C 8B1D[A06A0000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
  2661 00000E32 3B1D[A46A0000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
  2662 00000E38 668B03              <1> 	mov	ax, [ebx]
  2663 00000E3B 9C                  <1> 	pushf				; SAVE FLAGS
  2664 00000E3C 6650                <1> 	push	ax			; SAVE CODE
  2665 00000E3E E8CD060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2666 00000E43 8A1D[956A0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2667 00000E49 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2668 00000E4B 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
  2669 00000E4E 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
  2670 00000E50 E850060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2671                              <1> _K2T:
  2672 00000E55 6658                <1> 	pop	ax			; RESTORE CODE
  2673 00000E57 9D                  <1> 	popf				; RESTORE FLAGS
  2674 00000E58 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2675 00000E59 C3                  <1> 	retn				; RETURN
  2676                              <1> 
  2677                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
  2678                              <1> _KIO_E_XLAT:
  2679 00000E5A 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2680 00000E5C 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
  2681 00000E5E 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
  2682 00000E60 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
  2683 00000E62 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
  2684                              <1> _KIO_E_RET:				
  2685 00000E64 C3                  <1> 	retn				; GO BACK
  2686                              <1> 
  2687                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
  2688                              <1> _KIO_S_XLAT:
  2689 00000E65 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
  2690 00000E68 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
  2691 00000E6A 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
  2692 00000E6C 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
  2693 00000E6E 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
  2694 00000E70 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
  2695 00000E72 B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
  2696                              <1> _kio_ret: ; 03/12/2014
  2697 00000E74 F8                  <1> 	clc
  2698 00000E75 C3                  <1> 	retn
  2699                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2700                              <1> _KIO_S1:				
  2701 00000E76 B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
  2702                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2703 00000E78 C3                  <1> 	retn
  2704                              <1> _KIO_S2:		
  2705 00000E79 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
  2706 00000E7C 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
  2707 00000E7E 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2708 00000E80 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
  2709 00000E82 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2710 00000E84 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
  2711 00000E86 EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
  2712                              <1> _KIO_S3:
  2713 00000E88 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
  2714                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
  2715 00000E8A 75E8                <1> 	jne	short _kio_ret
  2716 00000E8C 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2717 00000E8E 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
  2718 00000E90 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
  2719                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
  2720                              <1> _KIO_USE:
  2721                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
  2722 00000E92 C3                  <1> 	retn				; RETURN	
  2723                              <1> _KIO_DIS:
  2724 00000E93 F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
  2725 00000E94 C3                  <1> 	retn				; RETURN
  2726                              <1> 
  2727                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
  2728                              <1> _K4:    
  2729 00000E95 43                  <1> 	inc     ebx
  2730 00000E96 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
  2731 00000E97 3B1D[9C6A0000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
  2732                              <1>         ;jne    short _K5               ; NO, CONTINUE
  2733 00000E9D 7206                <1> 	jb	short _K5
  2734 00000E9F 8B1D[986A0000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
  2735                              <1> _K5:
  2736 00000EA5 C3                  <1> 	retn
  2737                              <1> 
  2738                              <1> ; 20/02/2015
  2739                              <1> ; 05/12/2014
  2740                              <1> ; 26/08/2014
  2741                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
  2742                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
  2743                              <1> ;
  2744                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
  2745                              <1> ; rombios source code (06/10/1985)
  2746                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
  2747                              <1> 
  2748                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
  2749                              <1> ENA_KBD		equ	0AEh	; ENABLE KEYBOARD COMMAND
  2750                              <1> DIS_KBD		equ	0ADh	; DISABLE KEYBOARD COMMAND
  2751                              <1> SHUT_CMD	equ	0FEh	; CAUSE A SHUTDOWN COMMAND
  2752                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  2753                              <1> STATUS_PORT	equ	064h	; 8042 STATUS PORT
  2754                              <1> INPT_BUF_FULL	equ	00000010b ; 1 = +INPUT BUFFER FULL
  2755                              <1> PORT_A		equ	060h	; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  2756                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
  2757                              <1> KB_ACK		equ	0FAh	; ACKNOWLEDGE PROM TRANSMISSION
  2758                              <1> KB_RESEND	equ	0FEh	; RESEND REQUEST
  2759                              <1> KB_OVER_RUN	equ	0FFh	; OVER RUN SCAN CODE
  2760                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
  2761                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
  2762                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
  2763                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
  2764                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
  2765                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
  2766                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
  2767                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
  2768                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
  2769                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
  2770                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
  2771                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
  2772                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
  2773                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
  2774                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
  2775                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
  2776                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
  2777                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
  2778                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
  2779                              <1> F11_M		equ	87		; F11 KEY MAKE
  2780                              <1> F12_M		equ	88		; F12 KEY MAKE
  2781                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
  2782                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
  2783                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
  2784                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
  2785                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
  2786                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
  2787                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
  2788                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
  2789                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
  2790                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
  2791                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
  2792                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
  2793                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
  2794                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
  2795                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
  2796                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
  2797                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
  2798                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
  2799                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
  2800                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
  2801                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
  2802                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
  2803                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
  2804                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
  2805                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
  2806                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
  2807                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
  2808                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
  2809                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
  2810                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
  2811                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
  2812                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
  2813                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
  2814                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
  2815                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
  2816                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
  2817                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
  2818                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
  2819                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
  2820                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
  2821                              <1> ;
  2822                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
  2823                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
  2824                              <1> INTA00		equ	020h		; 8259 PORT
  2825                              <1> 
  2826                              <1> 
  2827                              <1> kb_int:
  2828                              <1> 
  2829                              <1> ; 17/10/2015 ('ctrlbrk') 
  2830                              <1> ; 05/12/2014
  2831                              <1> ; 04/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2832                              <1> 	;	      instead of pc-at bios - 1985-)
  2833                              <1> ; 26/08/2014
  2834                              <1> ;
  2835                              <1> ; 03/06/86  KEYBOARD BIOS
  2836                              <1> ;
  2837                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
  2838                              <1> ;										;
  2839                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
  2840                              <1> ;										;
  2841                              <1> ;--------------------------------------------------------------------------------
  2842                              <1> 
  2843                              <1> KB_INT_1:
  2844 00000EA6 FB                  <1> 	sti				; ENABLE INTERRUPTS
  2845                              <1> 	;push	ebp
  2846 00000EA7 50                  <1> 	push	eax
  2847 00000EA8 53                  <1> 	push	ebx
  2848 00000EA9 51                  <1> 	push	ecx
  2849 00000EAA 52                  <1> 	push	edx
  2850 00000EAB 56                  <1> 	push	esi
  2851 00000EAC 57                  <1> 	push	edi
  2852 00000EAD 1E                  <1> 	push	ds
  2853 00000EAE 06                  <1> 	push	es
  2854 00000EAF FC                  <1> 	cld				; FORWARD DIRECTION
  2855 00000EB0 66B81000            <1> 	mov	ax, KDATA
  2856 00000EB4 8ED8                <1> 	mov	ds, ax
  2857 00000EB6 8EC0                <1> 	mov	es, ax
  2858                              <1> 	;
  2859                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
  2860 00000EB8 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
  2861 00000EBA E885050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
  2862 00000EBF FA                  <1> 	cli				; DISABLE INTERRUPTS
  2863 00000EC0 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
  2864                              <1> KB_INT_01:
  2865 00000EC5 E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
  2866 00000EC7 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
  2867 00000EC9 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
  2868                              <1> 	;
  2869                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
  2870 00000ECB E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
  2871                              <1> 	;
  2872                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
  2873                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
  2874                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
  2875                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
  2876                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
  2877                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
  2878                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
  2879                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
  2880                              <1> 	;
  2881                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
  2882                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
  2883 00000ECD FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  2884 00000ECE 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
  2885 00000ED0 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
  2886                              <1> 	;
  2887                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
  2888 00000ED2 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
  2889 00000ED4 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
  2890                              <1> 	;
  2891                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
  2892 00000ED6 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2893 00000ED7 800D[956A0000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
  2894 00000EDE E97A020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
  2895                              <1> 	;
  2896                              <1> 	;-----	RESEND THE LAST BYTE
  2897                              <1> KB_INT_4:
  2898 00000EE3 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2899 00000EE4 800D[956A0000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
  2900 00000EEB E96D020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
  2901                              <1> 	;
  2902                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
  2903                              <1> KB_INT_2:
  2904 00000EF0 6650                <1> 	push 	ax			; SAVE DATA IN
  2905 00000EF2 E819060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2906 00000EF7 8A1D[956A0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2907 00000EFD 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2908 00000EFF 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
  2909 00000F02 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
  2910 00000F04 E89C050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2911                              <1> UP0:
  2912 00000F09 6658                <1> 	pop	ax			; RESTORE DATA IN
  2913                              <1> ;------------------------------------------------------------------------
  2914                              <1> ;	START OF KEY PROCESSING						;
  2915                              <1> ;------------------------------------------------------------------------
  2916 00000F0B 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
  2917                              <1> 	;
  2918                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
  2919 00000F0D 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
  2920 00000F0F 0F841B050000        <1>         je      K62			; BUFFER_FULL_BEEP
  2921                              <1> 	;
  2922                              <1> K16:	
  2923 00000F15 8A3D[966A0000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
  2924                              <1> 	;
  2925                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
  2926 00000F1B F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
  2927 00000F1E 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
  2928 00000F20 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
  2929 00000F22 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
  2930 00000F24 7507                <1> 	jne	short RST_RD_ID
  2931 00000F26 800D[966A0000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
  2932                              <1> RST_RD_ID:
  2933 00000F2D 8025[966A0000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
  2934                              <1>         ;jmp    short ID_EX		; AND EXIT
  2935 00000F34 E924020000          <1> 	jmp	K26
  2936                              <1> 	;
  2937                              <1> TST_ID_2:
  2938 00000F39 8025[966A0000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
  2939 00000F40 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
  2940 00000F42 7419                <1>         je	short KX_BIT		; JUMP IF SO
  2941 00000F44 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
  2942                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
  2943 00000F46 0F8511020000        <1> 	jne	K26
  2944                              <1> 	;
  2945                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
  2946 00000F4C F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
  2947 00000F4F 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
  2948 00000F51 800D[936A0000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
  2949 00000F58 E848050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
  2950                              <1> KX_BIT:
  2951 00000F5D 800D[966A0000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
  2952 00000F64 E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
  2953                              <1> 	;
  2954                              <1> NOT_ID:
  2955 00000F69 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
  2956 00000F6B 750C                <1> 	jne	short TEST_E1
  2957 00000F6D 800D[966A0000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
  2958                              <1> 	;jmp	short EXIT		; THROW AWAY THIS CODE
  2959 00000F74 E9EB010000          <1> 	jmp	K26A	
  2960                              <1> TEST_E1:	
  2961 00000F79 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
  2962 00000F7B 750C                <1> 	jne	short NOT_HC
  2963 00000F7D 800D[966A0000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
  2964 00000F84 E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
  2965                              <1> 	;
  2966                              <1> NOT_HC:
  2967 00000F89 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
  2968 00000F8B F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
  2969 00000F8E 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
  2970                              <1> 	;
  2971 00000F90 BF[7E690000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
  2972 00000F95 AE                  <1> 	scasb
  2973 00000F96 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
  2974 00000F9C AE                  <1> 	scasb
  2975 00000F9D 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
  2976                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
  2977 00000F9F E9B9010000          <1> 	jmp	K26
  2978                              <1> 	;
  2979                              <1> NOT_LC_E0:
  2980 00000FA4 F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
  2981 00000FA7 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
  2982 00000FA9 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
  2983 00000FAE BF[7C690000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
  2984 00000FB3 F2AE                <1> 	repne	scasb			; CHECK IT
  2985                              <1> 	;je	short EXIT		; THROW AWAY IF SO
  2986 00000FB5 0F84A9010000        <1> 	je	K26A			
  2987                              <1> 	;
  2988 00000FBB 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
  2989                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
  2990 00000FBD 0F859A010000        <1> 	jne	K26
  2991 00000FC3 F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
  2992                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
  2993 00000FC6 0F8591010000        <1> 	jnz	K26
  2994                              <1>         ; 20/02/2015 
  2995 00000FCC F605[946A0000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
  2996                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
  2997 00000FD3 0F8584010000        <1> 	jnz	K26
  2998 00000FD9 E9E1020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
  2999                              <1> 	;
  3000                              <1> 	;-----	TEST FOR SYSTEM KEY
  3001                              <1> T_SYS_KEY:
  3002 00000FDE 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
  3003 00000FE0 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
  3004                              <1> 	;
  3005 00000FE2 F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
  3006 00000FE5 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
  3007                              <1> 	;
  3008 00000FE7 F605[946A0000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
  3009                              <1>         ;jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
  3010 00000FEE 0F8569010000        <1> 	jnz     K26			
  3011                              <1> 	;
  3012 00000FF4 800D[946A0000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
  3013 00000FFB B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3014 00000FFD E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3015                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3016 00000FFF B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3017 00001001 E83E040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3018                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
  3019                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
  3020                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  3021                              <1> 	;INT	15H			; USER INTERRUPT	
  3022 00001006 E965010000          <1>         jmp     K27A                    ; END PROCESSING
  3023                              <1> 	;
  3024                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
  3025                              <1> 	;
  3026                              <1> K16C:
  3027 0000100B 8025[946A0000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
  3028 00001012 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3029 00001014 E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
  3030                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3031                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3032                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3033                              <1> 	;
  3034                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
  3035                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  3036                              <1> 	;INT	15H			; USER INTERRUPT
  3037                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
  3038                              <1> 	;
  3039 00001016 E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
  3040                              <1> 	;
  3041                              <1> 	;-----	TEST FOR SHIFT KEYS
  3042                              <1> K16A:
  3043 0000101B 8A1D[936A0000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
  3044 00001021 BF[78690000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
  3045 00001026 B908000000          <1> 	mov	ecx, _K6L		; LENGTH
  3046 0000102B F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
  3047 0000102D 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
  3048 0000102F 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
  3049                              <1> 	;
  3050                              <1> 	;------	SHIFT KEY FOUND
  3051                              <1> K17:
  3052 00001035 81EF[79690000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
  3053 0000103B 8AA7[80690000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
  3054 00001041 B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
  3055 00001043 A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
  3056 00001045 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
  3057                              <1> 	;
  3058                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
  3059                              <1> K17C:
  3060 0000104B 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
  3061 0000104E 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
  3062                              <1> 	;
  3063                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
  3064 00001050 0825[936A0000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
  3065 00001056 A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
  3066                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
  3067 00001058 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
  3068                              <1> K17D:
  3069 0000105E F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
  3070 00001061 740B                <1> 	jz 	short K17E		; NO, JUMP
  3071 00001063 0825[966A0000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
  3072 00001069 E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
  3073                              <1> K17E:
  3074 0000106E D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
  3075 00001070 0825[946A0000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
  3076 00001076 E9E2000000          <1> 	jmp	K26
  3077                              <1> 	;
  3078                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
  3079                              <1> K18:					; SHIFT-TOGGLE
  3080 0000107B F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
  3081                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
  3082 0000107E 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
  3083                              <1> K18A:
  3084 00001084 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
  3085 00001086 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
  3086 00001088 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
  3087                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
  3088 0000108B 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
  3089                              <1> K18B:
  3090 00001091 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
  3091 00001094 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
  3092                              <1> K19:	
  3093 00001096 F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
  3094 00001099 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
  3095 0000109B F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
  3096 0000109E 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
  3097                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
  3098 000010A0 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
  3099 000010A2 E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
  3100                              <1> K21:					; MIGHT BE NUMERIC
  3101 000010A7 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
  3102 000010AA 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
  3103                              <1> 	;
  3104                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
  3105 000010AC 8425[946A0000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
  3106 000010B2 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
  3107                              <1> K22A:
  3108 000010B8 0825[946A0000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
  3109 000010BE 3025[936A0000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
  3110                              <1> 	;
  3111                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
  3112 000010C4 F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
  3113 000010C7 7409                <1> 	jz	short K22B		; GO IF NOT
  3114                              <1> 	;
  3115 000010C9 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
  3116 000010CB E8D5030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
  3117 000010D0 6658                <1> 	pop	ax			; RESTORE SCAN CODE
  3118                              <1> K22B:
  3119 000010D2 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
  3120 000010D4 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
  3121 000010DA 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
  3122 000010DC E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
  3123                              <1> 	;
  3124                              <1> 	;-----	BREAK SHIFT FOUND
  3125                              <1> K23:					; BREAK-SHIFT-FOUND
  3126 000010E1 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
  3127 000010E4 F6D4                <1> 	not	ah			; INVERT MASK
  3128 000010E6 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
  3129 000010E8 2025[936A0000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
  3130 000010EE 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
  3131 000010F1 7730                <1> 	ja	short K23D		; NO, ALL DONE
  3132                              <1> 	;
  3133 000010F3 F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
  3134 000010F6 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
  3135 000010F8 2025[966A0000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
  3136 000010FE EB08                <1> 	jmp	short K23B		; CONTINUE
  3137                              <1> K23A:
  3138 00001100 D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
  3139 00001102 2025[946A0000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
  3140                              <1> K23B:
  3141 00001108 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
  3142 0000110A A0[966A0000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
  3143 0000110F D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
  3144 00001111 0A05[946A0000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
  3145 00001117 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
  3146 00001119 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
  3147 0000111B 0805[936A0000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
  3148 00001121 88E0                <1> 	mov	al, ah
  3149                              <1> K23D:
  3150 00001123 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
  3151 00001125 7536                <1> 	jne	short K26		; INTERRUPT RETURN
  3152                              <1> 	;	
  3153                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
  3154 00001127 A0[976A0000]        <1> 	mov	al, [ALT_INPUT]
  3155 0000112C B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
  3156 0000112E 8825[976A0000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
  3157 00001134 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
  3158 00001136 7425                <1> 	je	short K26		; INTERRUPT_RETURN
  3159 00001138 E9D0020000          <1>         jmp     K61                     ; IT WASN'T, SO PUT IN BUFFER
  3160                              <1> 	;
  3161                              <1> K24:					; BREAK-TOGGLE
  3162 0000113D 2025[946A0000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
  3163 00001143 EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
  3164                              <1> 	;
  3165                              <1> 	;-----	TEST FOR HOLD STATE
  3166                              <1> 					; AL, AH = SCAN CODE
  3167                              <1> K25:					; NO-SHIFT-FOUND
  3168 00001145 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
  3169 00001147 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
  3170 00001149 F605[946A0000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
  3171 00001150 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
  3172 00001152 3C45                <1> 	cmp	al, NUM_KEY
  3173 00001154 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
  3174 00001156 8025[946A0000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
  3175                              <1> 	;
  3176                              <1> K26:
  3177 0000115D 8025[966A0000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3178                              <1> K26A:					; INTERRUPT-RETURN
  3179 00001164 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3180 00001165 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3181 00001167 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3182                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
  3183 00001169 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3184 0000116B E8D4020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3185                              <1> K27A:
  3186 00001170 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3187 00001171 07                  <1> 	pop	es			; RESTORE REGISTERS
  3188 00001172 1F                  <1> 	pop	ds
  3189 00001173 5F                  <1> 	pop	edi
  3190 00001174 5E                  <1> 	pop	esi
  3191 00001175 5A                  <1> 	pop	edx
  3192 00001176 59                  <1> 	pop	ecx
  3193 00001177 5B                  <1> 	pop	ebx
  3194 00001178 58                  <1> 	pop	eax
  3195                              <1> 	;pop	ebp
  3196 00001179 CF                  <1> 	iret				; RETURN
  3197                              <1> 
  3198                              <1> 	;-----	NOT IN	HOLD STATE
  3199                              <1> K28:					; NO-HOLD-STATE
  3200 0000117A 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
  3201 0000117C 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
  3202                              <1> 	;
  3203 0000117E F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
  3204                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
  3205 00001181 0F84F1000000        <1>         jz      K38
  3206                              <1> 	;
  3207 00001187 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
  3208 0000118A 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  3209                              <1> 	 ;28/02/2015
  3210 0000118C F605[946A0000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
  3211                              <1> 	;jz	short K29		;  NO, ALT STATE IS REAL
  3212 00001193 0F85DF000000        <1> 	jnz	K38			; YES, THIS IS PHONY ALT STATE 
  3213                              <1>         ;				; DUE TO PRESSING SYSREQ	
  3214                              <1> ;K28A:	jmp	short K38
  3215                              <1> 	;
  3216                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
  3217                              <1> K29:					; TEST-RESET
  3218 00001199 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
  3219 0000119C 740B                <1> 	jz	short K31		; NO_RESET
  3220 0000119E 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
  3221 000011A0 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
  3222                              <1> 	;
  3223                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
  3224                              <1>  	; 26/08/2014
  3225                              <1> cpu_reset:
  3226                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
  3227                              <1> 	; Send FEh (system reset command) to the keyboard controller.
  3228 000011A2 B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
  3229 000011A4 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
  3230                              <1> khere:
  3231 000011A6 F4                  <1> 	hlt				; WAIT FOR 80286 RESET
  3232 000011A7 EBFD                <1> 	jmp 	short khere		; INSURE HALT
  3233                              <1> 
  3234                              <1> 	;
  3235                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
  3236                              <1> K31:					; NO-RESET
  3237 000011A9 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
  3238 000011AB 7507                <1> 	jne	short K311		; NOT THERE
  3239 000011AD B020                <1> 	mov	al, ' '			; SET SPACE CHAR
  3240 000011AF E948020000          <1>         jmp     K57                     ; BUFFER_FILL
  3241                              <1> K311:
  3242 000011B4 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
  3243 000011B6 7509                <1> 	jne	short K312		; NOT THERE
  3244 000011B8 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
  3245 000011BC E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
  3246                              <1> K312:
  3247 000011C1 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
  3248 000011C3 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
  3249 000011C9 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
  3250 000011CB 0F849A000000        <1>         je      K37B                    ; GO PROCESS
  3251                              <1> 	;
  3252                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
  3253                              <1> K32:					; ALT-KEY-PAD
  3254 000011D1 BF[54690000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
  3255 000011D6 B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
  3256 000011DB F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
  3257 000011DD 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
  3258 000011DF F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
  3259 000011E2 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
  3260 000011E8 81EF[55690000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
  3261 000011EE A0[976A0000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
  3262 000011F3 B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
  3263 000011F5 F6E4                <1> 	mul	ah
  3264 000011F7 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
  3265 000011FA A2[976A0000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
  3266                              <1> ;K32A:
  3267 000011FF E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
  3268                              <1> 	;
  3269                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
  3270                              <1> K33:					; NO-ALT-KEYPAD
  3271 00001204 C605[976A0000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
  3272 0000120B B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
  3273 00001210 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
  3274 00001212 7450                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
  3275                              <1> 	;
  3276                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
  3277                              <1> K34:					; ALT-TOP-ROW
  3278 00001214 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
  3279 00001216 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
  3280 00001218 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
  3281 0000121A 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
  3282 0000121C 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
  3283 0000121F EB43                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3284                              <1> 	;
  3285                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
  3286                              <1> K35:					; ALT-FUNCTION
  3287 00001221 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
  3288 00001223 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
  3289 00001225 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
  3290 00001227 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
  3291 00001229 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
  3292 0000122C EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3293                              <1> K35A:
  3294 0000122E F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
  3295 00001231 7422                <1> 	jz	short K37		; NO, JUMP
  3296 00001233 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
  3297 00001235 7509                <1>         jne     short K35B              ; NOT THERE
  3298 00001237 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
  3299 0000123B E9BC010000          <1> 	jmp	K57			; BUFFER FILL
  3300                              <1> K35B:
  3301 00001240 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
  3302 00001242 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
  3303 00001244 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
  3304                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
  3305 00001246 0F8511FFFFFF        <1>         jne     K26
  3306 0000124C 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
  3307 00001250 E9A7010000          <1> 	jmp	K57			; BUFFER FILL
  3308                              <1> K37:
  3309 00001255 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
  3310 00001257 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
  3311 00001259 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
  3312                              <1>         ;ja	short K32A		; IF SO, IGNORE
  3313 0000125B 0F87FCFEFFFF        <1>         ja      K26
  3314 00001261 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
  3315                              <1> K37A:
  3316 00001264 B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  3317 00001266 E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  3318                              <1> K37B:
  3319 0000126B B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  3320 0000126D E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  3321                              <1> K37C:
  3322 00001272 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  3323 00001274 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  3324 00001276 EBEC                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  3325                              <1> 	;
  3326                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  3327                              <1> K38:					; NOT-ALT-SHIFT
  3328                              <1> 					; BL STILL HAS SHIFT FLAGS
  3329 00001278 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  3330                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
  3331 0000127B 0F84B0000000        <1>         jz      K44                     ; NOT-CTL-SHIFT
  3332                              <1> 	;
  3333                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  3334                              <1> 	;-----	TEST FOR BREAK
  3335                              <1> K38A:
  3336 00001281 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  3337 00001283 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
  3338 00001285 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3339 00001288 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  3340 0000128A F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3341 0000128D 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  3342                              <1> K38B:
  3343 0000128F 8B1D[A06A0000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  3344 00001295 891D[A46A0000]      <1> 	mov	[BUFFER_TAIL], ebx
  3345 0000129B C605[926A0000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  3346                              <1> 	;
  3347                              <1> 	;-----	ENABLE KEYBOARD
  3348 000012A2 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3349 000012A4 E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3350                              <1> 	;
  3351                              <1> 	; CTRL+BREAK code here !!!
  3352                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  3353                              <1> 	; 17/10/2015	
  3354 000012A9 E89E260000          <1> 	call	ctrlbrk ; control+break subroutine
  3355                              <1> 	;
  3356 000012AE 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
  3357 000012B1 E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  3358                              <1> 	;
  3359                              <1> 	;-----	TEST FOR PAUSE
  3360                              <1> K39:					; NO_BREAK
  3361 000012B6 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3362 000012B9 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  3363 000012BB 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  3364 000012BD 7533                <1> 	jne	short K41		; NO-PAUSE
  3365                              <1> K39P:
  3366 000012BF 800D[946A0000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  3367                              <1> 	;
  3368                              <1> 	;-----	ENABLE KEYBOARD
  3369 000012C6 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3370 000012C8 E877010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3371                              <1> K39A:
  3372 000012CD B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  3373 000012CF E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  3374                              <1> 	;
  3375                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  3376 000012D1 803D[906A0000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  3377 000012D8 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  3378 000012DA 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  3379 000012DE A0[916A0000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  3380 000012E3 EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  3381                              <1> 	;
  3382                              <1> K40:					; PAUSE-LOOP
  3383 000012E4 F605[946A0000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  3384 000012EB 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  3385                              <1> 	;
  3386 000012ED E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  3387                              <1>         ;
  3388                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  3389                              <1> K41:					; NO-PAUSE
  3390 000012F2 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  3391 000012F4 7513                <1> 	jne	short K42		; NOT-KEY-55
  3392 000012F6 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3393 000012F9 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  3394 000012FB F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3395 000012FE 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  3396                              <1> K41A:	
  3397 00001300 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  3398 00001304 E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  3399                              <1> 	;
  3400                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  3401                              <1> K42:					; NOT-KEY-55
  3402 00001309 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  3403 0000130B 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  3404 0000130D 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  3405 0000130F 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  3406 00001311 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  3407 00001314 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  3408 00001316 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  3409 0000131A E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  3410                              <1> K42A: 
  3411                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3412 0000131F 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  3413                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  3414                              <1> 	;;jb	K56 ; 20/02/2015
  3415                              <1> 	;;jmp	K64 ; 20/02/2015
  3416                              <1> K42B:
  3417 00001321 BB[88690000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3418 00001326 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  3419 0000132C E9B9000000          <1> 	jmp	K64	
  3420                              <1>         ;
  3421                              <1> 	;-----	NOT IN CONTROL SHIFT
  3422                              <1> K44:					; NOT-CTL-SHIFT
  3423 00001331 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  3424 00001333 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  3425 00001335 F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  3426 00001338 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  3427 0000133A F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  3428 0000133D 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  3429 0000133F EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3430                              <1> K44A:
  3431 00001341 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  3432 00001344 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3433                              <1> 	;
  3434                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  3435                              <1> K44B:
  3436 00001346 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3437 00001348 E8F7000000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3438 0000134D B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  3439 0000134F E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  3440                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  3441                              <1> 	;PUSH 	BP			; SAVE POINTER
  3442                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  3443                              <1> 	;POP	BP			; RESTORE POINTER
  3444 00001351 8025[966A0000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  3445 00001358 E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  3446                              <1> 	;
  3447                              <1> 	;-----	HANDLE IN-CORE KEYS
  3448                              <1> K45:					; NOT-PRINT-SCREEN
  3449 0000135D 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  3450 0000135F 7734                <1> 	ja	short K46		; JUMP IF NOT
  3451 00001361 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  3452 00001363 7505                <1> 	jne	short K45A		; NO, JUMP
  3453 00001365 F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  3454 00001368 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  3455                              <1> K45A:
  3456 0000136A B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  3457 0000136F BF[5E690000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  3458 00001374 F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  3459                              <1> 		; 20/02/2015
  3460 00001376 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  3461                              <1> 	;
  3462 00001378 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  3463 0000137B 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  3464                              <1> K45B:
  3465 0000137D F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3466 00001380 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  3467                              <1> 					; NO, LOWERCASE
  3468                              <1> K45C:
  3469 00001382 BB[E0690000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  3470 00001387 EB51                <1> 	jmp	short K56	
  3471                              <1> K45D:					; ALMOST-CAPS-STATE
  3472 00001389 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  3473 0000138C 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  3474                              <1> K45E:
  3475 0000138E BB[386A0000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  3476 00001393 EB45                <1> K45F:	jmp	short K56
  3477                              <1> 	;
  3478                              <1> 	;-----	TEST FOR KEYS F1 - F10
  3479                              <1> K46:					; NOT IN-CORE AREA
  3480 00001395 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  3481                              <1> 	;ja	short K47		; JUMP IF NOT
  3482                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  3483 00001397 7635                <1> 	jna	short K53		
  3484                              <1> 	;
  3485                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  3486                              <1> K47:					; NOT F1 - F10
  3487 00001399 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  3488 0000139B 772D                <1> 	ja	short K52		; JUMP IF NOT
  3489                              <1> 	;
  3490                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  3491                              <1> K48:
  3492 0000139D 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  3493 0000139F 74ED                <1> 	je	short K45E		; GO TRANSLATE
  3494 000013A1 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  3495 000013A3 74E9                <1> 	je	short K45E		; GO TRANSLATE
  3496 000013A5 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  3497 000013A8 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  3498                              <1> 	;		
  3499 000013AA F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  3500 000013AD 7514                <1> 	jnz	short K50		; TEST FOR SURE
  3501 000013AF F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3502                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  3503 000013B2 75DA                <1> 	jnz	short K45E
  3504                              <1> 	;
  3505                              <1> 	;-----	BASE CASE FOR KEYPAD
  3506                              <1> K49:					
  3507 000013B4 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  3508 000013B6 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  3509 000013B8 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  3510 000013BA EB40                <1> 	jmp	short K57		; BUFFER FILL
  3511                              <1> K49A:
  3512 000013BC BB[E0690000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  3513 000013C1 EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  3514                              <1> 	;
  3515                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  3516                              <1> K50:					; ALMOST-NUM-STATE
  3517 000013C3 F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  3518 000013C6 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  3519 000013C8 EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  3520                              <1> 	;
  3521                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  3522                              <1> K52:					; NOT A NUMPAD KEY
  3523 000013CA 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  3524                              <1> 	;jne	short K53		; JUMP IF NOT
  3525                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  3526 000013CC 74AF                <1> 	je	short K45B		
  3527                              <1> 	;
  3528                              <1> 	;-----	MUST BE F11 OR F12 
  3529                              <1> K53:					; F1 - F10 COME HERE, TOO
  3530 000013CE F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  3531 000013D1 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  3532                              <1> 		; 20/02/2015 
  3533 000013D3 BB[386A0000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  3534 000013D8 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  3535                              <1> 	;
  3536                              <1> 	;-----	TRANSLATE THE CHARACTER
  3537                              <1> K56:					; TRANSLATE-CHAR
  3538 000013DA FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3539 000013DC D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  3540 000013DD F605[966A0000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3541 000013E4 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3542 000013E6 B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  3543 000013E8 EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  3544                              <1> 	;
  3545                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  3546                              <1> K64:					; TRANSLATE-SCAN-ORGD
  3547 000013EA FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3548 000013EC D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  3549 000013ED 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  3550 000013EF B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  3551 000013F1 F605[966A0000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3552 000013F8 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3553 000013FA B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  3554                              <1> 	;
  3555                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  3556                              <1> K57:					; BUFFER_FILL
  3557 000013FC 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  3558                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  3559 000013FE 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  3560 00001404 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  3561                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  3562 00001407 0F8450FDFFFF        <1> 	je      K26			; INTERRUPT_RETURN
  3563                              <1> ;K59:					; NEAR_INTERRUPT_RETURN
  3564                              <1> ;	jmp	K26			; INTERRUPT_RETURN
  3565                              <1> K61:					; NOT-CAPS-STATE
  3566 0000140D 8B1D[A46A0000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  3567 00001413 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  3568 00001415 E87BFAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  3569 0000141A 3B1D[A06A0000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  3570 00001420 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  3571 00001422 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  3572 00001425 891D[A46A0000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  3573 0000142B E92DFDFFFF          <1> 	jmp	K26
  3574                              <1> 	;;cli				; TURN OFF INTERRUPTS
  3575                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  3576                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  3577                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3578                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3579                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  3580                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  3581                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3582                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  3583                              <1> 	;;jmp   K27                    
  3584                              <1> 	;
  3585                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  3586                              <1> K62:
  3587 00001430 B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  3588 00001432 E620                <1> 	out	INTA00, al
  3589 00001434 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  3590 00001438 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  3591 0000143A E8A1010000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  3592 0000143F E925FDFFFF          <1> 	jmp     K27			; EXIT   
  3593                              <1> 
  3594                              <1> SHIP_IT:
  3595                              <1> 	;---------------------------------------------------------------------------------
  3596                              <1> 	; SHIP_IT
  3597                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3598                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  3599                              <1> 	;---------------------------------------------------------------------------------
  3600                              <1> 	;
  3601 00001444 6650                <1> 	push	ax			; SAVE DATA TO SEND
  3602                              <1> 
  3603                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  3604 00001446 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  3605                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  3606 00001447 B900000100          <1> 	mov	ecx, 10000h			
  3607                              <1> S10:
  3608 0000144C E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  3609 0000144E A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  3610 00001450 E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  3611                              <1> 
  3612 00001452 6658                <1> 	pop	ax			; GET DATA TO SEND
  3613 00001454 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  3614 00001456 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3615 00001457 C3                  <1> 	retn				; RETURN TO CALLER
  3616                              <1> 
  3617                              <1> SND_DATA:
  3618                              <1> 	; ---------------------------------------------------------------------------------
  3619                              <1> 	; SND_DATA
  3620                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3621                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  3622                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  3623                              <1> 	; ---------------------------------------------------------------------------------
  3624                              <1> 	;
  3625 00001458 6650                <1> 	push	ax			; SAVE REGISTERS
  3626 0000145A 6653                <1> 	push	bx
  3627 0000145C 51                  <1> 	push	ecx
  3628 0000145D 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  3629 0000145F B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  3630                              <1> SD0:
  3631 00001461 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3632 00001462 8025[956A0000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  3633                              <1> 	;
  3634                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  3635 00001469 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  3636                              <1> SD5:
  3637 0000146E E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  3638 00001470 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  3639 00001472 E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  3640                              <1> 	;
  3641 00001474 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  3642 00001476 E660                <1> 	out	PORT_A, al		; SEND BYTE
  3643 00001478 FB                  <1> 	sti				; ENABLE INTERRUPTS
  3644                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  3645 00001479 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  3646                              <1> SD1:
  3647 0000147E F605[956A0000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  3648 00001485 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  3649 00001487 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  3650                              <1> SD2:
  3651 00001489 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  3652 0000148B 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  3653 0000148D 800D[956A0000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  3654 00001494 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  3655                              <1> SD3:
  3656 00001496 F605[956A0000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  3657 0000149D 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  3658                              <1> SD4:	
  3659 0000149F 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  3660 000014A0 665B                <1> 	pop	bx
  3661 000014A2 6658                <1> 	pop	ax
  3662 000014A4 C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  3663                              <1> 
  3664                              <1> SND_LED:
  3665                              <1> 	; ---------------------------------------------------------------------------------
  3666                              <1> 	; SND_LED
  3667                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  3668                              <1> 	;
  3669                              <1> 	;----------------------------------------------------------------------------------
  3670                              <1> 	;
  3671 000014A5 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3672 000014A6 F605[956A0000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3673 000014AD 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3674                              <1> 	;
  3675 000014AF 800D[956A0000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3676 000014B6 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3677 000014B8 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3678 000014BA EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  3679                              <1> SND_LED1:
  3680 000014BC FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3681 000014BD F605[956A0000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3682 000014C4 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3683                              <1> 	;
  3684 000014C6 800D[956A0000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3685                              <1> SL0:
  3686 000014CD B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  3687 000014CF E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3688 000014D4 FA                  <1> 	cli
  3689 000014D5 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  3690 000014DA 8025[956A0000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  3691 000014E1 0805[956A0000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  3692 000014E7 F605[956A0000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3693 000014EE 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  3694                              <1> 	;
  3695 000014F0 E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3696 000014F5 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3697 000014F6 F605[956A0000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3698 000014FD 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  3699                              <1> SL2:
  3700 000014FF B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  3701 00001501 E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3702 00001506 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3703                              <1> SL3:
  3704 00001507 8025[956A0000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  3705                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  3706 0000150E FB                  <1> 	sti				; ENABLE INTERRUPTS
  3707 0000150F C3                  <1> 	retn				; RETURN TO CALLER
  3708                              <1> 
  3709                              <1> MAKE_LED:
  3710                              <1> 	;---------------------------------------------------------------------------------
  3711                              <1> 	; MAKE_LED
  3712                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  3713                              <1> 	;	THE MODE INDICATORS.
  3714                              <1> 	;---------------------------------------------------------------------------------
  3715                              <1> 	;
  3716                              <1> 	;push 	cx			; SAVE CX
  3717 00001510 A0[936A0000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  3718 00001515 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  3719                              <1> 	;mov	cl, 4			; SHIFT COUNT
  3720                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  3721 00001517 C0C004              <1> 	rol	al, 4 ; 20/02/2015
  3722 0000151A 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  3723                              <1> 	;pop	cx
  3724 0000151C C3                  <1> 	retn				; RETURN TO CALLER
  3725                              <1> 
  3726                              <1> ; % include 'kybdata.inc'   ; KEYBOARD DATA ; 11/03/2015
  3727                              <1> 
  3728                              <1> 
  3729                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  3730                                  
  3731                                  %include 'video.inc' ; 07/03/2015
  3732                              <1> ; Retro UNIX 386 v1 Kernel - VIDEO.INC
  3733                              <1> ; Last Modification: 13/08/2015
  3734                              <1> ;		  (Video Data is in 'VIDATA.INC')
  3735                              <1> ;
  3736                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
  3737                              <1> 
  3738                              <1> ; 30/06/2015
  3739                              <1> ; 27/06/2015
  3740                              <1> ; 11/03/2015
  3741                              <1> ; 02/09/2014
  3742                              <1> ; 30/08/2014
  3743                              <1> ; VIDEO FUNCTIONS
  3744                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  3745                              <1> 
  3746                              <1> write_tty:
  3747                              <1> 	; 13/08/2015
  3748                              <1> 	; 02/09/2014
  3749                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  3750                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  3751                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  3752                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  3753                              <1> 	;
  3754                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  3755                              <1> 	;	   AL = Character to be written
  3756                              <1> 	;	   EBX = Video Page (0 to 7)
  3757                              <1> 	;	   (BH = 0 --> Video Mode 3)
  3758                              <1> 
  3759                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  3760                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  3761                              <1> 
  3762                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  3763                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  3764                              <1> ;
  3765                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  3766                              <1> ;
  3767                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  3768                              <1> ;										:
  3769                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  3770                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  3771                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  3772                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  3773                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  3774                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  3775                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  3776                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  3777                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  3778                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  3779                              <1> ;   THE 0 COLOR IS USED.							:
  3780                              <1> ;   ENTRY --									:
  3781                              <1> ;     (AH) = CURRENT CRT MODE							:
  3782                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  3783                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  3784                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  3785                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  3786                              <1> ;   EXIT -- 									:
  3787                              <1> ;     ALL REGISTERS SAVED							:
  3788                              <1> ;--------------------------------------------------------------------------------
  3789                              <1> 
  3790 0000151D FA                  <1> 	cli
  3791                              <1> 	;
  3792                              <1> 	; READ CURSOR (04/12/2013)
  3793                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  3794 0000151E 08FF                <1> 	or	bh, bh
  3795 00001520 0F85AB000000        <1> 	jnz	beeper
  3796                              <1> 	; 01/09/2014
  3797 00001526 803D[906A0000]03    <1> 	cmp	byte [CRT_MODE], 3
  3798 0000152D 7405                <1> 	je	short m3
  3799                              <1> 	;
  3800 0000152F E889020000          <1> 	call	set_mode
  3801                              <1> m3:
  3802 00001534 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  3803 00001536 66D1E6              <1> 	shl	si, 1
  3804 00001539 81C6[C6700000]      <1> 	add	esi, cursor_posn
  3805 0000153F 668B16              <1> 	mov	dx, [esi]
  3806                              <1> 	;
  3807                              <1> 	; dx now has the current cursor position
  3808                              <1> 	;
  3809 00001542 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  3810 00001544 764D                <1> 	jbe	short u8
  3811                              <1> 	;
  3812                              <1> 	; write the char to the screen
  3813                              <1> u0:	
  3814                              <1> 	; ah = attribute/color
  3815                              <1> 	; al = character
  3816                              <1> 	; bl = video page number (0 to 7)
  3817                              <1> 	; bh = 0
  3818                              <1> 	;
  3819 00001546 E841020000          <1> 	call	write_c_current
  3820                              <1> 	;
  3821                              <1> 	; position the cursor for next char
  3822 0000154B FEC2                <1> 	inc	dl		; next column
  3823                              <1> 	;cmp	dl, [CRT_COLS]
  3824 0000154D 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  3825 00001550 0F85EB000000        <1>         jne     set_cpos
  3826 00001556 B200                <1> 	mov	dl, 0		; column = 0
  3827                              <1> u10:				; (line feed found)
  3828 00001558 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  3829 0000155B 722F                <1> 	jb 	short u6
  3830                              <1> 	;
  3831                              <1> 	; scroll required
  3832                              <1> u1:	
  3833                              <1> 	; SET CURSOR POSITION (04/12/2013)
  3834 0000155D E8DF000000          <1> 	call	set_cpos
  3835                              <1> 	;
  3836                              <1> 	; determine value to fill with during scroll
  3837                              <1> u2:
  3838                              <1> 	; READ_AC_CURRENT		:
  3839                              <1> 	;   THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER
  3840                              <1> 	;    AT THE CURRENT CURSOR POSITION
  3841                              <1> 	;
  3842                              <1> 	; INPUT				
  3843                              <1> 	;	(AH) = CURRENT CRT MODE
  3844                              <1> 	;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )
  3845                              <1> 	;	(DS) = DATA SEGMENT
  3846                              <1> 	;	(ES) = REGEN SEGMENT
  3847                              <1> 	; OUTPUT			
  3848                              <1> 	;	(AL) = CHARACTER READ
  3849                              <1> 	;	(AH) = ATTRIBUTE READ
  3850                              <1> 	;
  3851                              <1> 	; mov	ah, [CRT_MODE] ; move current mode into ah
  3852                              <1> 	;
  3853                              <1> 	; bl = video page number
  3854                              <1> 	;
  3855 00001562 E837010000          <1> 	call	find_position	; get regen location and port address
  3856                              <1> 	; dx = status port
  3857                              <1> 	; esi = cursor location/address
  3858                              <1> p11:
  3859 00001567 FB                  <1> 	sti			; enable interrupts
  3860 00001568 90                  <1> 	nop			; allow for small interupts window
  3861 00001569 FA                  <1> 	cli			; blocks interrupts for single loop
  3862 0000156A EC                  <1> 	in	al, dx		; get status from adapter
  3863 0000156B A801                <1> 	test	al, RHRZ	; is horizontal retrace low
  3864 0000156D 75F8                <1> 	jnz	short p11	; wait until it is
  3865                              <1> p12:				; now wait for either retrace high
  3866 0000156F EC                  <1> 	in	al, dx		; get status
  3867 00001570 A809                <1> 	test	al, RVRT+RHRZ	; is horizontal or vertical retrace high
  3868 00001572 74FB                <1> 	jz	short p12	; wait until either is active	
  3869                              <1> p13:
  3870 00001574 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
  3871 0000157A 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
  3872                              <1> 	;
  3873                              <1> 	; al = character, ah = attribute
  3874                              <1> 	;
  3875 0000157D FB                  <1> 	sti
  3876                              <1> 	; bl = video page number 	
  3877                              <1> u3:
  3878                              <1> 	;;mov	ax, 0601h 	; scroll one line
  3879                              <1> 	;;sub	cx, cx		; upper left corner
  3880                              <1> 	;;mov	dh, 25-1 	; lower right row
  3881                              <1> 	;;;mov	dl, [CRT_COLS]
  3882                              <1> 	;mov	dl, 80		; lower right column	
  3883                              <1> 	;;dec	dl
  3884                              <1> 	;;mov	dl, 79
  3885                              <1> 
  3886                              <1> 	;;call	scroll_up	; 04/12/2013
  3887                              <1> 	;;; 11/03/2015
  3888                              <1> 	; 02/09/2014
  3889                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  3890                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  3891                              <1> 	; 11/03/2015
  3892 0000157E 6629C9              <1> 	sub	cx, cx
  3893 00001581 66BA4F18            <1> 	mov	dx, 184Fh ; dl= 79 (column), dh = 24 (row)
  3894                              <1> 	;
  3895 00001585 B001                <1> 	mov	al, 1		; scroll 1 line up
  3896                              <1> 		; ah = attribute
  3897 00001587 E93E010000          <1> 	jmp	scroll_up
  3898                              <1> ;u4:
  3899                              <1> 	;;int	10h		; video-call return
  3900                              <1> 				; scroll up the screen
  3901                              <1> 				; tty return
  3902                              <1> ;u5:
  3903                              <1> 	;retn			; return to the caller
  3904                              <1> 
  3905                              <1> u6:				; set-cursor-inc
  3906 0000158C FEC6                <1> 	inc	dh		; next row
  3907                              <1> 				; set cursor
  3908                              <1> ;u7:					
  3909                              <1> 	;;mov	ah, 02h
  3910                              <1> 	;;jmp	short u4 	; establish the new cursor
  3911                              <1> 	;call	set_cpos
  3912                              <1> 	;jmp 	short u5
  3913 0000158E E9AE000000          <1> 	jmp     set_cpos
  3914                              <1> 
  3915                              <1> 	; check for control characters
  3916                              <1> u8:
  3917 00001593 7438                <1> 	je	short u9
  3918 00001595 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  3919 00001597 74BF                <1> 	je	short u10
  3920 00001599 3C07                <1> 	cmp	al, 07h 	; is it a bell
  3921 0000159B 7434                <1> 	je	short u11
  3922 0000159D 3C08                <1> 	cmp	al, 08h		; is it a backspace
  3923                              <1> 	;jne	short u0
  3924 0000159F 7424                <1> 	je	short bs	; 12/12/2013
  3925                              <1> 	; 12/12/2013 (tab stop)
  3926 000015A1 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  3927 000015A3 75A1                <1> 	jne	short u0
  3928 000015A5 88D0                <1> 	mov	al, dl
  3929 000015A7 6698                <1> 	cbw
  3930 000015A9 B108                <1> 	mov	cl, 8
  3931 000015AB F6F1                <1> 	div	cl
  3932 000015AD 28E1                <1> 	sub	cl, ah
  3933                              <1> ts:
  3934                              <1> 	; 02/09/2014
  3935                              <1> 	; 01/09/2014
  3936 000015AF B020                <1> 	mov	al, 20h
  3937                              <1> tsloop:
  3938 000015B1 6651                <1> 	push	cx
  3939 000015B3 6650                <1> 	push	ax
  3940 000015B5 30FF                <1> 	xor 	bh, bh
  3941                              <1> 	;mov	bl, [active_page]
  3942 000015B7 E878FFFFFF          <1> 	call	m3
  3943 000015BC 6658                <1> 	pop	ax  ; ah = attribute/color
  3944 000015BE 6659                <1> 	pop	cx
  3945 000015C0 FEC9                <1> 	dec	cl
  3946 000015C2 75ED                <1> 	jnz	short tsloop
  3947 000015C4 C3                  <1> 	retn
  3948                              <1> bs:	
  3949                              <1> 	; back space found
  3950                              <1> 
  3951 000015C5 08D2                <1> 	or	dl, dl 		; is it already at start of line
  3952                              <1> 	;je	short u7 	; set_cursor
  3953 000015C7 7478                <1> 	jz	short set_cpos
  3954 000015C9 664A                <1> 	dec	dx     		; no -- just move it back
  3955                              <1> 	;jmp	short u7
  3956 000015CB EB74                <1> 	jmp	short set_cpos
  3957                              <1> 
  3958                              <1> 	; carriage return found
  3959                              <1> u9:
  3960 000015CD B200                <1> 	mov	dl, 0 		; move to first column
  3961                              <1> 	;jmp	short u7
  3962 000015CF EB70                <1> 	jmp	short set_cpos
  3963                              <1> 
  3964                              <1> 	; line feed found
  3965                              <1> ;u10:
  3966                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  3967                              <1> ;	jne	short u6 	; no, just set the cursor
  3968                              <1> ;       jmp     u1              ; yes, scroll the screen
  3969                              <1> 
  3970                              <1> beeper: 
  3971                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  3972                              <1> 	; 18/01/2014
  3973                              <1> 	; 03/12/2013
  3974                              <1> 	; bell found
  3975                              <1> u11:
  3976 000015D1 FB                  <1> 	sti
  3977 000015D2 3A1D[D6700000]      <1> 	cmp	bl, [active_page]
  3978 000015D8 7551                <1> 	jne	short u12	; Do not sound the beep 
  3979                              <1> 				; if it is not written on the active page
  3980 000015DA 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  3981 000015DE B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  3982                              <1> 	;call	beep		; sound the pod bell
  3983                              <1> 	;jmp	short u5 	; tty_return
  3984                              <1> 	;retn
  3985                              <1> 	
  3986                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  3987                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  3988                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  3989                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  3990                              <1> 
  3991                              <1> beep:
  3992                              <1> 	; 07/02/2015
  3993                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  3994                              <1> 	; 18/01/2014
  3995                              <1> 	; 03/12/2013
  3996                              <1> 	;
  3997                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  3998                              <1> 	;
  3999                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  4000                              <1> 	;
  4001                              <1> 	; ENTRY:
  4002                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  4003                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  4004                              <1> 	; EXIT:				:
  4005                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  4006                              <1> 
  4007 000015E0 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  4008 000015E1 FA                  <1> 	cli			; block interrupts during update
  4009 000015E2 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  4010 000015E4 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  4011 000015E6 EB00                <1> 	jmp	$+2		; I/O delay
  4012 000015E8 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  4013 000015EA E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  4014 000015EC EB00                <1> 	jmp	$+2		; I/O delay
  4015 000015EE 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  4016 000015F0 E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  4017 000015F2 E461                <1> 	in	al, PORT_B	; get current setting of port
  4018 000015F4 88C4                <1> 	mov	ah, al		; save that setting
  4019 000015F6 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  4020 000015F8 E661                <1> 	out	PORT_B, al	; and restore interrupt status
  4021                              <1> 	;popf	; 18/01/2014
  4022 000015FA FB                  <1> 	sti
  4023                              <1> g7:				; 1/64 second per count (bl)
  4024 000015FB B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  4025 00001600 E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  4026 00001605 FECB                <1> 	dec	bl		; (bl) length count expired?
  4027 00001607 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  4028                              <1> 	;
  4029                              <1> 	;pushf			; save interrupt status
  4030 00001609 FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  4031 0000160A E461                <1> 	in	al, PORT_B	; get current port value
  4032                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  4033 0000160C 0CFC                <1>         or      al, ~(GATE2+SPK2)
  4034 0000160E 20C4                <1>         and	ah, al		; someone turned them off during beep
  4035 00001610 88E0                <1> 	mov	al, ah		; recover value of port
  4036                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  4037 00001612 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  4038 00001614 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  4039                              <1> 	;popf			; restore interrupt flag state
  4040 00001616 FB                  <1> 	sti
  4041 00001617 B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  4042 0000161C E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  4043                              <1> 	;pushf			; save interrupt status
  4044 00001621 FA                  <1> 	cli			; block interrupts during update
  4045 00001622 E461                <1> 	in	al, PORT_B	; get current port value in case	
  4046 00001624 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  4047 00001626 08E0                <1> 	or	al, ah		; recover value of port_b
  4048 00001628 E661                <1> 	out	PORT_B, al	; restore speaker status
  4049 0000162A 9D                  <1> 	popf			; restore interrupt flag state
  4050                              <1> u12:	
  4051 0000162B C3                  <1> 	retn
  4052                              <1> 
  4053                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  4054                              <1> 
  4055                              <1> WAITF:
  4056                              <1> waitf:
  4057                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4058                              <1> 	; 03/12/2013
  4059                              <1> 	;
  4060                              <1> ;	push ax			; save work register (ah)	
  4061                              <1> ;waitf1:
  4062                              <1> 				; use timer 1 output bits
  4063                              <1> ;	in	al, PORT_B	; read current counter output status
  4064                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  4065                              <1> ;	cmp	al, ah		; did it just change
  4066                              <1> ;	je	short waitf1	; wait for a change in output line
  4067                              <1> ;	;
  4068                              <1> ;	mov	ah, al		; save new lflag state
  4069                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  4070                              <1> ;	;
  4071                              <1> ;	pop	ax		; restore (ah)
  4072                              <1> ;	retn			; return (cx)=0
  4073                              <1> 
  4074                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  4075                              <1> ; 17/12/2014 (dsectrm2.s)
  4076                              <1> ; WAITF
  4077                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  4078                              <1> ;
  4079                              <1> ;---WAITF-----------------------------------------------------------------------
  4080                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  4081                              <1> ; ENTRY:
  4082                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  4083                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  4084                              <1> ; EXIT:
  4085                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  4086                              <1> ;	(CX) = 0	
  4087                              <1> ;-------------------------------------------------------------------------------
  4088                              <1> 
  4089                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  4090                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  4091                              <1> 
  4092                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  4093 0000162C 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  4094                              <1> 	; 16/12/2014
  4095                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  4096 0000162E D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  4097                              <1> ;17/12/2014	
  4098                              <1> ;WAITF1:
  4099                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  4100                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  4101                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  4102                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  4103                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  4104                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  4105                              <1> 	;
  4106                              <1> 	; 17/12/2014
  4107                              <1> 	;
  4108                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  4109                              <1> 	;
  4110                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  4111                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  4112                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  4113                              <1> WR_STATE_0:
  4114 00001630 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4115 00001632 A810                <1> 	TEST	AL,010H
  4116 00001634 74FA                <1> 	JZ	SHORT WR_STATE_0
  4117                              <1> WR_STATE_1:
  4118 00001636 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4119 00001638 A810                <1> 	TEST	AL,010H
  4120 0000163A 75FA                <1> 	JNZ	SHORT WR_STATE_1
  4121 0000163C E2F2                <1>         LOOP    WR_STATE_0
  4122                              <1> 	;
  4123 0000163E 6658                <1> 	POP	AX			; RESTORE (AH)
  4124 00001640 C3                  <1> 	RETn				; (CX) = 0
  4125                              <1> 
  4126                              <1> set_cpos:
  4127                              <1> 	; 27/06/2015
  4128                              <1> 	; 01/09/2014
  4129                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  4130                              <1> 	;
  4131                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  4132                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  4133                              <1> 	;
  4134                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4135                              <1> 	;
  4136                              <1> 	; SET_CPOS
  4137                              <1> 	;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  4138                              <1> 	;	NEW X-Y VALUES PASSED
  4139                              <1> 	; INPUT
  4140                              <1> 	;	DX - ROW,COLUMN OF NEW CURSOR
  4141                              <1> 	;	BH - DISPLAY PAGE OF CURSOR
  4142                              <1> 	; OUTPUT
  4143                              <1> 	;	CURSOR IS SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  4144                              <1> 	;
  4145 00001641 0FB6C3              <1>         movzx   eax, bl  ; BL = video page number ; 27/06/2015 (movzx)
  4146 00001644 D0E0                <1>         shl     al, 1   ; word offset
  4147 00001646 BE[C6700000]        <1> 	mov	esi, cursor_posn
  4148 0000164B 01C6                <1>         add     esi, eax
  4149 0000164D 668916              <1> 	mov	[esi], dx ; save the pointer
  4150 00001650 381D[D6700000]      <1> 	cmp	[active_page], bl
  4151 00001656 7532                <1> 	jne	short m17
  4152                              <1> 	;call	m18	; CURSOR SET
  4153                              <1> ;m17:			; SET_CPOS_RETURN
  4154                              <1> 	; 01/09/2014
  4155                              <1> ;	retn
  4156                              <1> 		; DX  = row/column
  4157                              <1> m18:
  4158 00001658 E832000000          <1> 	call	position ; determine location in regen buffer	
  4159 0000165D 668B0D[C4700000]    <1> 	mov	cx, [CRT_START]
  4160 00001664 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  4161                              <1> 			; to the start address (offset) for this page
  4162 00001667 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  4163 0000166A B40E                <1> 	mov	ah, 14	; register number for cursor
  4164                              <1> 	;call	m16	; output value to the 6845	
  4165                              <1> 	;retn
  4166                              <1> 
  4167                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  4168                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  4169                              <1> m16:
  4170 0000166C FA                  <1> 	cli
  4171                              <1> 	;mov	dx, [addr_6845] ; address register
  4172 0000166D 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  4173 00001671 88E0                <1> 	mov	al, ah	; get value
  4174 00001673 EE                  <1> 	out	dx, al	; register set
  4175 00001674 6642                <1> 	inc	dx	; data register
  4176 00001676 EB00                <1> 	jmp	$+2	; i/o delay
  4177 00001678 88E8                <1> 	mov	al, ch	; data
  4178 0000167A EE                  <1> 	out	dx, al	
  4179 0000167B 664A                <1> 	dec	dx	
  4180 0000167D 88E0                <1> 	mov	al, ah
  4181 0000167F FEC0                <1> 	inc	al	; point to other data register
  4182 00001681 EE                  <1> 	out	dx, al	; set for second register
  4183 00001682 6642                <1> 	inc	dx
  4184 00001684 EB00                <1> 	jmp	$+2	; i/o delay
  4185 00001686 88C8                <1> 	mov	al, cl	; second data value
  4186 00001688 EE                  <1> 	out	dx, al
  4187 00001689 FB                  <1> 	sti
  4188                              <1> m17:
  4189 0000168A C3                  <1> 	retn
  4190                              <1> 
  4191                              <1> 
  4192                              <1> set_ctype:
  4193                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4194                              <1> 	;
  4195                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4196                              <1> 
  4197                              <1> ;	CH) = BITS 4-0 = START LINE FOR CURSOR
  4198                              <1> ;       ** HARDWARE WILL ALWAYS CAUSE BLINK
  4199                              <1> ;       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
  4200                              <1> ;          OR NO CURSOR AT ALL
  4201                              <1> ;	(CL) = BITS 4-0 = END LINE FOR CURSOR
  4202                              <1> 
  4203                              <1> ;------------------------------------------------
  4204                              <1> ; SET_CTYPE
  4205                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
  4206                              <1> ; INPUT
  4207                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
  4208                              <1> ; OUTPUT	
  4209                              <1> ;	NONE
  4210                              <1> ;------------------------------------------------
  4211                              <1> 
  4212 0000168B B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  4213                              <1> 	;mov	[CURSOR_MODE], cx ; save in data area
  4214                              <1> 	;call	m16	; output cx register
  4215                              <1> 	;retn
  4216 0000168D EBDD                <1> 	jmp	m16
  4217                              <1> 
  4218                              <1> 
  4219                              <1> position:
  4220                              <1> 	; 27/06/2015
  4221                              <1> 	; 02/09/2014
  4222                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4223                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
  4224                              <1> 	;
  4225                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4226                              <1> 	;
  4227                              <1> 	; POSITION
  4228                              <1> 	;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
  4229                              <1> 	;	OF A CHARACTER IN THE ALPHA MODE
  4230                              <1> 	; INPUT
  4231                              <1> 	;	AX = ROW, COLUMN POSITION
  4232                              <1> 	; OUTPUT
  4233                              <1> 	;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
  4234                              <1> 
  4235                              <1> 		; DX = ROW, COLUMN POSITION
  4236                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
  4237 0000168F 31C0                <1> 	xor	eax, eax ; 02/09/2014
  4238 00001691 B050                <1> 	mov	al, 80   ; determine bytes to row	
  4239 00001693 F6E6                <1> 	mul	dh ;	 row value
  4240 00001695 30F6                <1> 	xor	dh, dh   ; 0	
  4241 00001697 6601D0              <1> 	add	ax, dx	 ; add column value to the result
  4242 0000169A 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
  4243                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
  4244 0000169D C3                  <1> 	retn
  4245                              <1> 
  4246                              <1> find_position:
  4247                              <1> 	; 27/06/2015
  4248                              <1> 	; 07/09/2014
  4249                              <1> 	; 02/09/2014
  4250                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4251                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4252 0000169E 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
  4253 000016A1 89CE                <1> 	mov	esi, ecx
  4254 000016A3 66D1E6              <1> 	shl	si, 1
  4255 000016A6 668B96[C6700000]    <1> 	mov	dx, [esi + cursor_posn]
  4256 000016AD 740A                <1> 	jz	short p21
  4257 000016AF 6631F6              <1> 	xor	si, si
  4258                              <1> p20:
  4259                              <1> 	;add	si, [CRT_LEN]
  4260 000016B2 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
  4261 000016B7 E2F9                <1> 	loop	p20
  4262                              <1> p21:
  4263 000016B9 6621D2              <1> 	and	dx, dx
  4264 000016BC 7407                <1> 	jz	short p22
  4265 000016BE E8CCFFFFFF          <1> 	call 	position ; determine location in regen in page
  4266 000016C3 01C6                <1> 	add	esi, eax ; add location to start of regen page
  4267                              <1> p22:	
  4268                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
  4269                              <1> 	;mov	dx, 03D4h ; I/O address of color card
  4270                              <1> 	;add	dx, 6	; point at status port
  4271 000016C5 66BADA03            <1> 	mov	dx, 03DAh ; status port
  4272                              <1> 	; cx = 0
  4273 000016C9 C3                  <1> 	retn
  4274                              <1> 
  4275                              <1> scroll_up:
  4276                              <1> 	; 07/09/2014
  4277                              <1> 	; 02/09/2014
  4278                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
  4279                              <1> 	; 04/04/2014
  4280                              <1> 	; 04/12/2013
  4281                              <1> 	;
  4282                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4283                              <1> 	;
  4284                              <1> 	; SCROLL UP
  4285                              <1> 	;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
  4286                              <1> 	;	ON THE SCREEN
  4287                              <1> 	; INPUT
  4288                              <1> 	;	(AH) = CURRENT CRT MODE
  4289                              <1> 	;	(AL) = NUMBER OF ROWS TO SCROLL
  4290                              <1> 	;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
  4291                              <1> 	;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
  4292                              <1> 	;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
  4293                              <1> 	;	(DS) = DATA SEGMENT
  4294                              <1> 	;	(ES) = REGEN BUFFER SEGMENT
  4295                              <1> 	; OUTPUT
  4296                              <1> 	;	NONE -- THE REGEN BUFFER IS MODIFIED
  4297                              <1> 	;
  4298                              <1> 	;	bh = 0  (02/09/2014)
  4299                              <1> 	;
  4300                              <1> 	; ((ah = 3))
  4301                              <1> 	; cl = left upper column
  4302                              <1> 	; ch = left upper row
  4303                              <1> 	; dl = right lower column
  4304                              <1> 	; dh = right lower row
  4305                              <1> 	;
  4306                              <1> 	; al = line count 
  4307                              <1> 	; ah = attribute to be used on blanked line	
  4308                              <1> 	; bl = video page number (0 to 7)
  4309                              <1> 	; 
  4310                              <1> 
  4311                              <1> 	; Test	Line Count
  4312 000016CA 08C0                <1> 	or	al, al
  4313 000016CC 740C                <1> 	jz	short al_set
  4314 000016CE 88F7                <1> 	mov	bh, dh	; subtract lower row from upper row
  4315 000016D0 28EF                <1> 	sub	bh, ch
  4316 000016D2 FEC7                <1> 	inc	bh	; adjust difference by 1
  4317 000016D4 38C7                <1> 	cmp	bh, al 	; line count = amount of rows in window?
  4318 000016D6 7502                <1> 	jne	short al_set ; if not the we're all set
  4319 000016D8 30C0                <1> 	xor	al, al	; otherwise set al to zero
  4320                              <1> al_set:
  4321 000016DA 30FF                <1> 	xor	bh, bh	; 0
  4322 000016DC 6650                <1> 	push	ax
  4323                              <1> 	;mov 	esi, [crt_base]
  4324 000016DE BE00800B00          <1>         mov     esi, 0B8000h  
  4325 000016E3 3A1D[D6700000]      <1>         cmp     bl, [active_page]
  4326 000016E9 750B                <1> 	jne	short n0
  4327                              <1> 	;
  4328 000016EB 66A1[C4700000]      <1>         mov     ax, [CRT_START]
  4329 000016F1 6601C6              <1>         add     si, ax
  4330 000016F4 EB0F                <1>         jmp     short n1
  4331                              <1> n0:
  4332 000016F6 20DB                <1>         and     bl, bl
  4333 000016F8 740B                <1> 	jz	short n1
  4334 000016FA 88D8                <1> 	mov	al, bl
  4335                              <1> n0x:
  4336                              <1>         ;add    si, [CRT_LEN]
  4337                              <1>         ;add    esi, 80*25*2 
  4338 000016FC 6681C6A00F          <1>         add     si, 80*25*2
  4339 00001701 FEC8                <1>         dec	al
  4340 00001703 75F7                <1> 	jnz	short n0x
  4341                              <1> n1:	
  4342                              <1>         ;Scroll position
  4343 00001705 6652                <1> 	push	dx
  4344 00001707 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
  4345 0000170A E880FFFFFF          <1> 	call	position
  4346 0000170F 01C6                <1> 	add	esi, eax
  4347 00001711 89F7                <1> 	mov	edi, esi
  4348 00001713 665A                <1> 	pop	dx	; lower right position in DX
  4349 00001715 6629CA              <1> 	sub	dx, cx
  4350 00001718 FEC6                <1> 	inc	dh	; dh = #rows 
  4351 0000171A FEC2                <1> 	inc	dl	; dl = #cols in block
  4352 0000171C 6658                <1> 	pop	ax	; al = line count, ah = attribute
  4353 0000171E 31C9                <1> 	xor	ecx, ecx
  4354 00001720 6689C1              <1> 	mov	cx, ax
  4355                              <1> 	;mov	ah, [CRT_COLS]
  4356 00001723 B450                <1> 	mov	ah, 80
  4357 00001725 F6E4                <1> 	mul	ah	; determine offset to from address
  4358 00001727 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
  4359                              <1> 	;
  4360 0000172A 6650                <1> 	push	ax	; offset 
  4361 0000172C 6652                <1> 	push	dx
  4362                              <1> 	;
  4363                              <1> 	; 04/04/2014
  4364 0000172E 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
  4365                              <1> n8:                      ; wait_display_enable
  4366 00001732 EC                  <1>         in      al, dx   ; get port
  4367 00001733 A808                <1> 	test	al, RVRT ; wait for vertical retrace	
  4368 00001735 74FB                <1> 	jz	short n8 ; wait_display_enable
  4369 00001737 B025                <1> 	mov	al, 25h
  4370 00001739 B2D8                <1> 	mov	dl, 0D8h ; address control port
  4371 0000173B EE                  <1> 	out	dx, al	; turn off video during vertical retrace
  4372 0000173C 665A                <1> 	pop	dx	; #rows, #cols
  4373 0000173E 6658                <1>        	pop	ax	; offset
  4374 00001740 6691                <1> 	xchg	ax, cx	; 
  4375                              <1> 	; ecx = offset, al = line count, ah = attribute
  4376                              <1> ;n9:
  4377 00001742 08C0                <1> 	or	al, al
  4378 00001744 7420                <1>         jz      short n3 
  4379 00001746 01CE                <1>         add     esi, ecx ; from address for scroll
  4380 00001748 88F7                <1> 	mov	bh, dh  ; #rows in block
  4381 0000174A 28C7                <1> 	sub	bh, al	; #rows to be moved
  4382                              <1> n2:
  4383                              <1> 	; Move rows
  4384 0000174C 88D1                <1> 	mov	cl, dl	; get # of cols to move
  4385 0000174E 56                  <1> 	push	esi
  4386 0000174F 57                  <1> 	push	edi	; save start address
  4387                              <1> n10:
  4388 00001750 66A5                <1> 	movsw		; move that line on screen
  4389 00001752 FEC9                <1> 	dec	cl
  4390 00001754 75FA                <1>         jnz     short n10
  4391 00001756 5F                  <1> 	pop	edi
  4392 00001757 5E                  <1> 	pop	esi	; recover addresses
  4393                              <1>         ;mov    cl, [CRT_COLS] 
  4394                              <1> 	;add	cl, cl
  4395                              <1>         ;mov    ecx, 80*2
  4396 00001758 66B9A000            <1>         mov     cx, 80*2
  4397 0000175C 01CE                <1>         add     esi, ecx  ; next line
  4398 0000175E 01CF                <1>         add     edi, ecx
  4399 00001760 FECF                <1> 	dec	bh	 ; count of lines to move
  4400 00001762 75E8                <1> 	jnz	short n2 ; row loop
  4401                              <1> 	; bh = 0
  4402 00001764 88C6                <1> 	mov	dh, al	 ; #rows	
  4403                              <1> n3:
  4404                              <1> 	; attribute in ah
  4405 00001766 B020                <1> 	mov	al, ' '	 ; fill with blanks
  4406                              <1> 	; Clear rows
  4407                              <1>                 ; dh =  #rows
  4408 00001768 88D1                <1>         mov	cl, dl	; get # of cols to clear
  4409 0000176A 57                  <1>         push    edi     ; save address
  4410                              <1> n11:
  4411 0000176B 66AB                <1>         stosw           ; store fill character
  4412 0000176D FEC9                <1> 	dec	cl
  4413 0000176F 75FA                <1>         jnz     short n11
  4414 00001771 5F                  <1>         pop     edi     ; recover address
  4415                              <1> 	;mov	cl, [CRT_COLS]
  4416                              <1> 	;add	cl, cl
  4417                              <1>         ;mov    ecx, 80*2
  4418 00001772 B1A0                <1>         mov	cl, 80*2
  4419 00001774 01CE                <1>         add     esi, ecx  ; next line
  4420 00001776 01CF                <1>         add     edi, ecx
  4421 00001778 FECE                <1> 	dec	dh
  4422 0000177A 75EA                <1> 	jnz	short n3
  4423                              <1> 	;
  4424 0000177C 3A1D[D6700000]      <1> 	cmp	bl, [active_page]
  4425 00001782 7507                <1> 	jne	short n6
  4426                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
  4427 00001784 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
  4428 00001786 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
  4429 0000178A EE                  <1> 	out	dx, al
  4430                              <1> n6:
  4431 0000178B C3                  <1> 	retn
  4432                              <1> 
  4433                              <1> 
  4434                              <1> write_c_current:
  4435                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4436                              <1> 	; 18/01/2014
  4437                              <1> 	; 04/12/2013
  4438                              <1> 	;
  4439                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4440                              <1> 	;
  4441                              <1> 	; WRITE_C_CURRENT
  4442                              <1> 	;	THIS ROUTINE WRITES THE CHARACTER AT
  4443                              <1> 	;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED
  4444                              <1> 	; INPUT	
  4445                              <1> 	;	(AH) = CURRENT CRT MODE
  4446                              <1> 	;	(BH) = DISPLAY PAGE
  4447                              <1> 	;	(CX) = COUNT OF CHARACTERS TO WRITE
  4448                              <1> 	;	(AL) = CHAR TO WRITE
  4449                              <1> 	;	(DS) = DATA SEGMENT
  4450                              <1> 	;	(ES) = REGEN SEGMENT
  4451                              <1> 	; OUTPUT
  4452                              <1> 	;	DISPLAY REGEN BUFFER UPDATED
  4453                              <1> 
  4454 0000178C FA                  <1> 	cli		
  4455                              <1> 	; bl = video page
  4456                              <1> 	; al = character
  4457                              <1> 	; ah = color/attribute
  4458 0000178D 6652                <1> 	push	dx
  4459 0000178F 6650                <1> 	push	ax	; save character & attribute/color
  4460 00001791 E808FFFFFF          <1> 	call 	find_position  ; get regen location and port address
  4461                              <1> 	; esi = regen location
  4462                              <1> 	; dx = status port
  4463                              <1> 	;
  4464                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  4465                              <1> 	;
  4466                              <1> p41:			; wait for horizontal retrace is low or vertical
  4467 00001796 FB                  <1> 	sti		; enable interrupts first
  4468 00001797 3A1D[D6700000]      <1>         cmp     bl, [active_page]
  4469 0000179D 7510                <1> 	jne	short p44 
  4470 0000179F FA                  <1> 	cli 		; block interrupts for single loop
  4471 000017A0 EC                  <1> 	in	al, dx	; get status from the adapter
  4472 000017A1 A808                <1> 	test	al, RVRT ; check for vertical retrace first
  4473 000017A3 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  4474 000017A5 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  4475 000017A7 75ED                <1> 	jnz	short p41 ; wait until it is
  4476                              <1> p42:			;  wait for either retrace high
  4477 000017A9 EC                  <1> 	in	al, dx ; get status again
  4478 000017AA A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  4479 000017AC 74FB                <1> 	jz	short p42 ; wait until either retrace active
  4480                              <1> p43:	
  4481 000017AE FB                  <1> 	sti
  4482                              <1> p44:
  4483 000017AF 6658                <1> 	pop	ax	; restore the character (al) & attribute (ah)
  4484 000017B1 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  4485                              <1> 				; Retro UNIX 386 v1 feature only!
  4486 000017B7 668906              <1> 	mov	[esi], ax
  4487 000017BA 665A                <1> 	pop	dx
  4488 000017BC C3                  <1> 	retn
  4489                              <1> 
  4490                              <1> set_mode:
  4491                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4492                              <1> 	;
  4493                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4494                              <1> 
  4495                              <1> ;------------------------------------------------------
  4496                              <1> ; SET MODE					      :
  4497                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
  4498                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
  4499                              <1> ; INPUT						      :
  4500                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
  4501                              <1> ; OUTPUT					      :
  4502                              <1> ;	NONE					      :
  4503                              <1> ;------------------------------------------------------
  4504                              <1> 
  4505 000017BD 53                  <1> 	push	ebx
  4506 000017BE 52                  <1> 	push	edx
  4507 000017BF 50                  <1>         push    eax
  4508                              <1> 
  4509                              <1> 	;mov	dx, 03D4h 	; address or color card
  4510 000017C0 B003                <1> 	mov	al, 3
  4511                              <1> ;M8:
  4512 000017C2 A2[906A0000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
  4513 000017C7 B029                <1> 	mov	al, 29h
  4514                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
  4515 000017C9 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
  4516                              <1> 	;push	dx  		; save port value
  4517                              <1> 	;add	dx, 4		; point to control register
  4518 000017CB 66BAD803            <1> 	mov	dx, 3D8h
  4519 000017CF EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
  4520                              <1> 	;pop	dx
  4521                              <1> ;M9:
  4522 000017D0 30E4                <1> 	xor	ah, ah
  4523 000017D2 BB[C86A0000]        <1> 	mov	ebx, video_params ; initialization table
  4524                              <1> 	;mov	ax, [ebx+10]      ; get the cursor mode from the table	
  4525                              <1> 	;xchg 	ah, al
  4526                              <1> 	;mov	[CURSOR_MODE], ax ; save cursor mode
  4527 000017D7 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
  4528                              <1> 	
  4529                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
  4530                              <1> 
  4531                              <1> M10:			;  initialization loop
  4532 000017D9 88E0                <1> 	mov	al, ah 	; get 6845 register number
  4533 000017DB EE                  <1> 	out	dx, al
  4534 000017DC 6642                <1> 	inc	dx      ; point to data port
  4535 000017DE FEC4                <1> 	inc	ah	; next register value
  4536 000017E0 8A03                <1> 	mov	al, [ebx] ; get table value
  4537 000017E2 EE                  <1> 	out	dx, al	; out to chip
  4538 000017E3 43                  <1> 	inc	ebx	; next in table
  4539 000017E4 664A                <1> 	dec	dx	; back to pointer register
  4540 000017E6 E2F1                <1> 	loop	M10	; do the whole table
  4541                              <1> 
  4542                              <1> ;-----	FILL REGEN AREA WITH BLANK
  4543                              <1> 	;xor	ax, ax  
  4544                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
  4545                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
  4546                              <1> 	;mov	ecx, 8192 ; number of words in color card
  4547                              <1> 	; black background, light gray characeter color, space character
  4548                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
  4549                              <1> ;M13:			  ; clear buffer
  4550                              <1> 	;add	edi, 0B8000h ; [crt_base]
  4551                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
  4552                              <1> 
  4553                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
  4554                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
  4555                              <1> 			 ; prepare to output to video enable port
  4556                              <1> 	;add	dx,4	 ; point to the mode control gerister
  4557 000017E8 66BAD803            <1> 	mov	dx, 3D8h
  4558                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
  4559 000017EC B029                <1> 	mov	al, 29h
  4560 000017EE EE                  <1> 	out	dx, al	 ; set video enable port
  4561                              <1> 
  4562                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
  4563                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
  4564                              <1> 	;
  4565                              <1> 	;mov byte [CRT_COLS], 80h ; initialize number of columns count
  4566                              <1> 	;
  4567                              <1> ;-----	SET CURSOR POSITIONS
  4568 000017EF 57                  <1> 	push	edi
  4569                              <1> 	;mov	word [CRT_LEN], 80*25*2
  4570 000017F0 51                  <1> 	push	ecx
  4571 000017F1 BF[C6700000]        <1> 	mov	edi, cursor_posn
  4572 000017F6 B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
  4573 000017FB 31C0                <1> 	xor	eax, eax
  4574 000017FD F3AB                <1> 	rep 	stosd	; fill with zeroes
  4575 000017FF 59                  <1> 	pop	ecx
  4576 00001800 5F                  <1> 	pop	edi
  4577                              <1> 
  4578                              <1> ;-----	SET UP OVERSCAN REGISTER
  4579 00001801 6642                <1> 	inc	dx	; set overscan port to a default
  4580 00001803 B030                <1> 	mov	al, 30h	; 30H valuye for all modes except 640X200 bw
  4581                              <1> ;M14:
  4582 00001805 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
  4583                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
  4584                              <1> 
  4585                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  4586                              <1> 	;
  4587 00001806 58                  <1> 	pop	eax
  4588 00001807 5A                  <1> 	pop	edx
  4589 00001808 5B                  <1> 	pop	ebx
  4590 00001809 C3                  <1> 	retn
  4591                              <1> 	
  4592                              <1> tty_sw:
  4593                              <1> 	; 30/06/2015
  4594                              <1> 	; 27/06/2015 
  4595                              <1> 	; 07/09/2014
  4596                              <1> 	; 02/09/2014 (Retro UNIX 386 v1 - beginning)
  4597                              <1> 	;
  4598                              <1> 	; (Modified registers : EAX)
  4599                              <1> 	;
  4600                              <1>         ;mov     byte [u.quant], 0  ; 04/03/2014
  4601                              <1> 	;
  4602                              <1> ;act_disp_page:
  4603                              <1> 	; 30/06/2015
  4604                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
  4605                              <1> 	; 10/12/2013
  4606                              <1> 	; 04/12/2013
  4607                              <1> 	;
  4608                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4609                              <1> 	;
  4610                              <1> 	; ACT_DISP_PAGE
  4611                              <1> 	;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
  4612                              <1> 	;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
  4613                              <1> 	; INPUT
  4614                              <1> 	;	AL HAS THE NEW ACTIVE DISPLAY PAGE
  4615                              <1> 	; OUTPUT
  4616                              <1> 	;	THE 6845 IS RESET TO DISPLAY THAT PAGE
  4617                              <1> 
  4618                              <1> 	;cli
  4619                              <1> 
  4620 0000180A 53                  <1> 	push	ebx
  4621 0000180B 6651                <1> 	push	cx
  4622 0000180D 6652                <1> 	push	dx
  4623                              <1> 	;
  4624 0000180F A2[D6700000]        <1> 	mov	[active_page], al ; save active page value ; [ptty]
  4625                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
  4626 00001814 66B9A00F            <1> 	mov	cx, 25*80*2
  4627                              <1> 	; 27/06/2015
  4628 00001818 0FB6D8              <1> 	movzx	ebx, al
  4629                              <1> 	;
  4630 0000181B 6698                <1> 	cbw	; 07/09/2014 (ah=0)
  4631 0000181D 66F7E1              <1> 	mul 	cx	; display page times regen length
  4632                              <1> 	; 10/12/2013
  4633 00001820 66A3[C4700000]      <1> 	mov	[CRT_START], ax ; save start address for later
  4634 00001826 6689C1              <1> 	mov	cx, ax ; start address to cx
  4635                              <1> 	;sar	cx, 1
  4636 00001829 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
  4637 0000182C B40C                <1> 	mov	ah, 12	; 6845 register for start address
  4638 0000182E E839FEFFFF          <1> 	call	m16
  4639                              <1> 	;sal	bx, 1
  4640                              <1> 	; 01/09/2014
  4641 00001833 D0E3                <1> 	shl	bl, 1	; *2 for word offset
  4642 00001835 81C3[C6700000]      <1> 	add	ebx, cursor_posn
  4643 0000183B 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
  4644 0000183E E815FEFFFF          <1> 	call	m18
  4645                              <1> 	;
  4646 00001843 665A                <1> 	pop	dx
  4647 00001845 6659                <1> 	pop	cx
  4648 00001847 5B                  <1> 	pop	ebx
  4649                              <1> 	;
  4650                              <1> 	;sti
  4651                              <1> 	;
  4652 00001848 C3                  <1> 	retn
  4653                              <1> 
  4654                              <1> ; % include 'vidata.inc' ; VIDEO DATA ; 11/03/2015
  4655                              <1> 
  4656                              <1> 
  4657                              <1> ; /// End Of VIDEO FUNCTIONS ///
  4658                                  
  4659                                  setup_rtc_int:
  4660                                  ; source: http://wiki.osdev.org/RTC
  4661 00001849 FA                      	cli		; disable interrupts
  4662                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  4663                                  	; in order to change this ...
  4664                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  4665                                  	; (rate must be above 2 and not over 15)
  4666                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  4667 0000184A B08A                    	mov	al, 8Ah 
  4668 0000184C E670                    	out	70h, al ; set index to register A, disable NMI
  4669 0000184E 90                      	nop
  4670 0000184F E471                    	in	al, 71h ; get initial value of register A
  4671 00001851 88C4                    	mov 	ah, al
  4672 00001853 80E4F0                  	and	ah, 0F0h
  4673 00001856 B08A                    	mov	al, 8Ah 
  4674 00001858 E670                    	out	70h, al ; reset index to register A
  4675 0000185A 88E0                    	mov	al, ah
  4676 0000185C 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  4677 0000185E E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  4678                                  	; enable RTC interrupt
  4679 00001860 B08B                    	mov	al, 8Bh ;
  4680 00001862 E670                    	out	70h, al ; select register B and disable NMI
  4681 00001864 90                      	nop
  4682 00001865 E471                    	in	al, 71h ; read the current value of register B
  4683 00001867 88C4                    	mov	ah, al  ;
  4684 00001869 B08B                    	mov 	al, 8Bh ;
  4685 0000186B E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  4686 0000186D 88E0                    	mov	al, ah  ;
  4687 0000186F 0C40                    	or	al, 40h ;
  4688 00001871 E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  4689 00001873 FB                      	sti
  4690 00001874 C3                      	retn
  4691                                  
  4692                                  ; Write memory information
  4693                                  ; Temporary Code
  4694                                  ; 06/11/2014
  4695                                  ; 14/08/2015 
  4696                                  memory_info:	
  4697 00001875 A1[AC700000]            	mov	eax, [memory_size] ; in pages
  4698 0000187A 50                      	push	eax
  4699 0000187B C1E00C                  	shl	eax, 12		   ; in bytes
  4700 0000187E BB0A000000              	mov	ebx, 10
  4701 00001883 89D9                    	mov	ecx, ebx	   ; 10
  4702 00001885 BE[AD6C0000]            	mov	esi, mem_total_b_str	
  4703 0000188A E8B2000000              	call	bintdstr
  4704 0000188F 58                      	pop	eax
  4705 00001890 B107                    	mov	cl, 7
  4706 00001892 BE[D16C0000]            	mov	esi, mem_total_p_str
  4707 00001897 E8A5000000              	call	bintdstr	
  4708                                  	; 14/08/2015
  4709 0000189C E8BD000000              	call	calc_free_mem
  4710                                  	; edx = calculated free pages
  4711                                  	; ecx = 0
  4712 000018A1 A1[B0700000]            	mov 	eax, [free_pages]
  4713 000018A6 39D0                    	cmp	eax, edx ; calculated free mem value 
  4714                                  		; and initial free mem value are same or not?
  4715 000018A8 751D                    	jne 	short pmim ; print mem info with '?' if not
  4716 000018AA 52                      	push 	edx ; free memory in pages	
  4717                                  	;mov 	eax, edx
  4718 000018AB C1E00C                  	shl	eax, 12 ; convert page count
  4719                                  			; to byte count
  4720 000018AE B10A                    	mov	cl, 10
  4721 000018B0 BE[F16C0000]            	mov	esi, free_mem_b_str
  4722 000018B5 E887000000              	call	bintdstr
  4723 000018BA 58                      	pop	eax
  4724 000018BB B107                    	mov	cl, 7
  4725 000018BD BE[156D0000]            	mov	esi, free_mem_p_str
  4726 000018C2 E87A000000              	call	bintdstr
  4727                                  pmim:
  4728 000018C7 BE[9B6C0000]            	mov	esi, msg_memory_info
  4729                                  pmim_nb:	
  4730 000018CC AC                      	lodsb
  4731 000018CD 08C0                    	or	al, al
  4732 000018CF 740D                    	jz	short pmim_ok
  4733 000018D1 56                      	push	esi
  4734 000018D2 31DB                    	xor	ebx, ebx ; 0
  4735                                  			; Video page 0 (bl=0)
  4736 000018D4 B407                    	mov	ah, 07h ; Black background, 
  4737                                  			; light gray forecolor
  4738 000018D6 E842FCFFFF              	call	write_tty
  4739 000018DB 5E                      	pop	esi
  4740 000018DC EBEE                    	jmp	short pmim_nb
  4741                                  pmim_ok:
  4742 000018DE C3                      	retn
  4743                                  
  4744                                  ; Convert binary number to hexadecimal string
  4745                                  ; 10/05/2015  
  4746                                  ; dsectpm.s (28/02/2015)
  4747                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  4748                                  ; 01/12/2014
  4749                                  ; 25/11/2014
  4750                                  ;
  4751                                  bytetohex:
  4752                                  	; INPUT ->
  4753                                  	; 	AL = byte (binary number)
  4754                                  	; OUTPUT ->
  4755                                  	;	AX = hexadecimal string
  4756                                  	;
  4757 000018DF 53                      	push	ebx
  4758 000018E0 31DB                    	xor	ebx, ebx
  4759 000018E2 88C3                    	mov	bl, al
  4760 000018E4 C0EB04                  	shr	bl, 4
  4761 000018E7 8A9B[31190000]          	mov	bl, [ebx+hexchrs] 	 	
  4762 000018ED 86D8                    	xchg	bl, al
  4763 000018EF 80E30F                  	and	bl, 0Fh
  4764 000018F2 8AA3[31190000]          	mov	ah, [ebx+hexchrs] 
  4765 000018F8 5B                      	pop	ebx	
  4766 000018F9 C3                      	retn
  4767                                  
  4768                                  wordtohex:
  4769                                  	; INPUT ->
  4770                                  	; 	AX = word (binary number)
  4771                                  	; OUTPUT ->
  4772                                  	;	EAX = hexadecimal string
  4773                                  	;
  4774 000018FA 53                      	push	ebx
  4775 000018FB 31DB                    	xor	ebx, ebx
  4776 000018FD 86E0                    	xchg	ah, al
  4777 000018FF 6650                    	push	ax
  4778 00001901 88E3                    	mov	bl, ah
  4779 00001903 C0EB04                  	shr	bl, 4
  4780 00001906 8A83[31190000]          	mov	al, [ebx+hexchrs] 	 	
  4781 0000190C 88E3                    	mov	bl, ah
  4782 0000190E 80E30F                  	and	bl, 0Fh
  4783 00001911 8AA3[31190000]          	mov	ah, [ebx+hexchrs]
  4784 00001917 C1E010                  	shl	eax, 16
  4785 0000191A 6658                    	pop	ax
  4786 0000191C 5B                      	pop	ebx
  4787 0000191D EBC0                    	jmp	short bytetohex
  4788                                  	;mov	bl, al
  4789                                  	;shr	bl, 4
  4790                                  	;mov	bl, [ebx+hexchrs] 	 	
  4791                                  	;xchg	bl, al	 	
  4792                                  	;and	bl, 0Fh
  4793                                  	;mov	ah, [ebx+hexchrs] 
  4794                                  	;pop	ebx	
  4795                                  	;retn
  4796                                  
  4797                                  dwordtohex:
  4798                                  	; INPUT ->
  4799                                  	; 	EAX = dword (binary number)
  4800                                  	; OUTPUT ->
  4801                                  	;	EDX:EAX = hexadecimal string
  4802                                  	;
  4803 0000191F 50                      	push	eax
  4804 00001920 C1E810                  	shr	eax, 16
  4805 00001923 E8D2FFFFFF              	call	wordtohex
  4806 00001928 89C2                    	mov	edx, eax
  4807 0000192A 58                      	pop	eax
  4808 0000192B E8CAFFFFFF              	call	wordtohex
  4809 00001930 C3                      	retn
  4810                                  
  4811                                  ; 10/05/2015
  4812                                  hex_digits:
  4813                                  hexchrs:
  4814 00001931 303132333435363738-     	db '0123456789ABCDEF'
  4815 0000193A 39414243444546     
  4816                                  
  4817                                  ; Convert binary number to decimal/numeric string
  4818                                  ; 06/11/2014
  4819                                  ; Temporary Code
  4820                                  ;
  4821                                  
  4822                                  bintdstr:
  4823                                  	; EAX = binary number
  4824                                  	; ESI = decimal/numeric string address
  4825                                  	; EBX = divisor (10)
  4826                                  	; ECX = string length (<=10)
  4827 00001941 01CE                    	add	esi, ecx
  4828                                  btdstr0:
  4829 00001943 4E                      	dec	esi
  4830 00001944 31D2                    	xor	edx, edx
  4831 00001946 F7F3                    	div	ebx
  4832 00001948 80C230                  	add	dl, 30h
  4833 0000194B 8816                    	mov	[esi], dl
  4834 0000194D FEC9                    	dec	cl
  4835 0000194F 740C                    	jz	btdstr2
  4836 00001951 09C0                    	or	eax, eax
  4837 00001953 75EE                    	jnz	short btdstr0
  4838                                  btdstr1:
  4839 00001955 4E                      	dec	esi
  4840 00001956 C60620                          mov     byte [esi], 20h ; blank space
  4841 00001959 FEC9                    	dec	cl
  4842 0000195B 75F8                    	jnz	short btdstr1
  4843                                  btdstr2:
  4844 0000195D C3                      	retn
  4845                                  
  4846                                  ; Calculate free memory pages on M.A.T.
  4847                                  ; 06/11/2014
  4848                                  ; Temporary Code
  4849                                  ;
  4850                                  
  4851                                  calc_free_mem:
  4852 0000195E 31D2                    	xor	edx, edx
  4853                                  	;xor	ecx, ecx
  4854 00001960 668B0D[C0700000]        	mov	cx, [mat_size] ; in pages
  4855 00001967 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  4856 0000196A BE00001000              	mov	esi, MEM_ALLOC_TBL
  4857                                  cfm0:
  4858 0000196F AD                      	lodsd
  4859 00001970 51                      	push	ecx
  4860 00001971 B920000000              	mov	ecx, 32
  4861                                  cfm1:
  4862 00001976 D1E8                    	shr	eax, 1
  4863 00001978 7301                    	jnc	short cfm2
  4864 0000197A 42                      	inc	edx
  4865                                  cfm2:
  4866 0000197B E2F9                    	loop	cfm1
  4867 0000197D 59                      	pop	ecx
  4868 0000197E E2EF                    	loop	cfm0
  4869 00001980 C3                      	retn
  4870                                  
  4871                                  %include 'diskio.inc'  ; 07/03/2015
  4872                              <1> ; Retro UNIX 386 v1 Kernel - DISKIO.INC
  4873                              <1> ; Last Modification: 22/08/2015
  4874                              <1> ; 	(Initialized Disk Parameters Data is in 'DISKDATA.INC') 
  4875                              <1> ; 	(Uninitialized Disk Parameters Data is in 'DISKBSS.INC') 
  4876                              <1> 
  4877                              <1> ; DISK I/O SYSTEM - Erdogan Tan (Retro UNIX 386 v1 project)
  4878                              <1> 
  4879                              <1> ; ///////// DISK I/O SYSTEM ///////////////
  4880                              <1> 
  4881                              <1> ; 06/02/2015
  4882                              <1> diskette_io:
  4883 00001981 9C                  <1> 	pushfd
  4884 00001982 0E                  <1> 	push 	cs
  4885 00001983 E809000000          <1> 	call 	DISKETTE_IO_1
  4886 00001988 C3                  <1> 	retn
  4887                              <1> 	
  4888                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
  4889                              <1> ;//////////////////////////////////////////////////////
  4890                              <1> 
  4891                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  4892                              <1> ; 20/02/2015
  4893                              <1> ; 06/02/2015 (unix386.s)
  4894                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
  4895                              <1> ;
  4896                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
  4897                              <1> ;
  4898                              <1> ; ADISK.EQU
  4899                              <1> 
  4900                              <1> ;----- Wait control constants 
  4901                              <1> 
  4902                              <1> ;amount of time to wait while RESET is active.
  4903                              <1> 
  4904                              <1> WAITCPU_RESET_ON	EQU	21		;Reset on must last at least 14us
  4905                              <1> 						;at 250 KBS xfer rate.
  4906                              <1> 						;see INTEL MCS, 1985, pg. 5-456
  4907                              <1> 
  4908                              <1> WAITCPU_FOR_STATUS	EQU	100		;allow 30 microseconds for
  4909                              <1> 						;status register to become valid
  4910                              <1> 						;before re-reading.
  4911                              <1> 
  4912                              <1> ;After sending a byte to NEC, status register may remain
  4913                              <1> ;incorrectly set for 24 us.
  4914                              <1> 
  4915                              <1> WAITCPU_RQM_LOW		EQU	24		;number of loops to check for
  4916                              <1> 						;RQM low.
  4917                              <1> 
  4918                              <1> ; COMMON.MAC
  4919                              <1> ;
  4920                              <1> ;	Timing macros
  4921                              <1> ;
  4922                              <1> 
  4923                              <1> %macro 		SIODELAY 0 			; SHORT IODELAY
  4924                              <1> 		jmp short $+2
  4925                              <1> %endmacro		
  4926                              <1> 
  4927                              <1> %macro		IODELAY  0			; NORMAL IODELAY
  4928                              <1> 		jmp short $+2
  4929                              <1> 		jmp short $+2
  4930                              <1> %endmacro
  4931                              <1> 
  4932                              <1> %macro		NEWIODELAY 0
  4933                              <1> 		out	0ebh,al
  4934                              <1> %endmacro 
  4935                              <1> 
  4936                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
  4937                              <1> ;;; WAIT_FOR_MEM
  4938                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
  4939                              <1> ;WAIT_FDU_INT_HI	equ	1
  4940                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
  4941                              <1> ;;; WAIT_FOR_PORT
  4942                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
  4943                              <1> ;WAIT_FDU_SEND_HI	equ	0
  4944                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
  4945                              <1> ;Time to wait while waiting for each byte of NEC results = .5
  4946                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  4947                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
  4948                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
  4949                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
  4950                              <1> ;;; WAIT_REFRESH
  4951                              <1> ;amount of time to wait for head settle, per unit in parameter
  4952                              <1> ;table = 1 ms.
  4953                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
  4954                              <1> 
  4955                              <1> 
  4956                              <1> ; //////////////// DISKETTE I/O ////////////////
  4957                              <1> 
  4958                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
  4959                              <1> 
  4960                              <1> ;----------------------------------------
  4961                              <1> ;	EQUATES USED BY POST AND BIOS	:
  4962                              <1> ;----------------------------------------
  4963                              <1> 
  4964                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  4965                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  4966                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  4967                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
  4968                              <1> 
  4969                              <1> ;----------------------------------------
  4970                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
  4971                              <1> ;-------------------------------------------------------------------------------
  4972                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
  4973                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
  4974                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
  4975                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
  4976                              <1> 
  4977                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
  4978                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
  4979                              <1> ;		EQU	011H		; - RESERVED			      ;C
  4980                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
  4981                              <1> ;		EQU	013H		; - RESERVED			      ;E
  4982                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
  4983                              <1> 
  4984                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
  4985                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
  4986                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
  4987                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
  4988                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
  4989                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
  4990                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
  4991                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
  4992                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
  4993                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
  4994                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
  4995                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
  4996                              <1> 
  4997                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
  4998                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
  4999                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
  5000                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
  5001                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
  5002                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
  5003                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
  5004                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
  5005                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
  5006                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
  5007                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
  5008                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
  5009                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
  5010                              <1> 
  5011                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
  5012                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
  5013                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
  5014                              <1> 
  5015                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
  5016                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
  5017                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
  5018                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
  5019                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
  5020                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
  5021                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
  5022                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
  5023                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
  5024                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
  5025                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
  5026                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
  5027                              <1> 
  5028                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
  5029                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
  5030                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
  5031                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
  5032                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
  5033                              <1> 
  5034                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
  5035                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
  5036                              <1> ;INTA00		EQU	020H		; 8259 PORT
  5037                              <1> INTA01		EQU	021H		; 8259 PORT
  5038                              <1> INTB00		EQU	0A0H		; 2ND 8259
  5039                              <1> INTB01		EQU	0A1H		;
  5040                              <1> 
  5041                              <1> ;-------------------------------------------------------------------------------
  5042                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
  5043                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
  5044                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
  5045                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
  5046                              <1> ;-------------------------------------------------------------------------------
  5047                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
  5048                              <1> 
  5049                              <1> ;-------------------------------------------------------------------------------
  5050                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
  5051                              <1> 
  5052                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
  5053                              <1> ; (unix386.s <-- dsectrm2.s)
  5054                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
  5055                              <1> 
  5056                              <1> ; 10/12/2014
  5057                              <1> ;
  5058                              <1> ;int40h:
  5059                              <1> ;	pushf
  5060                              <1> ;	push 	cs
  5061                              <1> ;	;cli
  5062                              <1> ;	call 	DISKETTE_IO_1
  5063                              <1> ;	retn
  5064                              <1> 
  5065                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
  5066                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  5067                              <1> ;
  5068                              <1> 
  5069                              <1> ;-- INT13H ---------------------------------------------------------------------
  5070                              <1> ; DISKETTE I/O
  5071                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
  5072                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
  5073                              <1> ; INPUT
  5074                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
  5075                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
  5076                              <1> ;		ON ALL DRIVES
  5077                              <1> ;------------------------------------------------------------------------------- 
  5078                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
  5079                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
  5080                              <1> ;-------------------------------------------------------------------------------
  5081                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
  5082                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5083                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
  5084                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
  5085                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
  5086                              <1> ;		320/360	320/360	    0-39
  5087                              <1> ;		320/360	1.2M	    0-39
  5088                              <1> ;		1.2M	1.2M	    0-79
  5089                              <1> ;		720K	720K	    0-79
  5090                              <1> ;		1.44M	1.44M	    0-79	
  5091                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
  5092                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
  5093                              <1> ;		320/360	320/360	     1-8/9
  5094                              <1> ;		320/360	1.2M	     1-8/9
  5095                              <1> ;		1.2M	1.2M	     1-15
  5096                              <1> ;		720K	720K	     1-9
  5097                              <1> ;		1.44M	1.44M	     1-18		
  5098                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
  5099                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
  5100                              <1> ;		320/360	320/360	        8/9
  5101                              <1> ;		320/360	1.2M	        8/9
  5102                              <1> ;		1.2M	1.2M		15
  5103                              <1> ;		720K	720K		9
  5104                              <1> ;		1.44M	1.44M		18
  5105                              <1> ;
  5106                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
  5107                              <1> ;
  5108                              <1> ;-------------------------------------------------------------------------------
  5109                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
  5110                              <1> ;-------------------------------------------------------------------------------
  5111                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
  5112                              <1> ;-------------------------------------------------------------------------------
  5113                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
  5114                              <1> ;-------------------------------------------------------------------------------
  5115                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
  5116                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
  5117                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
  5118                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
  5119                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
  5120                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
  5121                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
  5122                              <1> ;		READ/WRITE ACCESS.
  5123                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
  5124                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
  5125                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
  5126                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
  5127                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
  5128                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
  5129                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
  5130                              <1> ;
  5131                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
  5132                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
  5133                              <1> ;		---------------------------------------------
  5134                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
  5135                              <1> ;		---------------------------------------------
  5136                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
  5137                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
  5138                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
  5139                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
  5140                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
  5141                              <1> ;		---------------------------------------------
  5142                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
  5143                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
  5144                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
  5145                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
  5146                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
  5147                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
  5148                              <1> ;-------------------------------------------------------------------------------
  5149                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
  5150                              <1> ;	REGISTERS
  5151                              <1> ;	  INPUT
  5152                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5153                              <1> ;	  OUTPUT
  5154                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
  5155                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
  5156                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5157                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5158                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
  5159                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
  5160                              <1> ;	    (BH) - 0
  5161                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
  5162                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
  5163                              <1> ;	    (AX) - 0
  5164                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
  5165                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
  5166                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
  5167                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
  5168                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
  5169                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
  5170                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
  5171                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
  5172                              <1> ;-------------------------------------------------------------------------------
  5173                              <1> ;	(AH)= 15H  READ DASD TYPE
  5174                              <1> ;	OUTPUT REGISTERS
  5175                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
  5176                              <1> ;		00 - DRIVE NOT PRESENT	
  5177                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
  5178                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
  5179                              <1> ;		03 - RESERVED (FIXED DISK)
  5180                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5181                              <1> ;-------------------------------------------------------------------------------
  5182                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
  5183                              <1> ;	OUTPUT REGISTERS
  5184                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
  5185                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
  5186                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5187                              <1> ;-------------------------------------------------------------------------------
  5188                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
  5189                              <1> ;	INPUT REGISTERS
  5190                              <1> ;	(AL) -	00 - NOT USED	
  5191                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
  5192                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
  5193                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
  5194                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
  5195                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
  5196                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
  5197                              <1> ;-------------------------------------------------------------------------------
  5198                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
  5199                              <1> ;	INPUT REGISTERS
  5200                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
  5201                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5202                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5203                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
  5204                              <1> ;	OUTPUT REGISTERS:
  5205                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
  5206                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
  5207                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
  5208                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
  5209                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
  5210                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
  5211                              <1> ;-------------------------------------------------------------------------------
  5212                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
  5213                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
  5214                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
  5215                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
  5216                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
  5217                              <1> ;		CHANGE ERROR CODE
  5218                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
  5219                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
  5220                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
  5221                              <1> ;
  5222                              <1> ; DATA VARIABLE -- @DISK_POINTER
  5223                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
  5224                              <1> ;-------------------------------------------------------------------------------
  5225                              <1> ; OUTPUT FOR ALL FUNCTIONS
  5226                              <1> ;	AH = STATUS OF OPERATION
  5227                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
  5228                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
  5229                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
  5230                              <1> ;		TYPE AH=(15)).
  5231                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
  5232                              <1> ;	FOR READ/WRITE/VERIFY
  5233                              <1> ;		DS,BX,DX,CX PRESERVED
  5234                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
  5235                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
  5236                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
  5237                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
  5238                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
  5239                              <1> ;-------------------------------------------------------------------------------
  5240                              <1> ;
  5241                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
  5242                              <1> ;
  5243                              <1> ;   -----------------------------------------------------------------
  5244                              <1> ;   |       |       |       |       |       |       |       |       |
  5245                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
  5246                              <1> ;   |       |       |       |       |       |       |       |       |
  5247                              <1> ;   -----------------------------------------------------------------
  5248                              <1> ;	|	|	|	|	|	|	|	|
  5249                              <1> ;	|	|	|	|	|	-----------------
  5250                              <1> ;	|	|	|	|	|		|
  5251                              <1> ;	|	|	|	|    RESERVED		|
  5252                              <1> ;	|	|	|	|		  PRESENT STATE
  5253                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
  5254                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
  5255                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
  5256                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
  5257                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
  5258                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
  5259                              <1> ;	|	|	|	|	110: RESERVED
  5260                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
  5261                              <1> ;	|	|	|	|
  5262                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
  5263                              <1> ;	|	|	|
  5264                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
  5265                              <1> ;	|	|			DRIVE)
  5266                              <1> ;	|	|
  5267                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
  5268                              <1> ;
  5269                              <1> ;						00: 500 KBS
  5270                              <1> ;						01: 300 KBS
  5271                              <1> ;						10: 250 KBS
  5272                              <1> ;						11: RESERVED
  5273                              <1> ;
  5274                              <1> ;
  5275                              <1> ;-------------------------------------------------------------------------------
  5276                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
  5277                              <1> ;-------------------------------------------------------------------------------
  5278                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
  5279                              <1> ;-------------------------------------------------------------------------------
  5280                              <1> 
  5281                              <1> struc MD
  5282 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  5283 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  5284 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  5285 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
  5286 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
  5287 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
  5288 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
  5289 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
  5290 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
  5291 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
  5292 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
  5293 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
  5294 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
  5295                              <1> endstruc
  5296                              <1> 
  5297                              <1> BIT7OFF	EQU	7FH
  5298                              <1> BIT7ON	EQU	80H
  5299                              <1> 
  5300                              <1> ;;int13h: ; 16/02/2015
  5301                              <1> ;; 16/02/2015 - 21/02/2015
  5302                              <1> int40h:
  5303 00001989 9C                  <1> 	pushfd
  5304 0000198A 0E                  <1> 	push 	cs
  5305 0000198B E801000000          <1> 	call 	DISKETTE_IO_1
  5306 00001990 C3                  <1> 	retn	
  5307                              <1> 
  5308                              <1> DISKETTE_IO_1:
  5309                              <1> 
  5310 00001991 FB                  <1> 	STI				; INTERRUPTS BACK ON
  5311 00001992 55                  <1> 	PUSH	eBP			; USER REGISTER
  5312 00001993 57                  <1> 	PUSH	eDI			; USER REGISTER
  5313 00001994 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
  5314 00001995 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
  5315 00001996 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
  5316 00001997 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
  5317                              <1> 					; [BP]   = SECTOR #
  5318                              <1> 					; [BP+1] = TRACK #
  5319                              <1> 					; [BP+2] = BUFFER OFFSET
  5320                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
  5321                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
  5322                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
  5323                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
  5324                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
  5325                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
  5326                              <1> 					; BH/[BP+3] = 0
  5327                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
  5328                              <1> 					; DH/[BP+5] = MAX HEAD #
  5329                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
  5330 00001999 06                  <1> 	push	es ; 06/02/2015	
  5331 0000199A 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
  5332 0000199B 56                  <1> 	PUSH	eSI			; USER REGISTERS
  5333                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
  5334                              <1> 	;mov	cx, cs
  5335                              <1> 	;mov	ds, cx
  5336 0000199C 66B91000            <1> 	mov	cx, KDATA
  5337 000019A0 8ED9                <1>         mov     ds, cx
  5338 000019A2 8EC1                <1>         mov     es, cx
  5339                              <1> 
  5340                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
  5341 000019A4 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4 ; 18/02/2015
  5342 000019A7 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
  5343 000019A9 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5344                              <1> OK_FUNC:
  5345 000019AB 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
  5346 000019AE 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
  5347 000019B0 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
  5348 000019B3 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
  5349 000019B5 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
  5350 000019B8 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
  5351 000019BA B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5352                              <1> OK_DRV:
  5353 000019BC 31C9                <1> 	xor	ecx, ecx
  5354                              <1> 	;mov	esi, ecx ; 08/02/2015
  5355 000019BE 89CF                <1> 	mov	edi, ecx ; 08/02/2015
  5356 000019C0 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
  5357                              <1> 	;XOR	CH,CH			; CX = FUNCTION
  5358                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
  5359 000019C2 C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
  5360 000019C5 BB[FD190000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
  5361 000019CA 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
  5362 000019CC 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
  5363 000019CE 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
  5364 000019D0 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
  5365 000019D3 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
  5366                              <1> 	;
  5367                              <1> 	; 11/12/2014
  5368 000019D6 8815[516B0000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
  5369                              <1> 	;
  5370 000019DC 8A25[2C710000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
  5371 000019E2 C605[2C710000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
  5372                              <1> 
  5373                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
  5374                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
  5375                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
  5376                              <1> ;
  5377                              <1> ;		DI	: DRIVE #
  5378                              <1> ;		SI-HI	: HEAD #
  5379                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
  5380                              <1> ;		ES	: BUFFER SEGMENT
  5381                              <1> ;		[BP]	: SECTOR #
  5382                              <1> ;		[BP+1]	: TRACK #
  5383                              <1> ;		[BP+2]	: BUFFER OFFSET
  5384                              <1> ;
  5385                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
  5386                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
  5387                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
  5388                              <1> ;	SPECIFIC ERROR CODE.
  5389                              <1> ;
  5390                              <1> 					; (AH) = @DSKETTE_STATUS
  5391 000019E9 FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
  5392 000019EB 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
  5393 000019EC 1F                  <1> 	POP	DS
  5394 000019ED 07                  <1> 	pop	es	; 06/02/2015
  5395 000019EE 59                  <1> 	POP	eCX
  5396 000019EF 5B                  <1> 	POP	eBX
  5397 000019F0 5A                  <1> 	POP	eDX
  5398 000019F1 5F                  <1> 	POP	eDI
  5399 000019F2 89E5                <1> 	MOV	eBP, eSP
  5400 000019F4 50                  <1> 	PUSH	eAX
  5401 000019F5 9C                  <1> 	PUSHFd
  5402 000019F6 58                  <1> 	POP	eAX
  5403                              <1> 	;MOV	[BP+6], AX
  5404 000019F7 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
  5405 000019FA 58                  <1> 	POP	eAX
  5406 000019FB 5D                  <1> 	POP	eBP
  5407 000019FC CF                  <1> 	IRETd
  5408                              <1> 
  5409                              <1> ;-------------------------------------------------------------------------------
  5410                              <1> ; DW --> dd (06/02/2015)
  5411 000019FD [611A0000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
  5412 00001A01 [DA1A0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
  5413 00001A05 [EB1A0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
  5414 00001A09 [FC1A0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
  5415 00001A0D [0D1B0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
  5416 00001A11 [1E1B0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
  5417 00001A15 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
  5418 00001A19 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
  5419 00001A1D [B01B0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
  5420 00001A21 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
  5421 00001A25 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
  5422 00001A29 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
  5423 00001A2D [A31B0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
  5424 00001A31 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
  5425 00001A35 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
  5426 00001A39 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
  5427 00001A3D [A31B0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
  5428 00001A41 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
  5429 00001A45 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
  5430 00001A49 [A31B0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
  5431 00001A4D [A31B0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
  5432 00001A51 [711C0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
  5433 00001A55 [9C1C0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
  5434 00001A59 [D61C0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
  5435 00001A5D [591D0000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
  5436                              <1> FNC_TAE EQU     $                       ; END
  5437                              <1> 
  5438                              <1> ;-------------------------------------------------------------------------------
  5439                              <1> ; DISK_RESET	(AH = 00H)	
  5440                              <1> ;		RESET THE DISKETTE SYSTEM.
  5441                              <1> ;
  5442                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5443                              <1> ;-------------------------------------------------------------------------------
  5444                              <1> DSK_RESET:
  5445 00001A61 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
  5446 00001A65 FA                  <1> 	CLI				; NO INTERRUPTS
  5447 00001A66 A0[2A710000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  5448 00001A6B 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
  5449 00001A6D C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
  5450                              <1> 					; DRIVE SELECT TO LOW NIBBLE
  5451 00001A70 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
  5452 00001A72 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5453 00001A73 C605[29710000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  5454                              <1> 	;JMP	$+2			; WAIT FOR I/O
  5455                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
  5456                              <1> 					;      PULSE WIDTH)
  5457                              <1> 	; 19/12/2014
  5458                              <1> 	NEWIODELAY
  5459 00001A7A E6EB                <2>  out 0ebh,al
  5460                              <1> 
  5461                              <1> 	; 17/12/2014 
  5462                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
  5463 00001A7C B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
  5464                              <1> wdw1:
  5465                              <1> 	NEWIODELAY   ; 27/02/2015
  5466 00001A81 E6EB                <2>  out 0ebh,al
  5467 00001A83 E2FC                <1> 	loop	wdw1
  5468                              <1> 	;
  5469 00001A85 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
  5470 00001A87 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5471                              <1> 	; 16/12/2014
  5472                              <1> 	IODELAY
  5473 00001A88 EB00                <2>  jmp short $+2
  5474 00001A8A EB00                <2>  jmp short $+2
  5475                              <1> 	;
  5476                              <1> 	;STI				; ENABLE THE INTERRUPTS
  5477 00001A8C E8240C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  5478 00001A91 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
  5479 00001A93 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
  5480                              <1> NXT_DRV:
  5481 00001A97 6651                <1> 	PUSH	CX			; SAVE FOR CALL
  5482 00001A99 B8[CF1A0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
  5483 00001A9E 50                  <1> 	PUSH	eAX			; "
  5484 00001A9F B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  5485 00001AA1 E8020B0000          <1> 	CALL	NEC_OUTPUT
  5486 00001AA6 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  5487 00001AA7 E8390C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  5488 00001AAC 6659                <1> 	POP	CX			; RESTORE AFTER CALL
  5489 00001AAE 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
  5490 00001AB0 3A0D[2D710000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
  5491 00001AB6 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
  5492 00001AB8 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
  5493 00001ABA 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
  5494 00001ABD 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
  5495                              <1> 	;
  5496 00001ABF E852030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5497                              <1> RESBAC:
  5498 00001AC4 E805090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5499 00001AC9 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5500 00001ACC 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5501 00001ACE C3                  <1> 	RETn		
  5502                              <1> DR_POP_ERR:
  5503 00001ACF 6659                <1> 	POP	CX			; CLEAR STACK
  5504                              <1> DR_ERR:
  5505 00001AD1 800D[2C710000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
  5506 00001AD8 EBEA                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
  5507                              <1> 
  5508                              <1> ;-------------------------------------------------------------------------------
  5509                              <1> ; DISK_STATUS	(AH = 01H)
  5510                              <1> ;	DISKETTE STATUS.
  5511                              <1> ;
  5512                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
  5513                              <1> ;
  5514                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
  5515                              <1> ;-------------------------------------------------------------------------------
  5516                              <1> DSK_STATUS:
  5517 00001ADA 8825[2C710000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
  5518 00001AE0 E8E9080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5519 00001AE5 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5520 00001AE8 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5521 00001AEA C3                  <1> 	RETn		
  5522                              <1> 
  5523                              <1> ;-------------------------------------------------------------------------------
  5524                              <1> ; DISK_READ	(AH = 02H)	
  5525                              <1> ;	DISKETTE READ.
  5526                              <1> ;
  5527                              <1> ; ON ENTRY:	DI	: DRIVE #
  5528                              <1> ;		SI-HI	: HEAD #
  5529                              <1> ;		SI-LOW	: # OF SECTORS
  5530                              <1> ;		ES	: BUFFER SEGMENT
  5531                              <1> ;		[BP]	: SECTOR #
  5532                              <1> ;		[BP+1]	: TRACK #
  5533                              <1> ;		[BP+2]	: BUFFER OFFSET
  5534                              <1> ;
  5535                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5536                              <1> ;-------------------------------------------------------------------------------
  5537                              <1> 
  5538                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5539                              <1> 
  5540                              <1> DSK_READ:
  5541 00001AEB 8025[2A710000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5542 00001AF2 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
  5543 00001AF6 E825040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5544 00001AFB C3                  <1> 	RETn
  5545                              <1> 
  5546                              <1> ;-------------------------------------------------------------------------------
  5547                              <1> ; DISK_WRITE	(AH = 03H)
  5548                              <1> ;	DISKETTE WRITE.
  5549                              <1> ;
  5550                              <1> ; ON ENTRY:	DI	: DRIVE #
  5551                              <1> ;		SI-HI	: HEAD #
  5552                              <1> ;		SI-LOW	: # OF SECTORS
  5553                              <1> ;		ES	: BUFFER SEGMENT
  5554                              <1> ;		[BP]	: SECTOR #
  5555                              <1> ;		[BP+1]	: TRACK #
  5556                              <1> ;		[BP+2]	: BUFFER OFFSET
  5557                              <1> ;
  5558                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5559                              <1> ;-------------------------------------------------------------------------------
  5560                              <1> 
  5561                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5562                              <1> 
  5563                              <1> DSK_WRITE:
  5564 00001AFC 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
  5565 00001B00 800D[2A710000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
  5566 00001B07 E814040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5567 00001B0C C3                  <1> 	RETn
  5568                              <1> 
  5569                              <1> ;-------------------------------------------------------------------------------
  5570                              <1> ; DISK_VERF	(AH = 04H)
  5571                              <1> ;	DISKETTE VERIFY.
  5572                              <1> ;
  5573                              <1> ; ON ENTRY:	DI	: DRIVE #
  5574                              <1> ;		SI-HI	: HEAD #
  5575                              <1> ;		SI-LOW	: # OF SECTORS
  5576                              <1> ;		ES	: BUFFER SEGMENT
  5577                              <1> ;		[BP]	: SECTOR #
  5578                              <1> ;		[BP+1]	: TRACK #
  5579                              <1> ;		[BP+2]	: BUFFER OFFSET
  5580                              <1> ;
  5581                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5582                              <1> ;-------------------------------------------------------------------------------
  5583                              <1> DSK_VERF:
  5584 00001B0D 8025[2A710000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5585 00001B14 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
  5586 00001B18 E803040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5587 00001B1D C3                  <1> 	RETn
  5588                              <1> 
  5589                              <1> ;-------------------------------------------------------------------------------
  5590                              <1> ; DISK_FORMAT	(AH = 05H)
  5591                              <1> ;	DISKETTE FORMAT.
  5592                              <1> ;
  5593                              <1> ; ON ENTRY:	DI	: DRIVE #
  5594                              <1> ;		SI-HI	: HEAD #
  5595                              <1> ;		SI-LOW	: # OF SECTORS
  5596                              <1> ;		ES	: BUFFER SEGMENT
  5597                              <1> ;		[BP]	: SECTOR #
  5598                              <1> ;		[BP+1]	: TRACK #
  5599                              <1> ;		[BP+2]	: BUFFER OFFSET
  5600                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
  5601                              <1> ;
  5602                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5603                              <1> ;-------------------------------------------------------------------------------
  5604                              <1> DSK_FORMAT:
  5605 00001B1E E83C030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5606 00001B23 E838050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
  5607 00001B28 800D[2A710000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
  5608 00001B2F E880050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
  5609 00001B34 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
  5610 00001B36 E8DB020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5611 00001B3B E8E6050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
  5612 00001B40 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
  5613 00001B42 E8BD050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
  5614                              <1> FM_WR:
  5615 00001B47 E872060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
  5616 00001B4C 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
  5617 00001B4E B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
  5618 00001B50 E8CF060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
  5619 00001B55 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
  5620 00001B57 B8[931B0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
  5621 00001B5C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  5622 00001B5D B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
  5623 00001B5F E83E090000          <1> 	CALL	GET_PARM
  5624 00001B64 E83F0A0000          <1> 	CALL	NEC_OUTPUT
  5625 00001B69 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
  5626 00001B6B E832090000          <1> 	CALL	GET_PARM
  5627 00001B70 E8330A0000          <1> 	CALL	NEC_OUTPUT
  5628 00001B75 B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
  5629 00001B77 E826090000          <1> 	CALL	GET_PARM
  5630 00001B7C E8270A0000          <1> 	CALL	NEC_OUTPUT
  5631 00001B81 B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
  5632 00001B83 E81A090000          <1> 	CALL	GET_PARM
  5633 00001B88 E81B0A0000          <1> 	CALL	NEC_OUTPUT
  5634 00001B8D 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  5635 00001B8E E80F070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
  5636                              <1> FM_DON:
  5637 00001B93 E8F8020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5638 00001B98 E831080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5639 00001B9D 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5640 00001BA0 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5641 00001BA2 C3                  <1> 	RETn
  5642                              <1> 
  5643                              <1> ;-------------------------------------------------------------------------------
  5644                              <1> ; FNC_ERR
  5645                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
  5646                              <1> ;	SET BAD COMMAND IN STATUS.
  5647                              <1> ;
  5648                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5649                              <1> ;-------------------------------------------------------------------------------
  5650                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
  5651 00001BA3 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
  5652 00001BA6 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  5653 00001BA8 8825[2C710000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
  5654 00001BAE F9                  <1> 	STC				; SET CARRY INDICATING ERROR
  5655 00001BAF C3                  <1> 	RETn
  5656                              <1> 
  5657                              <1> ;-------------------------------------------------------------------------------
  5658                              <1> ; DISK_PARMS	(AH = 08H)	
  5659                              <1> ;	READ DRIVE PARAMETERS.
  5660                              <1> ;
  5661                              <1> ; ON ENTRY:	DI : DRIVE #
  5662                              <1> ;
  5663                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
  5664                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
  5665                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
  5666                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
  5667                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
  5668                              <1> ;		BH/[BP+3] = 0
  5669                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
  5670                              <1> ;		DH/[BP+5] = MAX HEAD #
  5671                              <1> ;		DI/[BP+6] = OFFSET TO DISK_BASE
  5672                              <1> ;		ES        = SEGMENT OF DISK_BASE
  5673                              <1> ;		AX        = 0
  5674                              <1> ;
  5675                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
  5676                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
  5677                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
  5678                              <1> ;		       CALLER.
  5679                              <1> ;-------------------------------------------------------------------------------
  5680                              <1> DSK_PARMS:
  5681 00001BB0 E8AA020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  5682                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
  5683 00001BB5 29D2                <1> 	sub     edx, edx ; 20/02/2015
  5684 00001BB7 895504              <1>         mov	[ebp+4], edx ; 20/02/2015
  5685                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
  5686                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
  5687                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
  5688                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
  5689                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
  5690                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
  5691                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
  5692                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
  5693                              <1> 	;sub	edx, edx
  5694 00001BBA 66A1[D86D0000]      <1> 	mov     ax, [fd0_type]
  5695 00001BC0 6621C0              <1> 	and     ax, ax
  5696 00001BC3 7474                <1> 	jz      short NON_DRV
  5697 00001BC5 FEC2                <1> 	inc     dl
  5698 00001BC7 20E4                <1> 	and     ah, ah
  5699 00001BC9 7402                <1> 	jz      short STO_DL
  5700 00001BCB FEC2                <1> 	inc     dl
  5701                              <1> STO_DL:
  5702                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
  5703 00001BCD 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
  5704 00001BD0 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
  5705 00001BD4 7766                <1> 	JA	short NON_DRV1		; DRIVE INVALID
  5706                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
  5707 00001BD6 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
  5708 00001BDA E8BA080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  5709                              <1> 	;;20/02/2015
  5710                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
  5711                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
  5712 00001BDF 7412                <1> 	JZ	short CHK_EST		; JUMP IF SO
  5713 00001BE1 E805020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5714 00001BE6 720B                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
  5715                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
  5716 00001BE8 884504              <1>         mov	[ebp+4], al ; 06/02/2015
  5717 00001BEB 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
  5718 00001BEE 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
  5719 00001BF1 EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
  5720                              <1> CHK_EST:
  5721 00001BF3 8AA7[39710000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
  5722 00001BF9 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
  5723 00001BFC 743E                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
  5724                              <1> USE_EST:
  5725 00001BFE 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
  5726 00001C01 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  5727 00001C04 7557                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
  5728                              <1> 
  5729                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
  5730                              <1> 
  5731 00001C06 B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
  5732 00001C08 E8DE010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5733 00001C0D 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5734 00001C10 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5735 00001C13 F687[39710000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
  5736 00001C1A 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
  5737                              <1> 
  5738                              <1> ;-----	IT IS 1.44 MB DRIVE
  5739                              <1> 
  5740                              <1> PARM144:
  5741 00001C1C B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
  5742 00001C1E E8C8010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5743 00001C23 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5744 00001C26 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5745                              <1> STO_CX:
  5746 00001C29 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
  5747                              <1> ES_DI:
  5748                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
  5749 00001C2C 895D0C              <1> 	mov	[ebp+12], ebx ; 06/02/2015
  5750                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
  5751                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  5752                              <1> DP_OUT:
  5753 00001C2F E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5754 00001C34 6631C0              <1> 	XOR	AX,AX			; CLEAR
  5755 00001C37 F8                  <1> 	CLC
  5756 00001C38 C3                  <1> 	RETn
  5757                              <1> 
  5758                              <1> ;-----	NO DRIYE PRESENT HANDLER
  5759                              <1> 
  5760                              <1> NON_DRV:
  5761                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
  5762 00001C39 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
  5763                              <1> NON_DRV1:
  5764 00001C3C 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
  5765 00001C41 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
  5766                              <1> 
  5767                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
  5768                              <1> 	
  5769 00001C43 E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
  5770 00001C48 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
  5771 00001C4B B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  5772 00001C4D F9                  <1> 	STC
  5773 00001C4E C3                  <1> 	RETn
  5774                              <1> 
  5775                              <1> NON_DRV2:
  5776                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
  5777 00001C4F 31C0                <1> 	xor	eax, eax	
  5778 00001C51 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
  5779                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
  5780 00001C55 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
  5781                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
  5782 00001C58 89450C              <1> 	mov	[ebp+12], eax
  5783                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  5784 00001C5B EBD2                <1> 	JMP	SHORT DP_OUT
  5785                              <1> 
  5786                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
  5787                              <1> 
  5788                              <1> USE_EST2:
  5789 00001C5D B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
  5790 00001C5F E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5791 00001C64 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5792 00001C67 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5793 00001C6A 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  5794 00001C6D 74BA                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
  5795 00001C6F EBAB                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
  5796                              <1> 
  5797                              <1> ;-------------------------------------------------------------------------------
  5798                              <1> ; DISK_TYPE (AH = 15H)	
  5799                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
  5800                              <1> ;
  5801                              <1> ;  ON ENTRY:	DI = DRIVE #
  5802                              <1> ;
  5803                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
  5804                              <1> ;-------------------------------------------------------------------------------
  5805                              <1> DSK_TYPE:
  5806 00001C71 E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5807 00001C76 8A87[39710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
  5808 00001C7C 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
  5809 00001C7E 7418                <1> 	JZ	short NO_DRV
  5810 00001C80 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
  5811 00001C82 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
  5812 00001C84 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
  5813 00001C86 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
  5814                              <1> DT_BACK:
  5815 00001C88 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
  5816 00001C8A E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5817 00001C8F 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
  5818 00001C91 F8                  <1> 	CLC				; NO ERROR
  5819 00001C92 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5820 00001C95 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5821 00001C97 C3                  <1> 	RETn
  5822                              <1> NO_DRV:	
  5823 00001C98 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
  5824 00001C9A EBEC                <1> 	JMP	SHORT DT_BACK
  5825                              <1> 
  5826                              <1> ;-------------------------------------------------------------------------------
  5827                              <1> ; DISK_CHANGE	(AH = 16H)
  5828                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
  5829                              <1> ;
  5830                              <1> ; ON ENTRY:	DI = DRIVE #
  5831                              <1> ;
  5832                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
  5833                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
  5834                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
  5835                              <1> ;-------------------------------------------------------------------------------
  5836                              <1> DSK_CHANGE:
  5837 00001C9C E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5838 00001CA1 8A87[39710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  5839 00001CA7 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  5840 00001CA9 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  5841 00001CAB A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  5842 00001CAD 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  5843                              <1> DC0:
  5844 00001CAF E88C0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  5845 00001CB4 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  5846                              <1> 
  5847 00001CB6 C605[2C710000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  5848                              <1> 
  5849 00001CBD E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5850 00001CC2 E807070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5851 00001CC7 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5852 00001CCA 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5853 00001CCC C3                  <1> 	RETn
  5854                              <1> DC_NON:
  5855 00001CCD 800D[2C710000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  5856 00001CD4 EBE7                <1> 	JMP	SHORT FINIS
  5857                              <1> 
  5858                              <1> ;-------------------------------------------------------------------------------
  5859                              <1> ; FORMAT_SET	(AH = 17H)
  5860                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  5861                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  5862                              <1> ;
  5863                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  5864                              <1> ;		DI     = DRIVE #
  5865                              <1> ;
  5866                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  5867                              <1> ;		AH = @DSKETTE_STATUS
  5868                              <1> ;		CY = 1 IF ERROR
  5869                              <1> ;-------------------------------------------------------------------------------
  5870                              <1> FORMAT_SET:
  5871 00001CD6 E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5872 00001CDB 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  5873 00001CDD 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  5874 00001CE0 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  5875 00001CE2 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  5876 00001CE5 80A7[39710000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  5877 00001CEC 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  5878 00001CEE 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  5879 00001CF0 808F[39710000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  5880 00001CF7 EB48                <1> 	JMP	SHORT S0
  5881                              <1> 
  5882                              <1> NOT_320:
  5883 00001CF9 E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  5884 00001CFE 803D[2C710000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  5885 00001D05 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  5886                              <1> S3:
  5887 00001D07 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  5888 00001D09 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  5889 00001D0B 808F[39710000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  5890 00001D12 EB2D                <1> 	JMP	SHORT S0
  5891                              <1> 
  5892                              <1> NOT_320_12:
  5893 00001D14 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  5894 00001D16 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  5895 00001D18 808F[39710000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  5896 00001D1F EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  5897                              <1> 
  5898                              <1> NOT_12:	
  5899 00001D21 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  5900 00001D23 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  5901                              <1> 
  5902 00001D25 F687[39710000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  5903 00001D2C 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  5904 00001D2E B050                <1> 	MOV	AL,MED_DET+RATE_300
  5905 00001D30 F687[39710000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  5906 00001D37 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  5907                              <1> 
  5908                              <1> ASSUME:
  5909 00001D39 B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  5910                              <1> 
  5911                              <1> OR_IT_IN:
  5912 00001D3B 0887[39710000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  5913                              <1> S0:
  5914 00001D41 E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5915 00001D46 E883060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5916 00001D4B 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  5917 00001D4D 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5918 00001D4F C3                  <1> 	RETn
  5919                              <1> 
  5920                              <1> FS_ERR:
  5921 00001D50 C605[2C710000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  5922 00001D57 EBE8                <1> 	JMP	SHORT S0
  5923                              <1> 
  5924                              <1> ;-------------------------------------------------------------------------------
  5925                              <1> ; SET_MEDIA	(AH = 18H)
  5926                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  5927                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  5928                              <1> ;
  5929                              <1> ; ON ENTRY:
  5930                              <1> ;	[BP]	= SECTOR PER TRACK
  5931                              <1> ;	[BP+1]	= TRACK #
  5932                              <1> ;	DI	= DRIVE #
  5933                              <1> ;
  5934                              <1> ; ON EXIT:
  5935                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  5936                              <1> ;	IF NO ERROR:
  5937                              <1> ;		AH = 0
  5938                              <1> ;		CY = 0
  5939                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  5940                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  5941                              <1> ;	IF ERROR:	
  5942                              <1> ;		AH = @DSKETTE_STATUS
  5943                              <1> ;		CY = 1
  5944                              <1> ;-------------------------------------------------------------------------------
  5945                              <1> SET_MEDIA:
  5946 00001D59 E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5947 00001D5E F687[39710000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  5948 00001D65 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  5949 00001D67 E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  5950 00001D6C 803D[2C710000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  5951 00001D73 746B                <1> 	JE	short SM_RTN
  5952 00001D75 C605[2C710000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  5953                              <1> SM_CMOS:
  5954 00001D7C E818070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  5955                              <1> 	;;20/02/2015
  5956                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  5957                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  5958 00001D81 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  5959 00001D83 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5960 00001D88 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  5961 00001D8A 57                  <1> 	PUSH	eDI			; SAVE REG.
  5962 00001D8B 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  5963 00001D8D B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  5964                              <1> DR_SEARCH:
  5965 00001D92 8AA3[DC6A0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  5966 00001D98 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  5967 00001D9B 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  5968 00001D9D 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  5969                              <1> DR_FND:
  5970 00001D9F 8BBB[DD6A0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  5971                              <1> MD_SEARCH:
  5972 00001DA5 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5973 00001DA8 386500              <1> 	CMP	[eBP],AH		; MATCH?
  5974 00001DAB 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  5975 00001DAD 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  5976 00001DB0 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  5977 00001DB3 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  5978                              <1> NXT_MD:
  5979                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  5980 00001DB5 83C305              <1>         add	ebx, 5 ; 18/02/2015
  5981 00001DB8 E2D8                <1> 	LOOP    DR_SEARCH
  5982 00001DBA 5F                  <1> 	POP	eDI			; RESTORE REG.
  5983                              <1> MD_NOT_FND:
  5984 00001DBB C605[2C710000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  5985 00001DC2 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  5986                              <1> MD_FND:
  5987 00001DC4 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  5988 00001DC7 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  5989 00001DC9 7502                <1> 	JNE	short MD_SET
  5990 00001DCB 0C20                <1> 	OR	AL,DBL_STEP
  5991                              <1> MD_SET:
  5992                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  5993 00001DCD 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  5994 00001DD0 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  5995 00001DD2 5F                  <1> 	POP	eDI
  5996 00001DD3 80A7[39710000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  5997 00001DDA 0887[39710000]      <1> 	OR	[DSK_STATE+eDI], AL
  5998                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  5999                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  6000                              <1> SM_RTN:
  6001 00001DE0 E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6002 00001DE5 E8E4050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6003 00001DEA C3                  <1> 	RETn
  6004                              <1> 
  6005                              <1> ;----------------------------------------------------------------
  6006                              <1> ; DR_TYPE_CHECK							:
  6007                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  6008                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  6009                              <1> ; ON ENTRY:							:
  6010                              <1> ;	AL = DRIVE TYPE						:
  6011                              <1> ; ON EXIT:							:
  6012                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  6013                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  6014                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  6015                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  6016                              <1> ; REGISTERS ALTERED: eBX						:
  6017                              <1> ;----------------------------------------------------------------		
  6018                              <1> DR_TYPE_CHECK:
  6019 00001DEB 6650                <1> 	PUSH	AX			
  6020 00001DED 51                  <1> 	PUSH	eCX
  6021 00001DEE 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6022 00001DF0 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6023                              <1> TYPE_CHK:	
  6024 00001DF5 8AA3[DC6A0000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  6025 00001DFB 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6026 00001DFD 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  6027                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6028 00001DFF 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  6029 00001E02 E2F1                <1> 	LOOP    TYPE_CHK
  6030                              <1> 	;
  6031 00001E04 BB[3B6B0000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  6032                              <1> 					; Default for GET_PARM (11/12/2014)
  6033                              <1> 	;
  6034 00001E09 F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  6035 00001E0A EB06                <1> 	JMP	SHORT TYPE_RTN
  6036                              <1> DR_TYPE_VALID:
  6037 00001E0C 8B9B[DD6A0000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  6038                              <1> TYPE_RTN:
  6039 00001E12 59                  <1> 	POP	eCX
  6040 00001E13 6658                <1> 	POP	AX
  6041 00001E15 C3                  <1> 	RETn	
  6042                              <1> 		
  6043                              <1> ;----------------------------------------------------------------
  6044                              <1> ; SEND_SPEC							:
  6045                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6046                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  6047                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  6048                              <1> ; ON EXIT:	NONE						:	
  6049                              <1> ; REGISTERS ALTERED: CX, DX					:
  6050                              <1> ;----------------------------------------------------------------		
  6051                              <1> SEND_SPEC:
  6052 00001E16 50                  <1> 	PUSH	eAX			; SAVE AX
  6053 00001E17 B8[3D1E0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  6054 00001E1C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6055 00001E1D B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6056 00001E1F E884070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6057 00001E24 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  6058 00001E26 E877060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6059 00001E2B E878070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6060 00001E30 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  6061 00001E32 E86B060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6062 00001E37 E86C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6063 00001E3C 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6064                              <1> SPECBAC:
  6065 00001E3D 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6066 00001E3E C3                  <1> 	RETn
  6067                              <1> 
  6068                              <1> ;----------------------------------------------------------------
  6069                              <1> ; SEND_SPEC_MD							:
  6070                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6071                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  6072                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  6073                              <1> ; ON EXIT:	NONE						:	
  6074                              <1> ; REGISTERS ALTERED: AX						:
  6075                              <1> ;----------------------------------------------------------------		
  6076                              <1> SEND_SPEC_MD:
  6077 00001E3F 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  6078 00001E40 B8[5D1E0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  6079 00001E45 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6080 00001E46 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6081 00001E48 E85B070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6082 00001E4D 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  6083 00001E4F E854070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6084 00001E54 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  6085 00001E57 E84C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6086 00001E5C 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6087                              <1> SPEC_ESBAC:
  6088 00001E5D 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6089 00001E5E C3                  <1> 	RETn
  6090                              <1> 
  6091                              <1> ;-------------------------------------------------------------------------------
  6092                              <1> ; XLAT_NEW  
  6093                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  6094                              <1> ;	MODE TO NEW ARCHITECTURE.
  6095                              <1> ;
  6096                              <1> ; ON ENTRY:	DI = DRIVE #
  6097                              <1> ;-------------------------------------------------------------------------------
  6098                              <1> XLAT_NEW:
  6099 00001E5F 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  6100 00001E62 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  6101 00001E64 80BF[39710000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  6102 00001E6B 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  6103 00001E6D 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  6104 00001E70 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  6105 00001E73 A0[38710000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  6106 00001E78 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  6107 00001E7A 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  6108 00001E7C 80A7[39710000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  6109 00001E83 0887[39710000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  6110                              <1> XN_OUT:
  6111 00001E89 C3                  <1> 	RETn
  6112                              <1> DO_DET:
  6113 00001E8A E8BE080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  6114 00001E8F C3                  <1> 	RETn
  6115                              <1> 
  6116                              <1> ;-------------------------------------------------------------------------------
  6117                              <1> ; XLAT_OLD 
  6118                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  6119                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  6120                              <1> ;
  6121                              <1> ; ON ENTRY:	DI = DRIVE
  6122                              <1> ;-------------------------------------------------------------------------------
  6123                              <1> XLAT_OLD:
  6124 00001E90 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  6125                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  6126 00001E93 0F8786000000        <1>         ja      XO_OUT
  6127 00001E99 80BF[39710000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  6128 00001EA0 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  6129                              <1> 
  6130                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  6131                              <1> 
  6132 00001EA2 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  6133 00001EA5 C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  6134 00001EA8 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  6135 00001EAA D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  6136 00001EAC 8425[38710000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  6137 00001EB2 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  6138                              <1> 
  6139                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  6140                              <1> 
  6141 00001EB4 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  6142 00001EB6 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  6143 00001EB8 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  6144 00001EBA 2025[38710000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  6145                              <1> 
  6146                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  6147                              <1> 
  6148 00001EC0 8A87[39710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  6149 00001EC6 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  6150 00001EC8 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  6151 00001ECA 0805[38710000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  6152                              <1> 
  6153                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  6154                              <1> 
  6155                              <1> SAVE_SET:
  6156 00001ED0 8AA7[39710000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  6157 00001ED6 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  6158 00001ED8 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  6159 00001EDB 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  6160 00001EDE 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  6161 00001EE0 B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  6162 00001EE2 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  6163 00001EE5 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  6164 00001EE7 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  6165 00001EEA 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  6166                              <1> UNKNO:
  6167 00001EEC B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  6168 00001EEE EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  6169                              <1> CHK_144:
  6170 00001EF0 E8A4050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6171                              <1> 	;;20/02/2015
  6172                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  6173 00001EF5 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  6174 00001EF7 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  6175 00001EF9 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  6176 00001EFB B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  6177 00001EFD EB0C                <1> 	JMP	SHORT TST_DET
  6178                              <1> CHK_250:
  6179 00001EFF B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  6180 00001F01 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  6181 00001F04 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  6182 00001F06 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  6183 00001F09 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  6184                              <1> TST_DET:
  6185 00001F0B F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  6186 00001F0E 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  6187 00001F10 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  6188                              <1> AL_SET:
  6189 00001F12 80A7[39710000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  6190 00001F19 0887[39710000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  6191                              <1> XO_OUT:
  6192 00001F1F C3                  <1> 	RETn
  6193                              <1> 
  6194                              <1> ;-------------------------------------------------------------------------------
  6195                              <1> ; RD_WR_VF
  6196                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  6197                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  6198                              <1> ;
  6199                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  6200                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  6201                              <1> ;
  6202                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6203                              <1> ;-------------------------------------------------------------------------------
  6204                              <1> RD_WR_VF:
  6205 00001F20 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  6206 00001F22 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6207 00001F27 E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  6208 00001F2C 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  6209                              <1> DO_AGAIN:
  6210 00001F2E 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6211 00001F30 E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  6212 00001F35 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  6213 00001F37 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  6214                              <1> RWV:
  6215 00001F3D 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6216 00001F3F 8AB7[39710000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6217 00001F45 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  6218 00001F48 E84C050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  6219                              <1> 	;;20/02/2015
  6220                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  6221 00001F4D 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  6222 00001F4F 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  6223 00001F51 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  6224 00001F53 F687[39710000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  6225 00001F5A 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  6226 00001F5C B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  6227 00001F5E EB0F                <1> 	JMP	SHORT RWV_2
  6228                              <1> RWV_1:
  6229 00001F60 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  6230 00001F62 F687[39710000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  6231 00001F69 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  6232 00001F6B B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  6233 00001F6D EB04                <1> 	jmp	short rwv_3
  6234                              <1> RWV_2:
  6235 00001F6F 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  6236 00001F71 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  6237                              <1> rwv_3:
  6238 00001F73 E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  6239 00001F78 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  6240                              <1> 
  6241                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  6242                              <1> 
  6243 00001F7A 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  6244 00001F7B 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6245 00001F7D B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6246                              <1> RWV_DR_SEARCH:
  6247 00001F82 8AA3[DC6A0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  6248 00001F88 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  6249 00001F8B 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6250 00001F8D 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  6251                              <1> RWV_DR_FND:
  6252 00001F8F 8BBB[DD6A0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  6253                              <1> RWV_MD_SEARH:
  6254 00001F95 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  6255 00001F98 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  6256                              <1> RWV_NXT_MD:
  6257                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6258 00001F9A 83C305              <1> 	add	eBX, 5
  6259 00001F9D E2E3                <1> 	LOOP	RWV_DR_SEARCH
  6260 00001F9F 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6261                              <1> 
  6262                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  6263                              <1> 
  6264                              <1> RWV_ASSUME:
  6265 00001FA0 BB[FA6A0000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  6266 00001FA5 F687[39710000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  6267 00001FAC 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  6268 00001FAE BB[146B0000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  6269 00001FB3 EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  6270                              <1> 
  6271                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  6272                              <1> 	 			
  6273                              <1> RWV_MD_FND:
  6274 00001FB5 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  6275 00001FB7 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6276                              <1> 	
  6277                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  6278                              <1> 
  6279                              <1> RWV_MD_FND1:
  6280 00001FB8 E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  6281 00001FBD E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  6282 00001FC2 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  6283 00001FC4 E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  6284                              <1> RWV_DBL:
  6285 00001FC9 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6286 00001FCA E821040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  6287 00001FCF 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6288 00001FD0 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  6289 00001FD2 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  6290 00001FD4 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6291 00001FD6 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6292 00001FD7 E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  6293 00001FDC 5B                  <1> 	POP	eBX 
  6294 00001FDD 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  6295 00001FDF 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  6296 00001FE1 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6297 00001FE3 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6298 00001FE4 E83B020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  6299 00001FE9 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6300 00001FEA 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6301 00001FEC E865020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  6302 00001FF1 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6303 00001FF3 E8AA020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  6304                              <1> CHK_RET:
  6305 00001FF8 E849030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  6306 00001FFD 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  6307 00001FFF 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  6308 00002001 E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  6309                              <1> RWV_END:
  6310 00002006 E8F3020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  6311 0000200B E886030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  6312                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  6313 00002010 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  6314 00002012 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6315 00002017 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  6316 00002019 E8B0030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6317 0000201E C3                  <1> 	RETn
  6318                              <1> 
  6319                              <1> ;-------------------------------------------------------------------------------
  6320                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  6321                              <1> ;-------------------------------------------------------------------------------
  6322                              <1> SETUP_STATE:
  6323 0000201F F687[39710000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  6324 00002026 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  6325 00002028 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  6326 0000202C F687[39710000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  6327 00002033 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  6328 00002035 F687[39710000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  6329 0000203C 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  6330 0000203E 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  6331                              <1> AX_SET:	
  6332 00002042 80A7[39710000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  6333 00002049 08A7[39710000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  6334 0000204F 8025[34710000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  6335 00002056 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  6336 00002059 0805[34710000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  6337                              <1> J1C:	
  6338 0000205F C3                  <1> 	RETn
  6339                              <1> 
  6340                              <1> ;-------------------------------------------------------------------------------
  6341                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  6342                              <1> ;-------------------------------------------------------------------------------
  6343                              <1> FMT_INIT:
  6344 00002060 F687[39710000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  6345 00002067 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  6346 00002069 E82B040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  6347                              <1> 	;; 20/02/2015
  6348                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  6349 0000206E 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  6350 00002070 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  6351                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  6352 00002072 8AA7[39710000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  6353 00002078 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  6354 0000207B 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  6355 0000207D 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  6356 0000207F 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  6357 00002082 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6358                              <1> N_360:	
  6359 00002084 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  6360 00002086 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  6361                              <1> F1_RATE:
  6362 00002088 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  6363 0000208B EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6364                              <1> N_12:	
  6365 0000208D FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  6366 0000208F 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  6367 00002091 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  6368 00002094 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  6369 00002096 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  6370 00002099 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  6371 0000209B 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  6372 0000209E EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  6373                              <1> N_720:
  6374 000020A0 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  6375 000020A2 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  6376 000020A4 EBE2                <1> 	JMP	SHORT F1_RATE
  6377                              <1> ISNT_12: 
  6378 000020A6 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  6379                              <1> 
  6380                              <1> SKP_STATE:
  6381 000020A9 88A7[39710000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  6382                              <1> F1_OUT:
  6383 000020AF C3                  <1> 	RETn
  6384                              <1> CL_DRV:	
  6385 000020B0 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  6386 000020B2 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  6387                              <1> 
  6388                              <1> ;-------------------------------------------------------------------------------
  6389                              <1> ; MED_CHANGE	
  6390                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  6391                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  6392                              <1> ;
  6393                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  6394                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  6395                              <1> ;-------------------------------------------------------------------------------
  6396                              <1> MED_CHANGE:
  6397 000020B4 E887060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  6398 000020B9 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  6399 000020BB 80A7[39710000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  6400                              <1> 
  6401                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  6402                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  6403                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  6404                              <1> 
  6405 000020C2 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  6406 000020C5 B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  6407 000020C7 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  6408 000020C9 F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  6409 000020CB FA                  <1> 	CLI				; NO INTERRUPTS
  6410 000020CC 2005[2A710000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  6411 000020D2 FB                  <1> 	STI				; INTERRUPTS ENABLED
  6412 000020D3 E80F040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  6413                              <1> 
  6414                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  6415                              <1> 
  6416 000020D8 E884F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  6417 000020DD B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  6418 000020DF E8FE040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6419 000020E4 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  6420 000020E6 E8F7040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6421 000020EB C605[2C710000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  6422                              <1> OK1:
  6423 000020F2 E849060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  6424 000020F7 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  6425                              <1> OK4:
  6426 000020F9 C605[2C710000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  6427                              <1> OK2:		
  6428 00002100 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  6429 00002101 C3                  <1> 	RETn
  6430                              <1> MC_OUT:
  6431 00002102 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  6432 00002103 C3                  <1> 	RETn
  6433                              <1> 
  6434                              <1> ;-------------------------------------------------------------------------------
  6435                              <1> ; SEND_RATE
  6436                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  6437                              <1> ; ON ENTRY:	DI = DRIVE #
  6438                              <1> ; ON EXIT:	NONE
  6439                              <1> ; REGISTERS ALTERED: DX
  6440                              <1> ;-------------------------------------------------------------------------------
  6441                              <1> SEND_RATE:
  6442 00002104 6650                <1> 	PUSH	AX			; SAVE REG.
  6443 00002106 8025[34710000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  6444 0000210D 8A87[39710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6445 00002113 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  6446 00002115 0805[34710000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  6447 0000211B C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  6448 0000211E 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  6449 00002122 EE                  <1> 	OUT	DX,AL
  6450 00002123 6658                <1> 	POP	AX			; RESTORE REG.
  6451 00002125 C3                  <1> 	RETn
  6452                              <1> 
  6453                              <1> ;-------------------------------------------------------------------------------
  6454                              <1> ; CHK_LASTRATE
  6455                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  6456                              <1> ; ON ENTRY:
  6457                              <1> ;	DI = DRIVE #
  6458                              <1> ; ON EXIT:
  6459                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  6460                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  6461                              <1> ; REGISTERS ALTERED: DX
  6462                              <1> ;-------------------------------------------------------------------------------
  6463                              <1> CHK_LASTRATE:
  6464 00002126 6650                <1> 	PUSH	AX			; SAVE REG
  6465 00002128 2225[34710000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  6466 0000212E 8A87[39710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6467 00002134 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  6468 00002138 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  6469                              <1> 					; ZF = 1 RATE IS THE SAME
  6470 0000213A 6658                <1> 	POP	AX			; RESTORE REG.
  6471 0000213C C3                  <1> 	RETn
  6472                              <1> 
  6473                              <1> ;-------------------------------------------------------------------------------
  6474                              <1> ; DMA_SETUP
  6475                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  6476                              <1> ;
  6477                              <1> ; ON ENTRY:	AL = DMA COMMAND
  6478                              <1> ;
  6479                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6480                              <1> ;-------------------------------------------------------------------------------
  6481                              <1> 
  6482                              <1> ; SI = Head #, # of Sectors or DASD Type
  6483                              <1> 
  6484                              <1> ; 22/08/2015
  6485                              <1> ; 08/02/2015 - Protected Mode Modification
  6486                              <1> ; 06/02/2015 - 07/02/2015
  6487                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  6488                              <1> ; (DMA Addres = Physical Address)
  6489                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  6490                              <1> ;
  6491                              <1> 
  6492                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  6493                              <1> ; 16/12/2014 (IODELAY)
  6494                              <1> 
  6495                              <1> DMA_SETUP:
  6496                              <1> ;; 20/02/2015
  6497 0000213D 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6498 00002140 F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  6499 00002146 756D                <1> 	jnz	short dma_bnd_err_stc
  6500                              <1> 	;
  6501 00002148 6650                <1> 	push	ax			; DMA command
  6502 0000214A 52                  <1> 	push	edx			; *
  6503 0000214B B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  6504 0000214D E850030000          <1> 	call	GET_PARM		; 
  6505 00002152 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6506 00002154 6689F0              <1> 	mov	ax, si			; Sector count
  6507 00002157 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  6508 00002159 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  6509 0000215B 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  6510 0000215E 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  6511 00002161 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  6512 00002163 6689C1              <1> 	mov	cx, ax
  6513 00002166 5A                  <1> 	pop	edx			; *
  6514 00002167 6658                <1> 	pop	ax
  6515 00002169 3C42                <1> 	cmp	al, 42h
  6516 0000216B 7507                <1>         jne     short NOT_VERF
  6517 0000216D BA0000FF00          <1> 	mov	edx, 0FF0000h
  6518 00002172 EB08                <1> 	jmp	short J33
  6519                              <1> NOT_VERF:
  6520 00002174 6601CA              <1> 	add	dx, cx			; check for overflow
  6521 00002177 723D                <1> 	jc	short dma_bnd_err
  6522                              <1> 	;
  6523 00002179 6629CA              <1> 	sub	dx, cx			; Restore start address
  6524                              <1> J33:
  6525 0000217C FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6526 0000217D E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6527                              <1> 	IODELAY				; WAIT FOR I/O
  6528 0000217F EB00                <2>  jmp short $+2
  6529 00002181 EB00                <2>  jmp short $+2
  6530 00002183 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6531 00002185 89D0                <1> 	mov	eax, edx		; Buffer address
  6532 00002187 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6533                              <1> 	IODELAY				; WAIT FOR I/O
  6534 00002189 EB00                <2>  jmp short $+2
  6535 0000218B EB00                <2>  jmp short $+2
  6536 0000218D 88E0                <1> 	MOV	AL,AH
  6537 0000218F E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6538 00002191 C1E810              <1> 	shr	eax, 16
  6539                              <1> 	IODELAY				; I/O WAIT STATE
  6540 00002194 EB00                <2>  jmp short $+2
  6541 00002196 EB00                <2>  jmp short $+2
  6542 00002198 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6543                              <1> 	IODELAY
  6544 0000219A EB00                <2>  jmp short $+2
  6545 0000219C EB00                <2>  jmp short $+2
  6546 0000219E 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  6547 000021A1 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6548                              <1> 	IODELAY				; WAIT FOR I/O
  6549 000021A3 EB00                <2>  jmp short $+2
  6550 000021A5 EB00                <2>  jmp short $+2
  6551 000021A7 88E0                <1> 	MOV	AL, AH
  6552 000021A9 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6553                              <1> 	IODELAY
  6554 000021AB EB00                <2>  jmp short $+2
  6555 000021AD EB00                <2>  jmp short $+2
  6556 000021AF FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6557 000021B0 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  6558 000021B2 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6559 000021B4 C3                  <1> 	retn
  6560                              <1> dma_bnd_err_stc:
  6561 000021B5 F9                  <1> 	stc
  6562                              <1> dma_bnd_err:
  6563 000021B6 C605[2C710000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6564 000021BD C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  6565                              <1> 
  6566                              <1> ;; 16/12/2014
  6567                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6568                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6569                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6570                              <1> ;;	IODELAY
  6571                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6572                              <1> ;;	;SIODELAY
  6573                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  6574                              <1> ;;      ;JNE	short NOT_VERF		; NO
  6575                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  6576                              <1> ;;      ;JMP	SHORT J33
  6577                              <1> ;;;NOT_VERF:	
  6578                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  6579                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  6580                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  6581                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  6582                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  6583                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  6584                              <1> ;;	;JNC	short J33
  6585                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  6586                              <1> ;;;J33:
  6587                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  6588                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6589                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6590                              <1> ;;	IODELAY
  6591                              <1> ;;	MOV	AL,AH
  6592                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6593                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  6594                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  6595                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  6596                              <1> ;;	IODELAY
  6597                              <1> ;;	;AND	AL,00001111B
  6598                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  6599                              <1> ;;	;SIODELAY
  6600                              <1> ;;
  6601                              <1> ;;;----- DETERMINE COUNT
  6602                              <1> ;;	sub	eax, eax ; 08/02/2015
  6603                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  6604                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  6605                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  6606                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  6607                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  6608                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  6609                              <1> ;;	CALL	GET_PARM		; "
  6610                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6611                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  6612                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  6613                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  6614                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  6615                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6616                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6617                              <1> ;;	IODELAY
  6618                              <1> ;;	MOV	AL, AH
  6619                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6620                              <1> ;;	;IODELAY
  6621                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  6622                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  6623                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  6624                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  6625                              <1> ;;	add	ecx, eax ; 08/02/2015
  6626                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  6627                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6628                              <1> ;;	SIODELAY
  6629                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6630                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  6631                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  6632                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  6633                              <1> ;;	jz	short NO_BAD
  6634                              <1> ;;dma_bnd_err:
  6635                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6636                              <1> ;;NO_BAD:
  6637                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  6638                              <1> 
  6639                              <1> ;-------------------------------------------------------------------------------
  6640                              <1> ; FMTDMA_SET
  6641                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  6642                              <1> ;
  6643                              <1> ; ON ENTRY:	NOTHING REQUIRED
  6644                              <1> ;
  6645                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6646                              <1> ;-------------------------------------------------------------------------------
  6647                              <1> 
  6648                              <1> FMTDMA_SET:
  6649                              <1> ;; 20/02/2015 modification	
  6650 000021BE 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6651 000021C1 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  6652 000021C7 75EC                <1> 	jnz	short dma_bnd_err_stc
  6653                              <1> 	;
  6654 000021C9 6652                <1> 	push	dx			; *
  6655 000021CB B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  6656 000021CD E8D0020000          <1> 	call	GET_PARM		; "
  6657 000021D2 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  6658 000021D4 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  6659 000021D6 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  6660 000021DA 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  6661 000021DC 6689C1              <1> 	mov	cx, ax
  6662 000021DF 665A                <1> 	pop	dx			; *
  6663 000021E1 6601CA              <1> 	add	dx, cx			; check for overflow
  6664 000021E4 72D0                <1> 	jc	short dma_bnd_err
  6665                              <1> 	;
  6666 000021E6 6629CA              <1> 	sub	dx, cx			; Restore start address
  6667                              <1> 	;
  6668 000021E9 B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  6669 000021EB FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6670 000021EC E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6671                              <1> 	IODELAY				; WAIT FOR I/O
  6672 000021EE EB00                <2>  jmp short $+2
  6673 000021F0 EB00                <2>  jmp short $+2
  6674 000021F2 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6675 000021F4 89D0                <1> 	mov	eax, edx		; Buffer address
  6676 000021F6 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6677                              <1> 	IODELAY				; WAIT FOR I/O
  6678 000021F8 EB00                <2>  jmp short $+2
  6679 000021FA EB00                <2>  jmp short $+2
  6680 000021FC 88E0                <1> 	MOV	AL,AH
  6681 000021FE E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6682 00002200 C1E810              <1> 	shr	eax, 16
  6683                              <1> 	IODELAY				; I/O WAIT STATE
  6684 00002203 EB00                <2>  jmp short $+2
  6685 00002205 EB00                <2>  jmp short $+2
  6686 00002207 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6687                              <1> 	IODELAY
  6688 00002209 EB00                <2>  jmp short $+2
  6689 0000220B EB00                <2>  jmp short $+2
  6690 0000220D 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  6691 00002210 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6692                              <1> 	IODELAY				; WAIT FOR I/O
  6693 00002212 EB00                <2>  jmp short $+2
  6694 00002214 EB00                <2>  jmp short $+2
  6695 00002216 88E0                <1> 	MOV	AL, AH
  6696 00002218 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6697                              <1> 	IODELAY
  6698 0000221A EB00                <2>  jmp short $+2
  6699 0000221C EB00                <2>  jmp short $+2
  6700 0000221E FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6701 0000221F B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  6702 00002221 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6703 00002223 C3                  <1> 	retn
  6704                              <1> 
  6705                              <1> ;; 08/02/2015 - Protected Mode Modification
  6706                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  6707                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6708                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6709                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6710                              <1> ;;	IODELAY
  6711                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6712                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  6713                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  6714                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  6715                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  6716                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  6717                              <1> ;;	;JNC	short J33A
  6718                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  6719                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  6720                              <1> ;;;J33A:
  6721                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  6722                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6723                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6724                              <1> ;;	IODELAY
  6725                              <1> ;;	MOV	AL,AH
  6726                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6727                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  6728                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  6729                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  6730                              <1> ;;	IODELAY
  6731                              <1> ;;	;AND	AL,00001111B
  6732                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  6733                              <1> ;;
  6734                              <1> ;;;----- DETERMINE COUNT
  6735                              <1> ;;	sub	eax, eax ; 08/02/2015
  6736                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  6737                              <1> ;;	CALL	GET_PARM		; "
  6738                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  6739                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  6740                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  6741                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  6742                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  6743                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6744                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6745                              <1> ;;	IODELAY
  6746                              <1> ;;	MOV	AL, AH
  6747                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6748                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  6749                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  6750                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  6751                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  6752                              <1> ;;	add	ecx, eax ; 08/02/2015
  6753                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  6754                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6755                              <1> ;;	SIODELAY
  6756                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6757                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  6758                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  6759                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  6760                              <1> ;;	jz	short FMTDMA_OK
  6761                              <1> ;;	stc	; 20/02/2015
  6762                              <1> ;;fmtdma_bnd_err:
  6763                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6764                              <1> ;;FMTDMA_OK:
  6765                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  6766                              <1> 
  6767                              <1> ;-------------------------------------------------------------------------------
  6768                              <1> ; NEC_INIT	
  6769                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  6770                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  6771                              <1> ;
  6772                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  6773                              <1> ;
  6774                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6775                              <1> ;-------------------------------------------------------------------------------
  6776                              <1> NEC_INIT:
  6777 00002224 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6778 00002226 E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  6779                              <1> 
  6780                              <1> ;-----	DO THE SEEK OPERATION
  6781                              <1> 
  6782 0000222B 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  6783 0000222E E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  6784 00002233 6658                <1> 	POP	AX			; RECOVER COMMAND
  6785 00002235 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  6786 00002237 BB[55220000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  6787 0000223C 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  6788                              <1> 
  6789                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  6790                              <1> 
  6791 0000223D E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  6792 00002242 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  6793 00002245 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  6794 00002247 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  6795 0000224A 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  6796 0000224D 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  6797 0000224F E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  6798 00002254 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  6799                              <1> ER_1:
  6800 00002255 C3                  <1> 	RETn
  6801                              <1> 
  6802                              <1> ;-------------------------------------------------------------------------------
  6803                              <1> ; RWV_COM
  6804                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  6805                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  6806                              <1> ;
  6807                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  6808                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6809                              <1> ;-------------------------------------------------------------------------------
  6810                              <1> RWV_COM:
  6811 00002256 B8[A1220000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  6812 0000225B 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6813 0000225C 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  6814 0000225F E844030000          <1> 	CALL	NEC_OUTPUT
  6815 00002264 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  6816 00002267 E83C030000          <1> 	CALL	NEC_OUTPUT
  6817 0000226C 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  6818 0000226F E834030000          <1> 	CALL	NEC_OUTPUT
  6819 00002274 B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  6820 00002276 E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  6821 0000227B E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6822 00002280 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  6823 00002282 E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  6824 00002287 E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6825 0000228C 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  6826                              <1> _R15:
  6827 0000228F E814030000          <1> 	CALL	NEC_OUTPUT
  6828 00002294 B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  6829 00002296 E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  6830 0000229B E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6831 000022A0 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  6832                              <1> ER_2:
  6833 000022A1 C3                  <1> 	RETn
  6834                              <1> 
  6835                              <1> ;-------------------------------------------------------------------------------
  6836                              <1> ; NEC_TERM
  6837                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  6838                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  6839                              <1> ;
  6840                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6841                              <1> ;-------------------------------------------------------------------------------
  6842                              <1> NEC_TERM:
  6843                              <1> 
  6844                              <1> ;-----	LET THE OPERATION HAPPEN
  6845                              <1> 
  6846 000022A2 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  6847 000022A3 E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  6848 000022A8 9C                  <1> 	PUSHF
  6849 000022A9 E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  6850 000022AE 724B                <1> 	JC	short SET_END_POP
  6851 000022B0 9D                  <1> 	POPF
  6852 000022B1 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  6853                              <1> 
  6854                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  6855                              <1> 
  6856 000022B3 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  6857 000022B4 BE[2D710000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  6858 000022B9 AC                  <1> 	lodsb				; GET ST0
  6859 000022BA 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  6860 000022BC 7433                <1> 	JZ	short SET_END
  6861 000022BE 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  6862 000022C0 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  6863                              <1> 
  6864                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  6865                              <1> 
  6866 000022C2 AC                  <1> 	lodsb				; GET ST1
  6867 000022C3 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  6868 000022C5 B404                <1> 	MOV	AH,RECORD_NOT_FND
  6869 000022C7 7222                <1> 	JC	short J19
  6870 000022C9 C0E002              <1> 	SAL	AL,2
  6871 000022CC B410                <1> 	MOV	AH,BAD_CRC
  6872 000022CE 721B                <1> 	JC	short J19
  6873 000022D0 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  6874 000022D2 B408                <1> 	MOV	AH,BAD_DMA
  6875 000022D4 7215                <1> 	JC	short J19
  6876 000022D6 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  6877 000022D9 B404                <1> 	MOV	AH,RECORD_NOT_FND
  6878 000022DB 720E                <1> 	JC	short J19
  6879 000022DD D0E0                <1> 	SAL	AL,1
  6880 000022DF B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  6881 000022E1 7208                <1> 	JC	short J19
  6882 000022E3 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  6883 000022E5 B402                <1> 	MOV	AH,BAD_ADDR_MARK
  6884 000022E7 7202                <1> 	JC	short J19
  6885                              <1> 
  6886                              <1> ;----- 	NEC MUST HAVE FAILED
  6887                              <1> J18:
  6888 000022E9 B420                <1> 	MOV	AH,BAD_NEC
  6889                              <1> J19:
  6890 000022EB 0825[2C710000]      <1> 	OR	[DSKETTE_STATUS], AH
  6891                              <1> SET_END:
  6892 000022F1 803D[2C710000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  6893 000022F8 F5                  <1> 	CMC
  6894 000022F9 5E                  <1> 	POP	eSI
  6895 000022FA C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  6896                              <1> 
  6897                              <1> SET_END_POP:
  6898 000022FB 9D                  <1> 	POPF
  6899 000022FC EBF3                <1> 	JMP	SHORT SET_END
  6900                              <1> 
  6901                              <1> ;-------------------------------------------------------------------------------
  6902                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  6903                              <1> ;-------------------------------------------------------------------------------
  6904                              <1> DSTATE:
  6905 000022FE 803D[2C710000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  6906 00002305 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  6907 00002307 808F[39710000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  6908 0000230E F687[39710000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  6909 00002315 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  6910 00002317 8A87[39710000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  6911 0000231D 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  6912 0000231F 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  6913 00002321 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  6914                              <1> 
  6915                              <1> ;----- 	CHECK IF IT IS 1.44M
  6916                              <1> 
  6917 00002323 E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6918                              <1> 	;;20/02/2015
  6919                              <1> 	;;JC	short M_12		; CMOS BAD
  6920 00002328 7414                <1> 	jz	short M_12 ;; 20/02/2015
  6921 0000232A 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  6922 0000232C 7410                <1> 	JE	short M_12		; YES
  6923                              <1> M_720:
  6924 0000232E 80A7[39710000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  6925 00002335 808F[39710000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  6926 0000233C EB07                <1> 	JMP	SHORT SETBAC		; BACK
  6927                              <1> M_12:	
  6928 0000233E 808F[39710000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  6929                              <1> 					; TURN ON DETERMINED & FMT CAPA
  6930                              <1> SETBAC:
  6931 00002345 C3                  <1> 	RETn
  6932                              <1> 
  6933                              <1> ;-------------------------------------------------------------------------------
  6934                              <1> ; RETRY	
  6935                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  6936                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  6937                              <1> ;
  6938                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  6939                              <1> ;-------------------------------------------------------------------------------
  6940                              <1> RETRY:
  6941 00002346 803D[2C710000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  6942 0000234D 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  6943 0000234F 803D[2C710000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  6944 00002356 743C                <1> 	JZ	short NO_RETRY
  6945 00002358 8AA7[39710000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  6946 0000235E F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  6947 00002361 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  6948 00002363 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  6949 00002366 8A2D[34710000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  6950 0000236C C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  6951 0000236F 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  6952 00002372 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  6953 00002374 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  6954                              <1> 
  6955                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  6956                              <1> ;	 00000000B (500) -> 10000000B	(250)
  6957                              <1> ;	 10000000B (250) -> 01000000B	(300)
  6958                              <1> ;	 01000000B (300) -> 00000000B	(500)
  6959                              <1> 
  6960 00002376 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  6961 00002379 D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  6962 0000237B 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  6963 0000237E 80A7[39710000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  6964                              <1> 					; RATE, DBL STEP OFF
  6965 00002385 08A7[39710000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  6966 0000238B C605[2C710000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  6967 00002392 F9                  <1> 	STC				; SET CARRY FOR RETRY
  6968 00002393 C3                  <1> 	RETn				; RETRY RETURN
  6969                              <1> 
  6970                              <1> NO_RETRY:
  6971 00002394 F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  6972 00002395 C3                  <1> 	RETn				; NO RETRY RETURN
  6973                              <1> 
  6974                              <1> ;-------------------------------------------------------------------------------
  6975                              <1> ; NUM_TRANS
  6976                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  6977                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  6978                              <1> ;
  6979                              <1> ; ON ENTRY:	[BP+1] = TRACK
  6980                              <1> ;		SI-HI  = HEAD
  6981                              <1> ;		[BP]   = START SECTOR
  6982                              <1> ;
  6983                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  6984                              <1> ;-------------------------------------------------------------------------------
  6985                              <1> NUM_TRANS:
  6986 00002396 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  6987 00002398 803D[2C710000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  6988 0000239F 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  6989 000023A1 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  6990 000023A3 E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  6991 000023A8 8A1D[32710000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  6992 000023AE 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  6993 000023B1 3A2D[31710000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  6994 000023B7 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  6995 000023B9 8A2D[30710000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  6996 000023BF 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  6997 000023C2 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  6998 000023C4 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  6999                              <1> DIF_HD:
  7000 000023C6 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7001                              <1> SAME_TRK:
  7002 000023C8 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  7003 000023CB 88D8                <1> 	MOV	AL,BL			; TO AL
  7004                              <1> NT_OUT:
  7005 000023CD C3                  <1> 	RETn
  7006                              <1> 
  7007                              <1> ;-------------------------------------------------------------------------------
  7008                              <1> ; SETUP_END
  7009                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  7010                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  7011                              <1> ;
  7012                              <1> ; ON EXIT:
  7013                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7014                              <1> ;-------------------------------------------------------------------------------
  7015                              <1> SETUP_END:
  7016 000023CE B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  7017 000023D0 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  7018 000023D2 E8CB000000          <1> 	CALL	GET_PARM
  7019 000023D7 8825[2B710000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  7020 000023DD 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  7021 000023DF 8A25[2C710000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  7022 000023E5 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  7023 000023E7 7402                <1> 	JZ	short NUN_ERR			; NO ERROR
  7024 000023E9 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  7025                              <1> NUN_ERR: 
  7026 000023EB 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  7027 000023EE F5                  <1> 	CMC				; SUCCESS OR FAILURE
  7028 000023EF C3                  <1> 	RETn
  7029                              <1> 
  7030                              <1> ;-------------------------------------------------------------------------------
  7031                              <1> ; SETUP_DBL
  7032                              <1> ;	CHECK DOUBLE STEP.
  7033                              <1> ;
  7034                              <1> ; ON ENTRY :	DI = DRIVE
  7035                              <1> ;
  7036                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  7037                              <1> ;-------------------------------------------------------------------------------
  7038                              <1> SETUP_DBL:
  7039 000023F0 8AA7[39710000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  7040 000023F6 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  7041 000023F9 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  7042                              <1> 
  7043                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  7044                              <1> 
  7045 000023FB C605[29710000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  7046 00002402 E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  7047 00002407 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  7048 00002409 E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  7049 0000240E E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  7050 00002413 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  7051                              <1> 
  7052                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  7053                              <1> 
  7054 00002415 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  7055 00002419 F687[39710000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  7056 00002420 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  7057 00002422 B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  7058                              <1> 
  7059                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  7060                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  7061                              <1> ;	THEN SET DOUBLE STEP ON.
  7062                              <1> 
  7063                              <1> CNT_OK:
  7064 00002424 C605[2B710000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  7065 0000242B 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  7066 0000242D C605[2C710000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  7067 00002434 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  7068 00002437 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  7069 00002439 C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  7070 0000243C 6650                <1> 	PUSH	AX			; SAVE HEAD
  7071 0000243E E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  7072 00002443 6658                <1> 	POP	AX			; RESTORE HEAD
  7073 00002445 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  7074 00002448 E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  7075 0000244D 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  7076 0000244E 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  7077 00002453 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  7078 00002454 6659                <1> 	POP	CX			; RESTORE COUNT
  7079 00002456 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  7080 00002458 FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  7081 0000245A 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  7082 0000245C 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  7083                              <1> 
  7084                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  7085                              <1> 
  7086                              <1> SD_ERR:	
  7087 0000245E F9                  <1> 	STC				; SET CARRY FOR ERROR
  7088 0000245F C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  7089                              <1> 
  7090                              <1> DO_CHK:
  7091 00002460 8A0D[30710000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  7092 00002466 888F[3D710000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  7093 0000246C D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  7094 0000246E 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  7095 00002470 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  7096 00002472 808F[39710000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  7097                              <1> NO_DBL:
  7098 00002479 F8                  <1> 	CLC				; CLEAR ERROR FLAG
  7099 0000247A C3                  <1> 	RETn
  7100                              <1> 
  7101                              <1> ;-------------------------------------------------------------------------------
  7102                              <1> ; READ_ID
  7103                              <1> ;	READ ID FUNCTION.
  7104                              <1> ;
  7105                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  7106                              <1> ;
  7107                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  7108                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7109                              <1> ;-------------------------------------------------------------------------------
  7110                              <1> READ_ID:
  7111 0000247B B8[98240000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  7112 00002480 50                  <1> 	PUSH	eAX
  7113 00002481 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  7114 00002483 E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7115 00002488 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  7116 0000248B 88C4                <1> 	MOV	AH,AL
  7117 0000248D E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7118 00002492 E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  7119 00002497 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  7120                              <1> ER_3:
  7121 00002498 C3                  <1> 	RETn
  7122                              <1> 
  7123                              <1> ;-------------------------------------------------------------------------------
  7124                              <1> ; CMOS_TYPE
  7125                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  7126                              <1> ;
  7127                              <1> ; ON ENTRY:	DI = DRIVE #
  7128                              <1> ;
  7129                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  7130                              <1> ;-------------------------------------------------------------------------------
  7131                              <1> 
  7132                              <1> CMOS_TYPE: ; 11/12/2014
  7133 00002499 8A87[D86D0000]      <1> mov	al, [eDI+fd0_type]
  7134 0000249F 20C0                <1> and 	al, al ; 18/12/2014
  7135 000024A1 C3                  <1> retn
  7136                              <1> 
  7137                              <1> ;CMOS_TYPE:
  7138                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  7139                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  7140                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  7141                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  7142                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  7143                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  7144                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  7145                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  7146                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  7147                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  7148                              <1> ;TB:
  7149                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  7150                              <1> ;BAD_CM:
  7151                              <1> ;	RETn				; CY, STATUS OF READ
  7152                              <1> 
  7153                              <1> ;-------------------------------------------------------------------------------
  7154                              <1> ; GET_PARM
  7155                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  7156                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  7157                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  7158                              <1> ;	THE PARAMETER IN DL.
  7159                              <1> ;
  7160                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  7161                              <1> ;
  7162                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  7163                              <1> ;		AL,DH DESTROYED
  7164                              <1> ;-------------------------------------------------------------------------------
  7165                              <1> GET_PARM:
  7166                              <1> 	;PUSH	DS
  7167 000024A2 56                  <1> 	PUSH	eSI
  7168                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  7169                              <1>     	;MOV	DS,AX
  7170                              <1> 	;;mov	ax, cs
  7171                              <1> 	;;mov	ds, ax
  7172                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  7173 000024A3 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  7174                              <1> 	;SUB	BH,BH			; BX = INDEX
  7175 000024A5 81E3FF000000        <1> 	and	ebx, 0FFh
  7176                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  7177                              <1> 	;
  7178                              <1> 	; 17/12/2014
  7179 000024AB 66A1[516B0000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  7180 000024B1 38E0                <1> 	cmp	al, ah
  7181 000024B3 7425                <1> 	je	short gpndc
  7182 000024B5 A2[526B0000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  7183 000024BA 53                  <1> 	push	ebx ; 08/02/2015
  7184 000024BB 88C3                <1> 	mov	bl, al 
  7185                              <1> 	; 11/12/2014
  7186 000024BD 8A83[D86D0000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  7187                              <1> 	; 18/12/2014
  7188 000024C3 20C0                <1> 	and	al, al
  7189 000024C5 7507                <1> 	jnz	short gpdtc
  7190 000024C7 BB[3B6B0000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  7191 000024CC EB05                <1>         jmp     short gpdpu
  7192                              <1> gpdtc:	
  7193 000024CE E818F9FFFF          <1> 	call	DR_TYPE_CHECK
  7194                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  7195                              <1> gpdpu:
  7196 000024D3 891D[D86A0000]      <1> 	mov	[DISK_POINTER], ebx
  7197 000024D9 5B                  <1> 	pop	ebx
  7198                              <1> gpndc:
  7199 000024DA 8B35[D86A0000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  7200 000024E0 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  7201 000024E3 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  7202 000024E5 5E                  <1> 	POP	eSI
  7203                              <1> 	;POP	DS
  7204 000024E6 C3                  <1> 	RETn
  7205                              <1> 
  7206                              <1> ;-------------------------------------------------------------------------------
  7207                              <1> ; MOTOR_ON
  7208                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  7209                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  7210                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  7211                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  7212                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  7213                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  7214                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  7215                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  7216                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  7217                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  7218                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  7219                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  7220                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  7221                              <1> ;
  7222                              <1> ; ON ENTRY:	DI = DRIVE #
  7223                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  7224                              <1> ;-------------------------------------------------------------------------------
  7225                              <1> MOTOR_ON:
  7226 000024E7 53                  <1> 	PUSH	eBX			; SAVE REG.
  7227 000024E8 E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  7228 000024ED 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  7229 000024EF E89CF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7230 000024F4 E866F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  7231                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  7232                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  7233                              <1> M_WAIT:
  7234 000024F9 B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  7235 000024FB E8A2FFFFFF          <1> 	CALL	GET_PARM
  7236                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  7237                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  7238                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  7239 00002500 80FC08              <1> 	cmp	ah, 8
  7240                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  7241 00002503 7702                <1> 	ja	short J13
  7242                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  7243 00002505 B408                <1> 	mov	ah, 8
  7244                              <1> 
  7245                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  7246                              <1> GP2:	
  7247                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  7248                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  7249 00002507 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  7250 0000250C E81BF1FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  7251                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  7252 00002511 FECC                <1> 	dec	ah
  7253 00002513 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  7254                              <1> MOT_IS_ON:
  7255 00002515 5B                  <1> 	POP	eBX			; RESTORE REG.
  7256 00002516 C3                  <1> 	RETn
  7257                              <1> 
  7258                              <1> ;-------------------------------------------------------------------------------
  7259                              <1> ; TURN_ON
  7260                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  7261                              <1> ;
  7262                              <1> ; ON ENTRY:	DI = DRIVE #
  7263                              <1> ;
  7264                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  7265                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  7266                              <1> ;		AX,BX,CX,DX DESTROYED
  7267                              <1> ;-------------------------------------------------------------------------------
  7268                              <1> TURN_ON:
  7269 00002517 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7270 00002519 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  7271 0000251B C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  7272 0000251E FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  7273 0000251F C605[2B710000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  7274 00002526 A0[2A710000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7275 0000252B 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  7276 0000252D B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  7277 0000252F D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  7278                              <1> 
  7279                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  7280                              <1> ;  BL = DRIVE SELECT DESIRED
  7281                              <1> ;  AH = MOTOR ON MASK DESIRED
  7282                              <1> 
  7283 00002531 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  7284 00002533 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  7285 00002535 8425[2A710000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  7286 0000253B 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  7287                              <1> 
  7288                              <1> TURN_IT_ON:
  7289 0000253D 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  7290 0000253F 8A3D[2A710000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  7291 00002545 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  7292 00002548 8025[2A710000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  7293 0000254F 0825[2A710000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  7294 00002555 A0[2A710000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7295 0000255A 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  7296 0000255C 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  7297 0000255F FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  7298 00002560 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  7299 00002562 C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  7300 00002565 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  7301 00002567 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  7302 0000256B EE                  <1> 	OUT	DX,AL
  7303 0000256C 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  7304                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  7305 0000256E 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  7306 00002570 F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  7307 00002571 C3                  <1> 	RETn
  7308                              <1> 
  7309                              <1> NO_MOT_WAIT:
  7310 00002572 FB                  <1> 	sti
  7311                              <1> no_mot_w1: ; 27/02/2015
  7312 00002573 F9                  <1> 	STC				; SET NO WAIT REQUIRED
  7313                              <1> 	;STI				; INTERRUPTS BACK ON
  7314 00002574 C3                  <1> 	RETn
  7315                              <1> 
  7316                              <1> ;-------------------------------------------------------------------------------
  7317                              <1> ; HD_WAIT
  7318                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  7319                              <1> ;
  7320                              <1> ; ON ENTRY:	DI = DRIVE #
  7321                              <1> ;
  7322                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  7323                              <1> ;-------------------------------------------------------------------------------
  7324                              <1> HD_WAIT:
  7325 00002575 B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  7326 00002577 E826FFFFFF          <1> 	CALL	GET_PARM
  7327 0000257C 08E4                <1> 	or	ah, ah	; 17/12/2014
  7328 0000257E 7519                <1> 	jnz	short DO_WAT
  7329 00002580 F605[2A710000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  7330                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  7331                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  7332                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  7333 00002587 741E                <1> 	jz	short HW_DONE
  7334 00002589 B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  7335 0000258B 8A87[39710000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  7336 00002591 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  7337 00002593 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  7338 00002595 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  7339                              <1> ;GP3:
  7340 00002597 B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  7341                              <1> ;	JMP	SHORT DO_WAT
  7342                              <1> 
  7343                              <1> ;ISNT_WRITE:
  7344                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  7345                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  7346                              <1> 
  7347                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  7348                              <1> DO_WAT:
  7349                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  7350                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  7351                              <1> J29:					; 	1 MILLISECOND LOOP
  7352                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  7353 00002599 B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  7354 0000259E E889F0FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  7355                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  7356 000025A3 FECC                <1> 	dec	ah
  7357 000025A5 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  7358                              <1> HW_DONE:
  7359 000025A7 C3                  <1> 	RETn
  7360                              <1> 
  7361                              <1> ;-------------------------------------------------------------------------------
  7362                              <1> ; NEC_OUTPUT
  7363                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  7364                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  7365                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  7366                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  7367                              <1> ; 
  7368                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  7369                              <1> ;
  7370                              <1> ; ON EXIT:	CY = 0  SUCCESS
  7371                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  7372                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  7373                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  7374                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  7375                              <1> ;		AX,CX,DX DESTROYED
  7376                              <1> ;-------------------------------------------------------------------------------
  7377                              <1> 
  7378                              <1> ; 09/12/2014 [Erdogan Tan] 
  7379                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  7380                              <1> ; Diskette Drive Controller Status Register (3F4h)
  7381                              <1> ;	This read only register facilitates the transfer of data between
  7382                              <1> ;	the system microprocessor and the controller.
  7383                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  7384                              <1> ;	  with the system micrprocessor.
  7385                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  7386                              <1> ;	  the transfer is to the controller.
  7387                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  7388                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  7389                              <1> ; Bit 3 - Reserved.
  7390                              <1> ; Bit 2 - Reserved.
  7391                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7392                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7393                              <1> 
  7394                              <1> ; Data Register (3F5h)
  7395                              <1> ; This read/write register passes data, commands and parameters, and provides
  7396                              <1> ; diskette status information.
  7397                              <1>   		
  7398                              <1> NEC_OUTPUT:
  7399                              <1> 	;PUSH	BX			; SAVE REG.
  7400 000025A8 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  7401                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  7402                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  7403                              <1> 	; 16/12/2014
  7404                              <1> 	; waiting for (max.) 0.5 seconds
  7405                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  7406                              <1> 	;
  7407                              <1> 	; 17/12/2014
  7408                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  7409                              <1> 	;
  7410                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  7411                              <1> 	;		go on.
  7412                              <1> 	;INPUT:
  7413                              <1> 	;	AH=Mask for isolation bits.
  7414                              <1> 	;	AL=pattern to look for.
  7415                              <1> 	;	DX=Port to test for
  7416                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7417                              <1> 	;	     (normally 30 microseconds per period.)
  7418                              <1> 	;
  7419                              <1> 	;WFP_SHORT:  
  7420                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  7421                              <1> 	;
  7422                              <1> 
  7423                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  7424                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  7425 000025AC B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  7426                              <1> ;
  7427                              <1> ;WFPS_OUTER_LP:
  7428                              <1> ;	;
  7429                              <1> ;WFPS_CHECK_PORT:
  7430                              <1> J23:
  7431 000025B1 EC                  <1> 	IN	AL,DX			; GET STATUS
  7432 000025B2 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7433 000025B4 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7434 000025B6 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  7435                              <1> WFPS_HI:
  7436 000025B8 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  7437 000025BA A810                <1> 	TEST	AL,010H			; transition on memory
  7438 000025BC 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  7439                              <1> WFPS_LO:
  7440 000025BE E461                <1> 	IN	AL, PORT_B		; SYS1
  7441 000025C0 A810                <1> 	TEST	AL,010H
  7442 000025C2 74FA                <1> 	JZ	SHORT WFPS_LO
  7443                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  7444 000025C4 E2EB                <1> 	loop	J23	; 27/02/2015
  7445                              <1> ;	;
  7446                              <1> ;	dec	bl
  7447                              <1> ;	jnz	short WFPS_OUTER_LP
  7448                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  7449                              <1> ;J23:
  7450                              <1> ;	IN	AL,DX			; GET STATUS
  7451                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7452                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7453                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  7454                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  7455                              <1> 	;DEC	BL			; DECREMENT COUNTER
  7456                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  7457                              <1>    
  7458                              <1> 	;;27/02/2015
  7459                              <1> 	;16/12/2014
  7460                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  7461                              <1> 	;;jb	short J23
  7462                              <1> 
  7463                              <1> ;WFPS_TIMEOUT:
  7464                              <1> 
  7465                              <1> ;-----	FALL THRU TO ERROR RETURN
  7466                              <1> 
  7467 000025C6 800D[2C710000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  7468                              <1> 	;POP	BX			; RESTORE REG.
  7469 000025CD 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  7470 000025CE F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  7471 000025CF C3                  <1> 	RETn
  7472                              <1> 
  7473                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  7474                              <1> 
  7475                              <1> J27:	
  7476 000025D0 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  7477 000025D2 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  7478 000025D4 EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  7479                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  7480                              <1> 	; 27/02/2015
  7481 000025D5 9C                  <1> 	PUSHF				; SAVE FLAGS
  7482 000025D6 B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  7483 000025DB E84CF0FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  7484 000025E0 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  7485                              <1> 	;POP	BX			; RESTORE REG
  7486 000025E1 C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  7487                              <1> 
  7488                              <1> ;-------------------------------------------------------------------------------
  7489                              <1> ; SEEK
  7490                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  7491                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  7492                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  7493                              <1> ;
  7494                              <1> ; ON ENTRY:	DI = DRIVE #
  7495                              <1> ;		CH = TRACK #
  7496                              <1> ;
  7497                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7498                              <1> ;		AX,BX,CX DX DESTROYED
  7499                              <1> ;-------------------------------------------------------------------------------
  7500                              <1> SEEK:
  7501 000025E2 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7502 000025E4 B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  7503 000025E6 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  7504 000025E8 D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  7505 000025EA 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  7506 000025EC 8405[29710000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  7507 000025F2 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  7508                              <1> 
  7509 000025F4 0805[29710000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  7510 000025FA E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7511 000025FF 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  7512                              <1> 
  7513                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  7514                              <1> 
  7515 00002601 C605[2C710000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  7516 00002608 E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7517 0000260D 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  7518                              <1> 
  7519                              <1> AFT_RECAL:
  7520 0000260F C687[3D710000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  7521 00002616 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  7522 00002618 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  7523                              <1> 
  7524                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  7525                              <1> 
  7526 0000261A F687[39710000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  7527 00002621 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  7528 00002623 D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  7529                              <1> 
  7530 00002625 3AAF[3D710000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  7531 0000262B 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  7532                              <1> 
  7533 0000262D BA[60260000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  7534 00002632 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  7535 00002633 88AF[3D710000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  7536 00002639 B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  7537 0000263B E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  7538 00002640 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7539 00002642 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  7540 00002644 E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  7541 00002649 8AA7[3D710000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  7542 0000264F E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  7543 00002654 E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  7544                              <1> 
  7545                              <1> ;-----	WAIT FOR HEAD SETTLE
  7546                              <1> 
  7547                              <1> DO_WAIT:
  7548 00002659 9C                  <1> 	PUSHF				; SAVE STATUS
  7549 0000265A E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  7550 0000265F 9D                  <1> 	POPF				; RESTORE STATUS
  7551                              <1> RB:
  7552                              <1> NEC_ERR:
  7553                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  7554                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  7555 00002660 C3                  <1> 	RETn				; RETURN TO CALLER
  7556                              <1> 
  7557                              <1> ;-------------------------------------------------------------------------------
  7558                              <1> ; RECAL
  7559                              <1> ;	RECALIBRATE DRIVE
  7560                              <1> ;
  7561                              <1> ; ON ENTRY:	DI = DRIVE #
  7562                              <1> ;
  7563                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  7564                              <1> ;-------------------------------------------------------------------------------
  7565                              <1> RECAL:
  7566 00002661 6651                <1> 	PUSH	CX
  7567 00002663 B8[7F260000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  7568 00002668 50                  <1> 	PUSH	eAX
  7569 00002669 B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  7570 0000266B E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  7571 00002670 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7572 00002672 88DC                <1> 	MOV	AH,BL
  7573 00002674 E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  7574 00002679 E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  7575 0000267E 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  7576                              <1> RC_BACK:
  7577 0000267F 6659                <1> 	POP	CX
  7578 00002681 C3                  <1> 	RETn
  7579                              <1> 
  7580                              <1> ;-------------------------------------------------------------------------------
  7581                              <1> ; CHK_STAT_2
  7582                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  7583                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  7584                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  7585                              <1> ;
  7586                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7587                              <1> ;-------------------------------------------------------------------------------
  7588                              <1> CHK_STAT_2:
  7589 00002682 B8[AA260000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  7590 00002687 50                  <1> 	PUSH	eAX
  7591 00002688 E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  7592 0000268D 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  7593 0000268F B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  7594 00002691 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  7595 00002696 E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  7596 0000269B 720C                <1> 	JC	short J34
  7597 0000269D A0[2D710000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  7598 000026A2 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  7599 000026A4 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  7600 000026A6 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  7601 000026A8 F8                  <1> 	CLC				; GOOD RETURN
  7602                              <1> J34:
  7603 000026A9 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  7604                              <1> CS_BACK:
  7605 000026AA C3                  <1> 	RETn
  7606                              <1> J35:
  7607 000026AB 800D[2C710000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  7608 000026B2 F9                  <1> 	STC				; ERROR RETURN CODE
  7609 000026B3 EBF4                <1> 	JMP	SHORT J34
  7610                              <1> 
  7611                              <1> ;-------------------------------------------------------------------------------
  7612                              <1> ; WAIT_INT
  7613                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  7614                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  7615                              <1> ;	IF THE DRIVE IS NOT READY.
  7616                              <1> ;
  7617                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7618                              <1> ;-------------------------------------------------------------------------------
  7619                              <1> 
  7620                              <1> ; 17/12/2014
  7621                              <1> ; 2.5 seconds waiting !
  7622                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  7623                              <1> ; amount of time to wait for completion interrupt from NEC.
  7624                              <1> 
  7625                              <1> 
  7626                              <1> WAIT_INT:
  7627 000026B5 FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  7628 000026B6 F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  7629                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  7630                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  7631                              <1> 
  7632                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  7633                              <1> 	;
  7634                              <1> 	;WAIT_FOR_MEM:	
  7635                              <1> 	;	Waits for a bit at a specified memory location pointed
  7636                              <1> 	;	to by ES:[DI] to become set.
  7637                              <1> 	;INPUT:
  7638                              <1> 	;	AH=Mask to test with.
  7639                              <1> 	;	ES:[DI] = memory location to watch.
  7640                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7641                              <1> 	;	     (normally 30 microseconds per period.)
  7642                              <1> 
  7643                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  7644                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  7645                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  7646                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  7647                              <1> 	; 27/02/2015
  7648 000026B7 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  7649                              <1> WFMS_CHECK_MEM:
  7650 000026BC F605[29710000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7651 000026C3 7516                <1>         jnz     short J37
  7652                              <1> WFMS_HI:
  7653 000026C5 E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  7654 000026C7 A810                <1> 	TEST	AL,010H			; transition on memory
  7655 000026C9 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  7656                              <1> WFMS_LO:
  7657 000026CB E461                <1> 	IN	AL,PORT_B		;SYS1
  7658 000026CD A810                <1> 	TEST	AL,010H
  7659 000026CF 74FA                <1> 	JZ	SHORT WFMS_LO
  7660 000026D1 E2E9                <1>         LOOP    WFMS_CHECK_MEM
  7661                              <1> ;WFMS_OUTER_LP:
  7662                              <1> ;;	or	bl, bl			; check outer counter
  7663                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  7664                              <1> ;	dec	bl
  7665                              <1> ;	jz	short J36A	
  7666                              <1> ;	jmp	short WFMS_CHECK_MEM
  7667                              <1> 
  7668                              <1> 	;17/12/2014
  7669                              <1> 	;16/12/2014
  7670                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  7671                              <1> ;J36:
  7672                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7673                              <1> ;	JNZ	short J37
  7674                              <1> 	;16/12/2014
  7675                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  7676                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  7677                              <1> 	;JNZ	short J36
  7678                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  7679                              <1> ;	jb	short J36
  7680                              <1> 
  7681                              <1> ;WFMS_TIMEOUT:
  7682                              <1> ;J36A:
  7683 000026D3 800D[2C710000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  7684 000026DA F9                  <1> 	STC				; ERROR RETURN
  7685                              <1> J37:
  7686 000026DB 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  7687 000026DC 8025[29710000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  7688 000026E3 9D                  <1> 	POPF				; RECOVER CARRY
  7689 000026E4 C3                  <1> 	RETn				; GOOD RETURN CODE
  7690                              <1> 
  7691                              <1> ;-------------------------------------------------------------------------------
  7692                              <1> ; RESULTS
  7693                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  7694                              <1> ;	FOLLOWING AN INTERRUPT.
  7695                              <1> ;
  7696                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7697                              <1> ;		AX,BX,CX,DX DESTROYED
  7698                              <1> ;-------------------------------------------------------------------------------
  7699                              <1> RESULTS:
  7700 000026E5 57                  <1> 	PUSH	eDI
  7701 000026E6 BF[2D710000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  7702 000026EB B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  7703 000026ED 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  7704                              <1> 
  7705                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  7706                              <1> 
  7707                              <1> _R10: 
  7708                              <1> 	; 16/12/2014
  7709                              <1> 	; wait for (max) 0.5 seconds
  7710                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  7711                              <1> 	;XOR	CX,CX			; COUNTER
  7712                              <1> 
  7713                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  7714                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  7715                              <1> 	; 27/02/2015
  7716 000026F1 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  7717                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  7718                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  7719                              <1> 
  7720                              <1> WFPSR_OUTER_LP:
  7721                              <1> 	;
  7722                              <1> WFPSR_CHECK_PORT:
  7723                              <1> J39:					; WAIT FOR MASTER
  7724 000026F6 EC                  <1> 	IN	AL,DX			; GET STATUS
  7725 000026F7 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  7726 000026F9 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  7727 000026FB 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  7728                              <1> WFPSR_HI:
  7729 000026FD E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  7730 000026FF A810                <1> 	TEST	AL,010H			; transition on memory
  7731 00002701 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  7732                              <1> WFPSR_LO:
  7733 00002703 E461                <1> 	IN	AL, PORT_B		; SYS1
  7734 00002705 A810                <1> 	TEST	AL,010H
  7735 00002707 74FA                <1> 	JZ	SHORT WFPSR_LO
  7736 00002709 E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  7737                              <1> 	;; 27/02/2015
  7738                              <1> 	;;dec	bh
  7739                              <1> 	;;jnz	short WFPSR_OUTER_LP
  7740                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  7741                              <1> 
  7742                              <1> 	;;mov	byte [wait_count], 0
  7743                              <1> ;J39:					; WAIT FOR MASTER
  7744                              <1> ;	IN	AL,DX			; GET STATUS
  7745                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  7746                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  7747                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  7748                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  7749                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  7750                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  7751                              <1> 	;
  7752                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  7753                              <1> 	;;jb	short J39	
  7754                              <1> 
  7755                              <1> ;WFPSR_TIMEOUT:
  7756 0000270B 800D[2C710000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  7757 00002712 F9                  <1> 	STC				; SET ERROR RETURN
  7758 00002713 EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  7759                              <1> 
  7760                              <1> ;-----	READ IN THE STATUS
  7761                              <1> 
  7762                              <1> J42:
  7763 00002715 EB00                <1> 	JMP	$+2			; I/O DELAY
  7764 00002717 6642                <1> 	INC	DX			; POINT AT DATA PORT
  7765 00002719 EC                  <1> 	IN	AL,DX			; GET THE DATA
  7766                              <1> 	; 16/12/2014
  7767                              <1> 	NEWIODELAY
  7768 0000271A E6EB                <2>  out 0ebh,al
  7769 0000271C 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  7770 0000271E 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  7771                              <1> 	; 16/12/2014
  7772                              <1> ;	push	cx
  7773                              <1> ;	mov	cx, 30
  7774                              <1> ;wdw2:
  7775                              <1> ;	NEWIODELAY
  7776                              <1> ;	loop	wdw2
  7777                              <1> ;	pop	cx
  7778                              <1> 
  7779 0000271F B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  7780 00002724 E803EFFFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  7781 00002729 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  7782 0000272B EC                  <1> 	IN	AL,DX			; GET STATUS
  7783                              <1> 	; 16/12/2014
  7784                              <1> 	NEWIODELAY
  7785 0000272C E6EB                <2>  out 0ebh,al
  7786                              <1> 	;
  7787 0000272E A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  7788 00002730 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  7789                              <1> 
  7790 00002732 FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  7791 00002734 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  7792 00002736 800D[2C710000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  7793 0000273D F9                  <1> 	STC				; SET ERROR FLAG
  7794                              <1> 
  7795                              <1> ;-----	RESULT OPERATION IS DONE
  7796                              <1> POPRES:
  7797 0000273E 5F                  <1> 	POP	eDI
  7798 0000273F C3                  <1> 	RETn				; RETURN WITH CARRY SET
  7799                              <1> 
  7800                              <1> ;-------------------------------------------------------------------------------
  7801                              <1> ; READ_DSKCHNG
  7802                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  7803                              <1> ;
  7804                              <1> ; ON ENTRY:	DI = DRIVE #
  7805                              <1> ;
  7806                              <1> ; ON EXIT:	DI = DRIVE #
  7807                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  7808                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  7809                              <1> ;		AX,CX,DX DESTROYED
  7810                              <1> ;-------------------------------------------------------------------------------
  7811                              <1> READ_DSKCHNG:
  7812 00002740 E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  7813 00002745 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  7814 00002749 EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  7815 0000274A A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  7816 0000274C C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  7817                              <1> 
  7818                              <1> ;-------------------------------------------------------------------------------
  7819                              <1> ; DRIVE_DET
  7820                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  7821                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  7822                              <1> ; ON ENTRY:	DI = DRIVE #
  7823                              <1> ;-------------------------------------------------------------------------------
  7824                              <1> DRIVE_DET:
  7825 0000274D E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  7826 00002752 E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7827 00002757 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  7828 00002759 B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  7829 0000275B E882FEFFFF          <1> 	CALL	SEEK
  7830 00002760 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  7831 00002762 B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  7832                              <1> SK_GIN:
  7833 00002764 FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  7834 00002766 6651                <1> 	PUSH	CX			; SAVE TRACK
  7835 00002768 E875FEFFFF          <1> 	CALL	SEEK
  7836 0000276D 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  7837 0000276F B8[AB270000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  7838 00002774 50                  <1> 	PUSH	eAX
  7839 00002775 B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  7840 00002777 E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  7841 0000277C 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  7842 0000277F 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  7843 00002781 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  7844 00002786 E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  7845 0000278B 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  7846 0000278C 6659                <1> 	POP	CX			; RESTORE TRACK
  7847 0000278E F605[2D710000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  7848 00002795 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  7849 00002797 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  7850 00002799 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  7851                              <1> 
  7852                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  7853                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  7854                              <1> 
  7855 0000279B 808F[39710000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  7856 000027A2 C3                  <1> 	RETn				; ALL INFORMATION SET
  7857                              <1> IS_80:
  7858 000027A3 808F[39710000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  7859                              <1> DD_BAC:
  7860 000027AA C3                  <1> 	RETn
  7861                              <1> POP_BAC:
  7862 000027AB 6659                <1> 	POP	CX			; THROW AWAY
  7863 000027AD C3                  <1> 	RETn
  7864                              <1> 
  7865                              <1> fdc_int:  
  7866                              <1> 	  ; 30/07/2015	
  7867                              <1> 	  ; 16/02/2015
  7868                              <1> ;int_0Eh: ; 11/12/2014
  7869                              <1> 
  7870                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  7871                              <1> ; DISK_INT
  7872                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  7873                              <1> ;
  7874                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  7875                              <1> ;-------------------------------------------------------------------------------
  7876                              <1> DISK_INT_1:
  7877                              <1> 
  7878 000027AE 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  7879 000027B0 1E                  <1> 	push	ds
  7880 000027B1 66B81000            <1> 	mov	ax, KDATA
  7881 000027B5 8ED8                <1> 	mov 	ds, ax
  7882 000027B7 800D[29710000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  7883 000027BE B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  7884 000027C0 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  7885 000027C2 1F                  <1> 	pop	ds
  7886 000027C3 6658                <1> 	POP	AX			; RECOVER REGISTER
  7887 000027C5 CF                  <1> 	IRET				; RETURN FROM INTERRUPT
  7888                              <1> 
  7889                              <1> ;-------------------------------------------------------------------------------
  7890                              <1> ; DSKETTE_SETUP
  7891                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  7892                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  7893                              <1> ;-------------------------------------------------------------------------------
  7894                              <1> DSKETTE_SETUP:
  7895                              <1> 	;PUSH	AX			; SAVE REGISTERS
  7896                              <1> 	;PUSH	BX
  7897                              <1> 	;PUSH	CX
  7898 000027C6 52                  <1> 	PUSH	eDX
  7899                              <1> 	;PUSH	DI
  7900                              <1> 	;;PUSH	DS
  7901                              <1> 	; 14/12/2014
  7902                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  7903                              <1> 	;mov	[DISK_POINTER+2], cs
  7904                              <1> 	;
  7905                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  7906 000027C7 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  7907 000027C9 66C705[39710000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  7908 000027D1 00                  <1>
  7909 000027D2 8025[34710000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  7910 000027D9 800D[34710000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  7911 000027E0 C605[29710000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  7912 000027E7 C605[2B710000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  7913 000027EE C605[2A710000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  7914 000027F5 C605[2C710000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  7915                              <1> 	;
  7916                              <1> 	; 28/02/2015
  7917                              <1> 	;mov	word [cfd], 100h 
  7918 000027FC E860F2FFFF          <1> 	call	DSK_RESET
  7919 00002801 5A                  <1> 	pop	edx
  7920 00002802 C3                  <1> 	retn
  7921                              <1> 
  7922                              <1> ;SUP0:
  7923                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  7924                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7925                              <1> ;	; 02/01/2015
  7926                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  7927                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  7928                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  7929                              <1> ;       cmp     byte [fd1_type], 0	
  7930                              <1> ;	jna	short sup1
  7931                              <1> ;	or	di, di
  7932                              <1> ;	jnz	short sup1
  7933                              <1> ;	inc	di
  7934                              <1> ;       jmp     short SUP0
  7935                              <1> ;sup1:
  7936                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  7937                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  7938                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  7939                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  7940                              <1> ;	;POP	DI
  7941                              <1> ;	POP	eDX
  7942                              <1> ;	;POP	CX
  7943                              <1> ;	;POP	BX
  7944                              <1> ;	;POP	AX
  7945                              <1> ;	RETn
  7946                              <1> 
  7947                              <1> ;//////////////////////////////////////////////////////
  7948                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7949                              <1> ;
  7950                              <1> 
  7951                              <1> int13h: ; 21/02/2015
  7952 00002803 9C                  <1> 	pushfd
  7953 00002804 0E                  <1> 	push 	cs
  7954 00002805 E859000000          <1> 	call 	DISK_IO
  7955 0000280A C3                  <1> 	retn
  7956                              <1> 
  7957                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  7958                              <1> ;/////////////////////////////////////////////////////////////////////
  7959                              <1> 
  7960                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  7961                              <1> ; 23/02/2015
  7962                              <1> ; 21/02/2015 (unix386.s)
  7963                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  7964                              <1> ;
  7965                              <1> ; Original Source Code:
  7966                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  7967                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  7968                              <1> ;
  7969                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  7970                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  7971                              <1> ;
  7972                              <1> 
  7973                              <1> 
  7974                              <1> ;The wait for controller to be not busy is 10 seconds.
  7975                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  7976                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  7977                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  7978                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  7979                              <1> 
  7980                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  7981                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  7982                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  7983                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  7984                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  7985                              <1> 
  7986                              <1> ;The wait for Data request on read and write longs is
  7987                              <1> ;2000 us. (?)
  7988                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  7989                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  7990                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  7991                              <1> 
  7992                              <1> ; Port 61h (PORT_B)
  7993                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  7994                              <1> 
  7995                              <1> ; 23/12/2014
  7996                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  7997                              <1> 
  7998                              <1> 
  7999                              <1> ;--- INT 13H -------------------------------------------------------------------
  8000                              <1> ;									       :
  8001                              <1> ; FIXED DISK I/O INTERFACE						       :
  8002                              <1> ;									       :
  8003                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  8004                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  8005                              <1> ;									       :
  8006                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  8007                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  8008                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  8009                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  8010                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  8011                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  8012                              <1> ;									       :
  8013                              <1> ;------------------------------------------------------------------------------:
  8014                              <1> ;									       :
  8015                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  8016                              <1> ;									       :
  8017                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  8018                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  8019                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  8020                              <1> ;			  DL > 80H - DISK				       :
  8021                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  8022                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  8023                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  8024                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  8025                              <1> ;	(AH)= 06H  UNUSED						       :
  8026                              <1> ;	(AH)= 07H  UNUSED						       :
  8027                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  8028                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  8029                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  8030                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  8031                              <1> ;	(AH)= 0AH  READ LONG						       :
  8032                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  8033                              <1> ;	(AH)= 0CH  SEEK 						       :
  8034                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  8035                              <1> ;	(AH)= 0EH  UNUSED						       :
  8036                              <1> ;	(AH)= 0FH  UNUSED						       :
  8037                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  8038                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  8039                              <1> ;	(AH)= 12H  UNUSED						       :
  8040                              <1> ;	(AH)= 13H  UNUSED						       :
  8041                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  8042                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  8043                              <1> ;									       :
  8044                              <1> ;-------------------------------------------------------------------------------
  8045                              <1> ;									       :
  8046                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  8047                              <1> ;									       :
  8048                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  8049                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  8050                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  8051                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  8052                              <1> ;									       :
  8053                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  8054                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  8055                              <1> ;				 (10 BITS TOTAL)			       :
  8056                              <1> ;									       :
  8057                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  8058                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  8059                              <1> ;									       :
  8060                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  8061                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  8062                              <1> ;									       :
  8063                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  8064                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  8065                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  8066                              <1> ;			       80H FOR A BAD SECTOR			       :
  8067                              <1> ;			   N = SECTOR NUMBER				       :
  8068                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  8069                              <1> ;			   THE TABLE SHOULD BE: 			       :
  8070                              <1> ;									       :
  8071                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  8072                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  8073                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  8074                              <1> ;									       :
  8075                              <1> ;-------------------------------------------------------------------------------
  8076                              <1> 
  8077                              <1> ;-------------------------------------------------------------------------------
  8078                              <1> ; OUTPUT								       :
  8079                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  8080                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  8081                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  8082                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  8083                              <1> ;									       :
  8084                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  8085                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  8086                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  8087                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  8088                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  8089                              <1> ;		REWRITTEN.						       :
  8090                              <1> ;									       :
  8091                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  8092                              <1> ;	   INPUT:							       :
  8093                              <1> ;	     (DL) = DRIVE NUMBER					       :
  8094                              <1> ;	   OUTPUT:							       :
  8095                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  8096                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  8097                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  8098                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  8099                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  8100                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  8101                              <1> ;									       :
  8102                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  8103                              <1> ;									       :
  8104                              <1> ;	AH = 0 - NOT PRESENT						       :
  8105                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  8106                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  8107                              <1> ;	     3 - FIXED DISK						       :
  8108                              <1> ;									       :
  8109                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  8110                              <1> ;									       :
  8111                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  8112                              <1> ;	INFORMATION.							       :
  8113                              <1> ;									       :
  8114                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  8115                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  8116                              <1> ;									       :
  8117                              <1> ;-------------------------------------------------------------------------------
  8118                              <1> 
  8119                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  8120                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  8121                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  8122                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  8123                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  8124                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  8125                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  8126                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  8127                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  8128                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  8129                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  8130                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  8131                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  8132                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  8133                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  8134                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  8135                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  8136                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  8137                              <1> 
  8138                              <1> ;--------------------------------------------------------
  8139                              <1> ;							:
  8140                              <1> ; FIXED DISK PARAMETER TABLE				:
  8141                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  8142                              <1> ;							:
  8143                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  8144                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  8145                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  8146                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  8147                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  8148                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  8149                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  8150                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  8151                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  8152                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  8153                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  8154                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  8155                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  8156                              <1> ;							:
  8157                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  8158                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  8159                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  8160                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  8161                              <1> ;							:
  8162                              <1> ;--------------------------------------------------------
  8163                              <1> 
  8164                              <1> ;--------------------------------------------------------
  8165                              <1> ;							:
  8166                              <1> ; HARDWARE SPECIFIC VALUES				:
  8167                              <1> ;							:
  8168                              <1> ;  -  CONTROLLER I/O PORT				:
  8169                              <1> ;							:
  8170                              <1> ;     > WHEN READ FROM: 				:
  8171                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  8172                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  8173                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  8174                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  8175                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  8176                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  8177                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  8178                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  8179                              <1> ;							:
  8180                              <1> ;     > WHEN WRITTEN TO:				:
  8181                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  8182                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  8183                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  8184                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  8185                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  8186                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  8187                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  8188                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  8189                              <1> ;							:
  8190                              <1> ;--------------------------------------------------------
  8191                              <1> 
  8192                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  8193                              <1> ;HF1_PORT	equ	0170h	
  8194                              <1> ;HF_REG_PORT	EQU	03F6H
  8195                              <1> ;HF1_REG_PORT	equ	0376h
  8196                              <1> 
  8197                              <1> HDC1_BASEPORT	equ	1F0h
  8198                              <1> HDC2_BASEPORT	equ	170h		
  8199                              <1> 
  8200 0000280B 90                  <1> align 2
  8201                              <1> 
  8202                              <1> ;-----		STATUS REGISTER
  8203                              <1> 
  8204                              <1> ST_ERROR	EQU	00000001B	;
  8205                              <1> ST_INDEX	EQU	00000010B	;
  8206                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  8207                              <1> ST_DRQ		EQU	00001000B	;
  8208                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  8209                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  8210                              <1> ST_READY	EQU	01000000B	;
  8211                              <1> ST_BUSY 	EQU	10000000B	;
  8212                              <1> 
  8213                              <1> ;-----		ERROR REGISTER
  8214                              <1> 
  8215                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  8216                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  8217                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  8218                              <1> ;		EQU	00001000B	; NOT USED
  8219                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  8220                              <1> ;		EQU	00100000B	; NOT USED
  8221                              <1> ERR_DATA_ECC	EQU	01000000B
  8222                              <1> ERR_BAD_BLOCK	EQU	10000000B
  8223                              <1> 
  8224                              <1> 
  8225                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  8226                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  8227                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  8228                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  8229                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  8230                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  8231                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  8232                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  8233                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  8234                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  8235                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  8236                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  8237                              <1> 
  8238                              <1> ;MAX_FILE	EQU	2
  8239                              <1> ;S_MAX_FILE	EQU	2
  8240                              <1> MAX_FILE	equ	4		; 22/12/2014
  8241                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  8242                              <1> 
  8243                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  8244                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  8245                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  8246                              <1> 
  8247                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  8248                              <1> 
  8249                              <1> ;-----		COMMAND BLOCK REFERENCE
  8250                              <1> 
  8251                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  8252                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  8253                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  8254                              <1> ; 19/12/2014
  8255                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  8256                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  8257                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8258                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8259                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  8260                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  8261                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  8262                              <1> 
  8263                              <1> align 2
  8264                              <1> 
  8265                              <1> ;----------------------------------------------------------------
  8266                              <1> ; FIXED DISK I/O SETUP						:
  8267                              <1> ;								:
  8268                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  8269                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  8270                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  8271                              <1> ;								:
  8272                              <1> ;----------------------------------------------------------------
  8273                              <1> 
  8274                              <1> DISK_SETUP:
  8275                              <1> 	;CLI
  8276                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  8277                              <1> 	;xor	ax,ax
  8278                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  8279                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  8280                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  8281                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  8282                              <1> 	;MOV	[DISK_VECTOR+2],AX
  8283                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  8284                              <1> 	;MOV	[ORG_VECTOR+2],CS
  8285                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  8286                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  8287                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  8288                              <1> 	;;MOV	[HDISK_INT+2],CS
  8289                              <1> 	;mov	[HDISK_INT1+2],CS
  8290                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  8291                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  8292                              <1> 	;mov	[HDISK_INT2+2],CS
  8293                              <1> 	;
  8294                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  8295                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  8296                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  8297                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  8298                              <1> 	;push	cs
  8299                              <1> 	;pop	ds
  8300                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  8301                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  8302 0000280C C705[44710000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  8303 00002814 0900                <1>
  8304                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  8305                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  8306 00002816 C705[48710000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  8307 0000281E 0900                <1>
  8308                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  8309                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  8310 00002820 C705[4C710000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  8311 00002828 0900                <1>
  8312                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  8313                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  8314 0000282A C705[50710000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  8315 00002832 0900                <1>
  8316                              <1> 	;
  8317                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  8318                              <1> 	;;;AND	AL,0BFH
  8319                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  8320                              <1> 	;;;JMP	$+2
  8321                              <1> 	;;IODELAY
  8322                              <1> 	;;OUT	INTB01,AL
  8323                              <1> 	;;IODELAY
  8324                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  8325                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  8326                              <1> 	;;;JMP	$+2
  8327                              <1> 	;;IODELAY
  8328                              <1> 	;;OUT	INTA01,AL
  8329                              <1> 	;
  8330                              <1> 	;STI
  8331                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  8332                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  8333                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  8334                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8335                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  8336                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  8337                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  8338                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  8339                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  8340                              <1> 	;mov	si, hd0_type
  8341 00002834 BE[DA6D0000]        <1> 	mov	esi, hd0_type
  8342                              <1> 	;mov	cx, 4
  8343 00002839 B904000000          <1> 	mov	ecx, 4
  8344                              <1> hde_l:
  8345 0000283E AC                  <1> 	lodsb
  8346 0000283F 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  8347 00002841 7206                <1> 	jb	short _L4
  8348 00002843 FE05[40710000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  8349                              <1> _L4: ; 26/02/2015
  8350 00002849 E2F3                <1> 	loop	hde_l	
  8351                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  8352                              <1> ;L4:
  8353                              <1> 	; 
  8354                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  8355                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  8356                              <1> 	;;mov 	cl, 3
  8357                              <1> 	;;
  8358                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  8359                              <1> ;;hdc_dl:
  8360                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  8361                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  8362                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  8363                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  8364                              <1> 	;;jnc	short hdc_reset0
  8365                              <1> 	;;loop	hdc_dl
  8366                              <1> 	;;; 27/12/2014
  8367                              <1> 	;;stc
  8368                              <1> 	;;retn
  8369                              <1> 	;
  8370                              <1> ;;hdc_reset0:
  8371                              <1> 	; 18/01/2015
  8372 0000284B 8A0D[40710000]      <1> 	mov	cl, [HF_NUM]
  8373 00002851 20C9                <1> 	and	cl, cl
  8374 00002853 740D                <1> 	jz	short POD_DONE
  8375                              <1> 	;
  8376 00002855 B27F                <1> 	mov	dl, 7Fh
  8377                              <1> hdc_reset1:
  8378 00002857 FEC2                <1> 	inc	dl
  8379                              <1> 	;; 31/12/2015
  8380                              <1> 	;;push	dx
  8381                              <1> 	;;push	cx
  8382                              <1> 	;;push	ds
  8383                              <1> 	;;sub	ax, ax
  8384                              <1> 	;;mov	ds, ax
  8385                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  8386                              <1> 	;;pop	ds
  8387                              <1> 	;;MOV	BX,AX
  8388                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  8389                              <1> 	;;MOV	CX,AX
  8390                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  8391                              <1> 	;;
  8392                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  8393                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  8394                              <1> 	;;pop	cx
  8395                              <1> 	;;pop	dx
  8396                              <1> 	;;
  8397                              <1> 	; 18/01/2015
  8398 00002859 B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  8399                              <1> 	;int	13h
  8400 0000285B E8A3FFFFFF          <1> 	call	int13h
  8401 00002860 E2F5                <1> 	loop	hdc_reset1
  8402                              <1> POD_DONE:
  8403 00002862 C3                  <1> 	RETn
  8404                              <1> 
  8405                              <1> ;;-----	POD_ERROR
  8406                              <1> 
  8407                              <1> ;;CTL_ERRX:
  8408                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  8409                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  8410                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8411                              <1> ;	;JMP	short POD_DONE
  8412                              <1> 
  8413                              <1> ;;HD_RESET_1:
  8414                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  8415                              <1> ;;	;PUSH	CX
  8416                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  8417                              <1> ;;	INT	13H
  8418                              <1> ;;	JC	short RES_2
  8419                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  8420                              <1> ;;	INT	13H
  8421                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  8422                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  8423                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8424                              <1> ;;					; (30 seconds)		
  8425                              <1> ;;	;cmc
  8426                              <1> ;;	;JNC	short RES_1
  8427                              <1> ;;	jb	short RES_1
  8428                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  8429                              <1> ;;	;TEST	DL,1
  8430                              <1> ;;	;JNZ	RES_E1
  8431                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  8432                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  8433                              <1> ;;	;JMP	SHORT RES_E1
  8434                              <1> ;;RES_ER: ; 22/12/2014
  8435                              <1> ;;RES_OK:
  8436                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8437                              <1> ;;	;POP	BX
  8438                              <1> ;;	RETn
  8439                              <1> ;;
  8440                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  8441                              <1> ;;	INT	13H
  8442                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  8443                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  8444                              <1> ;;	INT	13H
  8445                              <1> ;;	JC	short RES_ER
  8446                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  8447                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  8448                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  8449                              <1> ;;	INT	13H
  8450                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  8451                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  8452                              <1> ;;	JE	short RES_OK
  8453                              <1> ;;	CMP	AH,DATA_CORRECTED
  8454                              <1> ;;	JE	short RES_OK
  8455                              <1> ;;	CMP	AH,BAD_ECC
  8456                              <1> ;;	JE	short RES_OK
  8457                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  8458                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8459                              <1> ;;					; (60 seconds)		
  8460                              <1> ;;	cmc
  8461                              <1> ;;	JC	short RES_ER		; FAILED
  8462                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  8463                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  8464                              <1> ;;	AND	AL,3FH
  8465                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  8466                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  8467                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  8468                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  8469                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  8470                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  8471                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  8472                              <1> ;;	;TEST	DL,1
  8473                              <1> ;;	;JNZ	short RES_E1
  8474                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  8475                              <1> ;;;RES_E1:
  8476                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8477                              <1> ;;;RES_OK:
  8478                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8479                              <1> ;;	;POP	BX
  8480                              <1> ;;	;RETn
  8481                              <1> ;
  8482                              <1> ;;SET_FAIL:
  8483                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  8484                              <1> ;	;CALL	CMOS_READ
  8485                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  8486                              <1> ;	;XCHG	AH,AL			; SAVE IT
  8487                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  8488                              <1> ;	;RETn
  8489                              <1> ;
  8490                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  8491                              <1> ;	;POP	AX			; SAVE RETURN
  8492                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  8493                              <1> ;	;POP	BX
  8494                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  8495                              <1> ;	;PUSH	CX
  8496                              <1> ;	;PUSH	AX
  8497                              <1> ;	;push	ds
  8498                              <1> ;	;xor	ax, ax
  8499                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  8500                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  8501                              <1> ;	;				; BX = START TIME
  8502                              <1> ;	;				; CX = END TIME
  8503                              <1> ;	;pop	ds
  8504                              <1> ;	;CMP	BX,CX
  8505                              <1> ;	;JB	short TCHK1		; START < END
  8506                              <1> ;	;CMP	BX,AX
  8507                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  8508                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  8509                              <1> ;;TCHK1: CMP	AX,BX
  8510                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  8511                              <1> ;;TCHK2: CMP	AX,CX
  8512                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  8513                              <1> ;;					; OR CURRENT < END < START
  8514                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  8515                              <1> ;;	RETn
  8516                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  8517                              <1> ;;	RETn
  8518                              <1> ;;
  8519                              <1> ;;int_13h:
  8520                              <1> 
  8521                              <1> ;----------------------------------------
  8522                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  8523                              <1> ;----------------------------------------
  8524                              <1> 
  8525                              <1> DISK_IO:
  8526 00002863 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  8527                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  8528                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  8529                              <1> 	;;call	int40h
  8530 00002866 0F8225F1FFFF        <1> 	jb	DISKETTE_IO_1
  8531                              <1> ;RET_2:
  8532                              <1> 	;RETf	2			; BACK TO CALLER
  8533                              <1> ;	retf	4
  8534                              <1> A1:
  8535 0000286C FB                  <1> 	STI				; ENABLE INTERRUPTS
  8536                              <1> 	;; 04/01/2015
  8537                              <1> 	;;OR	AH,AH
  8538                              <1> 	;;JNZ	short A2
  8539                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  8540                              <1> 	;;SUB	AH,AH
  8541 0000286D 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  8542 00002870 772C                <1> 	JA	short RET_2
  8543                              <1> 	; 18/01/2015
  8544 00002872 08E4                <1> 	or	ah,ah
  8545 00002874 742B                <1> 	jz	short A4
  8546 00002876 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  8547 00002879 7504                <1> 	jne	short A2
  8548 0000287B 28E4                <1> 	sub	ah,ah	; Reset
  8549 0000287D EB22                <1> 	jmp	short A4
  8550                              <1> A2:
  8551 0000287F 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  8552                              <1> 	;JNZ	short A3
  8553                              <1>         ;JMP    GET_PARM_N
  8554 00002882 0F841C030000        <1> 	je	GET_PARM_N
  8555 00002888 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  8556                              <1> 	;JNZ	short A4
  8557                              <1>         ;JMP    READ_DASD_TYPE
  8558 0000288B 0F84C7020000        <1>         je      READ_DASD_TYPE
  8559                              <1> 	; 02/02/2015
  8560 00002891 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  8561                              <1> 	; 12/01/2015
  8562 00002894 F5                  <1> 	cmc
  8563 00002895 730A                <1> 	jnc	short A4
  8564                              <1> 	; 30/01/2015
  8565                              <1> 	;mov     byte [CS:DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  8566 00002897 C605[3F710000]01    <1>         mov     byte [DISK_STATUS1], BAD_CMD
  8567                              <1> 	;jmp	short RET_2
  8568                              <1> RET_2:
  8569 0000289E CA0400              <1> 	retf	4
  8570                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  8571 000028A1 C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  8572 000028A5 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  8573 000028A6 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  8574 000028A7 52                  <1> 	PUSH	eDX
  8575 000028A8 1E                  <1> 	PUSH	DS
  8576 000028A9 06                  <1> 	PUSH	ES
  8577 000028AA 56                  <1> 	PUSH	eSI
  8578 000028AB 57                  <1> 	PUSH	eDI
  8579                              <1> 	;;04/01/2015
  8580                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  8581                              <1> 	;;JNZ	short A5
  8582                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  8583                              <1> ;;A5:	
  8584                              <1> 	;push	cs
  8585                              <1> 	;pop	ds
  8586                              <1> 	; 21/02/2015
  8587 000028AC 6650                <1> 	push	ax
  8588 000028AE 66B81000            <1> 	mov	ax, KDATA
  8589 000028B2 8ED8                <1> 	mov	ds, ax
  8590 000028B4 8EC0                <1> 	mov	es, ax	
  8591 000028B6 6658                <1> 	pop	ax
  8592 000028B8 E889000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  8593                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  8594 000028BD 8A25[3F710000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  8595 000028C3 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  8596 000028C6 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  8597 000028C7 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  8598 000028C8 5E                  <1> 	POP	eSI
  8599 000028C9 07                  <1>         POP     ES
  8600 000028CA 1F                  <1>         POP     DS
  8601 000028CB 5A                  <1> 	POP	eDX
  8602 000028CC 59                  <1> 	POP	eCX
  8603 000028CD 5B                  <1> 	POP	eBX
  8604 000028CE C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  8605                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  8606 000028CF CA0400              <1> 	retf	4
  8607                              <1> ; 21/02/2015
  8608                              <1> ;       dw --> dd
  8609                              <1> M1:					; FUNCTION TRANSFER TABLE
  8610 000028D2 [942A0000]          <1> 	dd	DISK_RESET		; 000H
  8611 000028D6 [0B2B0000]          <1> 	dd	RETURN_STATUS		; 001H
  8612 000028DA [182B0000]          <1> 	dd	DISK_READ		; 002H
  8613 000028DE [212B0000]          <1> 	dd	DISK_WRITE		; 003H
  8614 000028E2 [2A2B0000]          <1> 	dd	DISK_VERF		; 004H
  8615 000028E6 [422B0000]          <1> 	dd	FMT_TRK 		; 005H
  8616 000028EA [8A2A0000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  8617 000028EE [8A2A0000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  8618 000028F2 [8A2A0000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  8619 000028F6 [092C0000]          <1> 	dd	INIT_DRV		; 009H
  8620 000028FA [682C0000]          <1> 	dd	RD_LONG 		; 00AH
  8621 000028FE [712C0000]          <1> 	dd	WR_LONG 		; 00BH
  8622 00002902 [7A2C0000]          <1> 	dd	DISK_SEEK		; 00CH
  8623 00002906 [942A0000]          <1> 	dd	DISK_RESET		; 00DH
  8624 0000290A [8A2A0000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  8625 0000290E [8A2A0000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  8626 00002912 [A22C0000]          <1> 	dd	TST_RDY 		; 010H
  8627 00002916 [C62C0000]          <1> 	dd	HDISK_RECAL		; 011H
  8628 0000291A [8A2A0000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  8629 0000291E [8A2A0000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  8630 00002922 [FC2C0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  8631                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  8632 00002926 [8A2A0000]          <1> 	dd	BAD_COMMAND		; 015h
  8633 0000292A [8A2A0000]          <1> 	dd	BAD_COMMAND		; 016h
  8634 0000292E [8A2A0000]          <1> 	dd	BAD_COMMAND		; 017h
  8635 00002932 [8A2A0000]          <1> 	dd	BAD_COMMAND		; 018h
  8636 00002936 [8A2A0000]          <1> 	dd	BAD_COMMAND		; 019h
  8637 0000293A [8A2A0000]          <1> 	dd	BAD_COMMAND		; 01Ah
  8638 0000293E [182B0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  8639 00002942 [212B0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  8640                              <1> M1L     EQU    $-M1
  8641                              <1> 
  8642                              <1> DISK_IO_CONT:
  8643                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  8644 00002946 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  8645                              <1> 	;;JNZ	short SU0
  8646                              <1>         ;;JMP    RETURN_STATUS
  8647 00002949 0F84BC010000        <1> 	je	RETURN_STATUS
  8648                              <1> SU0:
  8649 0000294F C605[3F710000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8650                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  8651                              <1> 	;mov	si, bx ;; 14/02/2015
  8652 00002956 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  8653 00002958 8A1D[40710000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  8654                              <1> 	;; 04/01/2015
  8655                              <1> 	;;PUSH	AX
  8656 0000295E 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  8657                              <1> 					; (get drive number as 0 to 3)
  8658 00002961 38D3                <1> 	CMP	BL,DL
  8659                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  8660 00002963 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  8661                              <1>         ;
  8662                              <1> 	;;03/01/2015
  8663 00002969 29DB                <1> 	sub	ebx, ebx
  8664 0000296B 88D3                <1> 	mov	bl, dl
  8665                              <1> 	;sub	bh, bh
  8666 0000296D 883D[54710000]      <1> 	mov	[LBAMode], bh 	; 0
  8667                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  8668                              <1> 	;test	byte [ebx+hd0_type], 1
  8669                              <1> 	;jz	short su1		; no
  8670                              <1> 	;inc	byte [LBAMode]
  8671                              <1> ;su1:
  8672                              <1> 	; 21/02/2015 (32 bit modification)
  8673                              <1> 	;04/01/2015
  8674 00002973 6650                <1> 	push	ax ; ***
  8675                              <1> 	;PUSH	ES ; **
  8676 00002975 6652                <1> 	PUSH	DX ; *
  8677 00002977 6650                <1> 	push	ax
  8678 00002979 E85C060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  8679                              <1> 	; 02/02/2015
  8680                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  8681 0000297E 668B4310            <1> 	mov	ax, [ebx+16]
  8682 00002982 66A3[546B0000]      <1> 	mov	[HF_PORT], ax
  8683                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  8684 00002988 668B5312            <1> 	mov	dx, [ebx+18]
  8685 0000298C 668915[566B0000]    <1> 	mov	[HF_REG_PORT], dx
  8686                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  8687 00002993 8A4314              <1> 	mov	al, [ebx+20]
  8688                              <1> 	; 23/02/2015
  8689 00002996 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  8690 00002998 7406                <1> 	jz 	short su1
  8691 0000299A FE05[54710000]      <1> 	inc	byte [LBAMode] ; 1 
  8692                              <1> su1: 	 
  8693 000029A0 C0E804              <1> 	shr 	al, 4
  8694 000029A3 2401                <1> 	and	al, 1			
  8695 000029A5 A2[586B0000]        <1> 	mov	[hf_m_s], al 
  8696                              <1> 	;
  8697                              <1> 	; 03/01/2015
  8698                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  8699 000029AA 8A4308              <1> 	mov	al, [ebx+8]
  8700                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  8701 000029AD EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  8702                              <1> 					; Control Byte:  (= 08h, here)
  8703                              <1> 					; bit 0 - 0
  8704                              <1> 					; bit 1 - nIEN (1 = disable irq)
  8705                              <1> 					; bit 2 - SRST (software RESET)
  8706                              <1> 					; bit 3 - use extra heads (8 to 15)
  8707                              <1> 					;         -always set to 1-	
  8708                              <1> 					; (bits 3 to 7 are reserved
  8709                              <1> 					;          for ATA devices)
  8710 000029AE 8A25[41710000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  8711 000029B4 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  8712 000029B7 08C4                <1> 	OR	AH,AL
  8713 000029B9 8825[41710000]      <1> 	MOV	[CONTROL_BYTE],AH	
  8714                              <1> 	; 04/01/2015
  8715 000029BF 6658                <1> 	pop	ax
  8716 000029C1 665A                <1> 	pop	dx ; * ;; 14/02/2015
  8717 000029C3 20E4                <1> 	and	ah, ah	; Reset function ?
  8718 000029C5 7507                <1> 	jnz	short su2
  8719                              <1> 	;;pop	dx ; * ;; 14/02/2015
  8720                              <1> 	;pop	es ; **
  8721 000029C7 6658                <1> 	pop	ax ; ***
  8722                              <1> 	;;pop	bx
  8723 000029C9 E9C6000000          <1>         jmp     DISK_RESET
  8724                              <1> su2:
  8725 000029CE 803D[54710000]00    <1> 	cmp	byte [LBAMode], 0
  8726 000029D5 7661                <1> 	jna	short su3
  8727                              <1> 	;
  8728                              <1> 	; 02/02/2015 (LBA read/write function calls)
  8729 000029D7 80FC1B              <1> 	cmp	ah, 1Bh
  8730 000029DA 720B                <1> 	jb	short lbarw1
  8731 000029DC 80FC1C              <1> 	cmp	ah, 1Ch
  8732 000029DF 775C                <1> 	ja 	short invldfnc
  8733                              <1> 	;;pop	dx ; * ; 14/02/2015
  8734                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  8735 000029E1 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  8736                              <1> 	;; 14/02/2015
  8737 000029E3 88D1                <1> 	mov	cl, dl ; 14/02/2015
  8738                              <1> 	;;mov	dx, bx
  8739                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  8740                              <1> 	;;mov	bx, di
  8741                              <1> 	;mov	si, di ; Buffer offset
  8742 000029E5 EB31                <1> 	jmp	short lbarw2
  8743                              <1> lbarw1:
  8744                              <1> 	; convert CHS to LBA
  8745                              <1> 	;
  8746                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  8747                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  8748                              <1> 	;	+ Sector - 1
  8749 000029E7 6652                <1> 	push	dx ; * ;; 14/02/2015
  8750                              <1> 	;xor	dh, dh
  8751 000029E9 31D2                <1> 	xor	edx, edx
  8752                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  8753 000029EB 8A530E              <1> 	mov	dl, [ebx+14]
  8754                              <1> 	;xor	ah, ah
  8755 000029EE 31C0                <1> 	xor	eax, eax
  8756                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  8757 000029F0 8A4302              <1> 	mov	al, [ebx+2]
  8758 000029F3 FEC8                <1> 	dec	al
  8759 000029F5 6640                <1> 	inc	ax		; 0 =  256
  8760 000029F7 66F7E2              <1> 	mul 	dx
  8761                              <1> 		; AX = # of Heads" * Sectors/Track
  8762 000029FA 6689CA              <1> 	mov	dx, cx
  8763                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  8764 000029FD 83E13F              <1> 	and	ecx, 3fh
  8765 00002A00 86D6                <1> 	xchg	dl, dh
  8766 00002A02 C0EE06              <1> 	shr	dh, 6
  8767                              <1> 		; DX = cylinder (0 to 1023)
  8768                              <1> 	;mul 	dx
  8769                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  8770 00002A05 F7E2                <1> 	mul	edx
  8771 00002A07 FEC9                <1> 	dec	cl  ; sector - 1
  8772                              <1> 	;add	ax, cx
  8773                              <1> 	;adc	dx, 0
  8774                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  8775 00002A09 01C8                <1> 	add	eax, ecx
  8776 00002A0B 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  8777                              <1> 	;push	dx
  8778                              <1> 	;push	ax
  8779 00002A0D 50                  <1> 	push	eax
  8780                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  8781 00002A0E 8A430E              <1> 	mov	al, [ebx+14]
  8782 00002A11 F6E5                <1> 	mul	ch
  8783                              <1> 		;  AX = Head * Sectors/Track
  8784 00002A13 6699                <1>         cwd
  8785                              <1> 	;pop	dx
  8786 00002A15 5A                  <1> 	pop	edx
  8787                              <1> 	;add	ax, dx
  8788                              <1> 	;pop	dx
  8789                              <1> 	;adc	dx, 0 ; add carry bit
  8790 00002A16 01D0                <1> 	add	eax, edx
  8791                              <1> lbarw2:
  8792 00002A18 29D2                <1> 	sub	edx, edx ; 21/02/2015
  8793 00002A1A 88CA                <1> 	mov	dl, cl ; 21/02/2015
  8794 00002A1C C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  8795                              <1> 				; NOTE: Features register (1F1h, 171h)
  8796                              <1> 				; is not used for ATA device R/W functions. 
  8797                              <1> 				; It is old/obsolete 'write precompensation'
  8798                              <1> 				; register and error register
  8799                              <1> 				; for old ATA/IDE devices.
  8800                              <1> 	; 18/01/2014
  8801                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  8802 00002A20 8A0D[586B0000]      <1> 	mov	cl, [hf_m_s]
  8803                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  8804                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  8805                              <1> 				; bit 6 = 1 = LBA mode
  8806                              <1> 				; bit 7 = 1
  8807 00002A26 80C90E              <1> 	or	cl, 0Eh ; 1110b
  8808                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  8809 00002A29 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  8810 00002A2E C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  8811                              <1> 	;or	dh, ch
  8812 00002A31 09C8                <1> 	or	eax, ecx	
  8813                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  8814                              <1> 				  ; (Sector Number Register)
  8815                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  8816                              <1> 				  ; (Cylinder Low Register)
  8817                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  8818                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  8819                              <1> 				  ; (Cylinder High Register)
  8820                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  8821                              <1> 				  ; (Drive/Head Register)
  8822                              <1> 	
  8823                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  8824 00002A33 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  8825                              <1> 	;14/02/2015
  8826                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  8827 00002A36 EB38                <1> 	jmp	short su4
  8828                              <1> su3:
  8829                              <1> 	; 02/02/2015 
  8830                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  8831 00002A38 80FC14              <1> 	cmp 	ah, 14h
  8832 00002A3B 7604                <1> 	jna 	short chsfnc
  8833                              <1> invldfnc:
  8834                              <1>         ; 14/02/2015  
  8835                              <1> 	;pop	es ; **
  8836 00002A3D 6658                <1>         pop     ax ; ***
  8837                              <1>         ;jmp     short BAD_COMMAND_POP
  8838 00002A3F EB49                <1>         jmp     short BAD_COMMAND
  8839                              <1> chsfnc:	
  8840                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  8841 00002A41 668B4305            <1> 	mov	ax, [ebx+5]
  8842 00002A45 66C1E802            <1> 	SHR	AX,2
  8843 00002A49 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  8844                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  8845                              <1> 	;;PUSH	DX
  8846                              <1> 	;;MOV	DX,[HF_REG_PORT]
  8847                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  8848                              <1> 	;;POP	DX ; * 
  8849                              <1> 	;;POP	ES ; **
  8850                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  8851                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  8852                              <1> 	;;OR	AH,AL
  8853                              <1> 	;;MOV	[CONTROL_BYTE],AH
  8854                              <1> 	;
  8855 00002A4C 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  8856 00002A4E 243F                <1> 	AND	AL,3FH
  8857 00002A50 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  8858 00002A53 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  8859 00002A56 88C8                <1> 	MOV	AL,CL
  8860 00002A58 C0E806              <1> 	SHR	AL,6
  8861 00002A5B 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  8862                              <1> 	;;05/01/2015
  8863                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  8864 00002A5E A0[586B0000]        <1> 	mov	al, [hf_m_s]
  8865 00002A63 C0E004              <1> 	SHL	AL,4
  8866 00002A66 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  8867 00002A69 08F0                <1> 	OR	AL,DH
  8868                              <1> 	;OR	AL,80H or 20H
  8869 00002A6B 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  8870 00002A6D 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  8871                              <1> su4:
  8872                              <1> 	;POP	ES ; **
  8873                              <1>         ;; 14/02/2015
  8874                              <1>         ;;POP   AX
  8875                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  8876                              <1>         ;;PUSH  AX
  8877                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  8878                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  8879                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  8880 00002A70 6658                <1>         pop     ax ; ***
  8881 00002A72 8845F9              <1>         mov     [CMD_BLOCK+1], al
  8882 00002A75 29DB                <1>         sub	ebx, ebx
  8883 00002A77 88E3                <1> 	mov     bl, ah
  8884                              <1>         ;xor     bh, bh
  8885                              <1>         ;sal     bx, 1
  8886 00002A79 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  8887                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  8888                              <1>         ;;CMP   AX,M1L                  ; TEST WITHIN RANGE
  8889                              <1>         ;;JNB   short BAD_COMMAND_POP
  8890                              <1>         ;cmp     bx, M1L
  8891 00002A7D 83FB74              <1> 	cmp	ebx, M1L
  8892 00002A80 7308                <1> 	jnb	short BAD_COMMAND
  8893                              <1>         ;xchg    bx, si
  8894 00002A82 87DE                <1>         xchg	ebx, esi
  8895                              <1> 	;;;POP	AX			; RESTORE AX
  8896                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  8897                              <1> 	
  8898                              <1> 	;;PUSH	CX
  8899                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  8900                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  8901                              <1> 	;SHR	CX,4
  8902                              <1> 	;MOV	AX,ES
  8903                              <1> 	;ADD	AX,CX
  8904                              <1> 	;MOV	ES,AX
  8905                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  8906                              <1> 	;;POP	AX
  8907                              <1> 	;;POP	CX
  8908                              <1> 	;;JMP	word [CS:SI+M1]
  8909                              <1> 	;jmp	word [SI+M1]
  8910 00002A84 FFA6[D2280000]      <1> 	jmp	dword [esi+M1]
  8911                              <1> ;;BAD_COMMAND_POP:
  8912                              <1> ;;	POP	AX
  8913                              <1> ;;	POP	BX
  8914                              <1> BAD_COMMAND:
  8915 00002A8A C605[3F710000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  8916 00002A91 B000                <1> 	MOV	AL,0
  8917 00002A93 C3                  <1> 	RETn
  8918                              <1> 
  8919                              <1> ;----------------------------------------
  8920                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  8921                              <1> ;----------------------------------------
  8922                              <1> 
  8923                              <1> ; 18-1-2015 : one controller reset (not other one)
  8924                              <1> 
  8925                              <1> DISK_RESET:
  8926 00002A94 FA                  <1> 	CLI
  8927 00002A95 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  8928                              <1> 	;JMP	$+2
  8929                              <1> 	IODELAY
  8930 00002A97 EB00                <2>  jmp short $+2
  8931 00002A99 EB00                <2>  jmp short $+2
  8932                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  8933 00002A9B 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  8934 00002A9D E6A1                <1> 	OUT	INTB01,AL
  8935 00002A9F FB                  <1> 	STI				; START INTERRUPTS
  8936                              <1> 	; 14/02/2015
  8937 00002AA0 6689D7              <1> 	mov	di, dx	
  8938                              <1> 	; 04/01/2015
  8939                              <1> 	;xor	di,di
  8940                              <1> drst0:
  8941 00002AA3 B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  8942                              <1> 	;MOV	DX,HF_REG_PORT
  8943 00002AA5 668B15[566B0000]    <1> 	MOV	DX,[HF_REG_PORT]
  8944 00002AAC EE                  <1> 	OUT	DX,AL			; RESET
  8945                              <1> ;	MOV	CX,10			; DELAY COUNT
  8946                              <1> ;DRD:	DEC	CX
  8947                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  8948                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  8949 00002AAD B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  8950 00002AB2 E875EBFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  8951                              <1>                                         ; 40 micro seconds)
  8952 00002AB7 A0[41710000]        <1> 	mov	al,[CONTROL_BYTE]
  8953 00002ABC 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  8954 00002ABE EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  8955 00002ABF E80E040000          <1> 	CALL	NOT_BUSY
  8956 00002AC4 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  8957 00002AC6 668B15[546B0000]    <1> 	MOV	DX,[HF_PORT]
  8958 00002ACD FEC2                <1> 	inc	dl  ; HF_PORT+1
  8959                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  8960                              <1>         ;mov     cl, 10
  8961 00002ACF B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  8962                              <1> drst1:
  8963 00002AD4 EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  8964 00002AD5 3C01                <1> 	CMP	AL,1
  8965                              <1> 	; 04/01/2015
  8966 00002AD7 740A                <1> 	jz	short drst2
  8967                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  8968                              <1>         	; Drive/Head Register - bit 4
  8969 00002AD9 E2F9                <1> 	loop	drst1
  8970                              <1> DRERR:	
  8971 00002ADB C605[3F710000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  8972 00002AE2 C3                  <1> 	RETn
  8973                              <1> drst2:
  8974                              <1> 	; 14/02/2015
  8975 00002AE3 6689FA              <1> 	mov	dx,di
  8976                              <1> ;drst3:
  8977                              <1> ;	; 05/01/2015
  8978                              <1> ;	shl 	di,1
  8979                              <1> ;	; 04/01/2015
  8980                              <1> ;	mov	ax,[di+hd_cports]
  8981                              <1> ;	cmp	ax,[HF_REG_PORT]
  8982                              <1> ;	je	short drst4
  8983                              <1> ;	mov	[HF_REG_PORT], ax
  8984                              <1> ;	; 03/01/2015
  8985                              <1> ;	mov	ax,[di+hd_ports]
  8986                              <1> ;       mov     [HF_PORT], ax
  8987                              <1> ;	; 05/01/2014
  8988                              <1> ;	shr	di,1
  8989                              <1> ;	; 04/01/2015
  8990                              <1> ;	jmp	short drst0	; reset other controller
  8991                              <1> ;drst4:
  8992                              <1> ;	; 05/01/2015
  8993                              <1> ;	shr	di,1
  8994                              <1> ;	mov	al,[di+hd_dregs]
  8995                              <1> ;	and	al,10h ; bit 4 only
  8996                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  8997                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  8998                              <1> 	;
  8999 00002AE6 A0[586B0000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  9000 00002AEB A801                <1> 	test	al,1
  9001                              <1> ;	jnz	short drst6
  9002 00002AED 7516                <1>         jnz     short drst4
  9003 00002AEF 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  9004                              <1> ;drst5:
  9005                              <1> drst3:
  9006 00002AF3 E811010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  9007                              <1> 	;mov	dx,di
  9008 00002AF8 E8C9010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  9009                              <1> 	; 04/01/2014
  9010                              <1> ;	inc	di
  9011                              <1> ;	mov	dx,di
  9012                              <1> ;	cmp	dl,[HF_NUM]
  9013                              <1> ;	jb	short drst3
  9014                              <1> ;DRE:
  9015 00002AFD C605[3F710000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  9016 00002B04 C3                  <1> 	RETn
  9017                              <1> ;drst6:
  9018                              <1> drst4:		; Drive/Head Register - bit 4
  9019 00002B05 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  9020                              <1>         ;jmp    short drst5
  9021 00002B09 EBE8                <1>         jmp     short drst3
  9022                              <1> 
  9023                              <1> ;----------------------------------------
  9024                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  9025                              <1> ;----------------------------------------
  9026                              <1> 
  9027                              <1> RETURN_STATUS:
  9028 00002B0B A0[3F710000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  9029 00002B10 C605[3F710000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  9030 00002B17 C3                  <1> 	RETn
  9031                              <1> 
  9032                              <1> ;----------------------------------------
  9033                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  9034                              <1> ;----------------------------------------
  9035                              <1> 
  9036                              <1> DISK_READ:
  9037 00002B18 C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  9038 00002B1C E930020000          <1>         JMP     COMMANDI
  9039                              <1> 
  9040                              <1> ;----------------------------------------
  9041                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  9042                              <1> ;----------------------------------------
  9043                              <1> 
  9044                              <1> DISK_WRITE:
  9045 00002B21 C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  9046 00002B25 E97C020000          <1>         JMP     COMMANDO
  9047                              <1> 
  9048                              <1> ;----------------------------------------
  9049                              <1> ;	DISK VERIFY	     (AH = 04H) :
  9050                              <1> ;----------------------------------------
  9051                              <1> 
  9052                              <1> DISK_VERF:
  9053 00002B2A C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  9054 00002B2E E8EA020000          <1> 	CALL	COMMAND
  9055 00002B33 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  9056 00002B35 E85C030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  9057 00002B3A 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  9058 00002B3C E8E9030000          <1> 	CALL	CHECK_STATUS
  9059                              <1> VERF_EXIT:
  9060 00002B41 C3                  <1> 	RETn
  9061                              <1> 
  9062                              <1> ;----------------------------------------
  9063                              <1> ;	FORMATTING	     (AH = 05H) :
  9064                              <1> ;----------------------------------------
  9065                              <1> 
  9066                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  9067 00002B42 C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  9068                              <1> 	;PUSH	ES
  9069                              <1> 	;PUSH	BX
  9070 00002B46 53                  <1> 	push	ebx
  9071 00002B47 E88E040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  9072                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  9073 00002B4C 8A430E              <1> 	mov	al, [ebx+14]
  9074 00002B4F 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  9075 00002B52 5B                  <1> 	pop	ebx
  9076                              <1> 	;POP	BX
  9077                              <1> 	;POP	ES
  9078 00002B53 E955020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  9079                              <1> 
  9080                              <1> ;----------------------------------------
  9081                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  9082                              <1> ;----------------------------------------
  9083                              <1> 
  9084                              <1> READ_DASD_TYPE:
  9085                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  9086 00002B58 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9087                              <1> 	;PUSH	ES
  9088 00002B59 53                  <1> 	PUSH	eBX
  9089                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  9090                              <1> 	;push	cs
  9091                              <1> 	;pop	ds
  9092 00002B5A 66BB1000            <1>         mov	bx, KDATA
  9093 00002B5E 8EDB                <1> 	mov	ds, bx
  9094                              <1> 	;mov	es, bx
  9095 00002B60 C605[3F710000]00    <1> 	MOV     byte [DISK_STATUS1],0
  9096 00002B67 8A1D[40710000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  9097 00002B6D 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  9098 00002B70 38D3                <1> 	CMP	BL,DL
  9099 00002B72 7625                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  9100 00002B74 E861040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  9101                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  9102 00002B79 8A4302              <1> 	mov	al, [ebx+2]
  9103                              <1> 	;MOV	CL,[ES:BX+14]
  9104 00002B7C 8A4B0E              <1> 	mov	cl, [ebx+14]
  9105 00002B7F F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  9106                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  9107 00002B81 668B0B              <1> 	mov	cx ,[ebx]
  9108                              <1> 	;
  9109                              <1> 	; 02/01/2015 
  9110                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  9111                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  9112 00002B84 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  9113                              <1> 	;
  9114 00002B86 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  9115 00002B89 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  9116 00002B8C 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  9117                              <1> 	;SUB	AX,AX
  9118 00002B8F 28C0                <1> 	sub	al, al
  9119 00002B91 B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  9120 00002B93 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  9121                              <1> 	;POP	ES
  9122 00002B94 1F                  <1> 	POP	DS
  9123 00002B95 F8                  <1> 	CLC				; CLEAR CARRY
  9124                              <1> 	;RETf	2
  9125 00002B96 CA0400              <1> 	retf	4
  9126                              <1> RDT_NOT_PRESENT:
  9127 00002B99 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  9128 00002B9C 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  9129 00002B9F 6689C2              <1> 	MOV	DX,AX
  9130 00002BA2 EBEF                <1> 	JMP	short RDT2
  9131                              <1> 
  9132                              <1> ;----------------------------------------
  9133                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  9134                              <1> ;----------------------------------------
  9135                              <1> 
  9136                              <1> GET_PARM_N:
  9137                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  9138 00002BA4 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9139                              <1> 	;PUSH	ES
  9140 00002BA5 53                  <1> 	PUSH	eBX
  9141                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  9142                              <1> 	;MOV	DS,AX
  9143                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  9144                              <1> 	;JZ	short G0
  9145                              <1> 	;LES	BX,@HF1_TBL_VEC
  9146                              <1> 	;JMP	SHORT G1
  9147                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  9148                              <1> ;G1:
  9149                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  9150                              <1> 	; 22/12/2014
  9151                              <1> 	;push	cs
  9152                              <1> 	;pop	ds
  9153 00002BA6 66BB1000            <1> 	mov	bx, KDATA
  9154 00002BAA 8EDB                <1> 	mov	ds, bx
  9155                              <1> 	;mov	es, bx
  9156                              <1> 	;
  9157 00002BAC 80EA80              <1> 	SUB	DL,80H
  9158 00002BAF 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  9159 00002BB2 7341                <1> 	JAE	short G4
  9160                              <1> 	;
  9161 00002BB4 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  9162                              <1> 	; 22/12/2014
  9163 00002BB6 88D3                <1> 	mov	bl, dl
  9164                              <1> 	;xor	bh, bh  
  9165 00002BB8 C0E302              <1> 	shl	bl, 2			; convert index to offset
  9166                              <1> 	;add	bx, HF_TBL_VEC
  9167 00002BBB 81C3[44710000]      <1> 	add	ebx, HF_TBL_VEC
  9168                              <1> 	;mov	ax, [bx+2]
  9169                              <1> 	;mov	es, ax			; dpt segment
  9170                              <1> 	;mov	bx, [bx]		; dpt offset
  9171 00002BC1 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  9172                              <1> 
  9173 00002BC3 C605[3F710000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9174                              <1>         ;MOV     AX,[ES:BX]              ; MAX NUMBER OF CYLINDERS
  9175 00002BCA 668B03              <1> 	mov	ax, [ebx]
  9176                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  9177 00002BCD 6648                <1> 	dec	ax			; max. cylinder number
  9178 00002BCF 88C5                <1> 	MOV	CH,AL
  9179 00002BD1 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  9180 00002BD5 66D1E8              <1> 	SHR	AX,1
  9181 00002BD8 66D1E8              <1> 	SHR	AX,1
  9182                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  9183 00002BDB 0A430E              <1> 	or	al, [ebx+14]
  9184 00002BDE 88C1                <1> 	MOV	CL,AL
  9185                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  9186 00002BE0 8A7302              <1> 	mov	dh, [ebx+2]
  9187 00002BE3 FECE                <1> 	DEC	DH			; 0-N RANGE
  9188 00002BE5 8A15[40710000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  9189 00002BEB 6629C0              <1> 	SUB	AX,AX
  9190                              <1>         ;27/12/2014 
  9191                              <1> 	; ES:DI = Address of disk parameter table from BIOS
  9192                              <1> 	;(Programmer's Guide to the AMIBIOS - 1993)
  9193                              <1> 	;mov	di, bx			; HDPT offset
  9194 00002BEE 89DF                <1> 	mov	edi, ebx
  9195                              <1> G5:
  9196 00002BF0 5B                  <1> 	POP	eBX			; RESTORE REGISTERS
  9197                              <1> 	;POP	ES
  9198 00002BF1 1F                  <1> 	POP	DS
  9199                              <1> 	;RETf	2
  9200 00002BF2 CA0400              <1> 	retf	4
  9201                              <1> G4:
  9202 00002BF5 C605[3F710000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  9203 00002BFC B407                <1> 	MOV	AH,INIT_FAIL
  9204 00002BFE 28C0                <1> 	SUB	AL,AL
  9205 00002C00 6629D2              <1> 	SUB	DX,DX
  9206 00002C03 6629C9              <1> 	SUB	CX,CX
  9207 00002C06 F9                  <1> 	STC				; SET ERROR FLAG
  9208 00002C07 EBE7                <1> 	JMP	short G5
  9209                              <1> 
  9210                              <1> ;----------------------------------------
  9211                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  9212                              <1> ;----------------------------------------
  9213                              <1> 	; 03/01/2015
  9214                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  9215                              <1> 	; logical sector per logical track
  9216                              <1> 	; and logical heads - 1 would be set but
  9217                              <1> 	; it is seen as it will be good
  9218                              <1> 	; if physical parameters will be set here
  9219                              <1> 	; because, number of heads <= 16.
  9220                              <1> 	; (logical heads usually more than 16)
  9221                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  9222                              <1> 	;	== INT 13h physical parameters
  9223                              <1> 
  9224                              <1> ;INIT_DRV:
  9225                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  9226                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  9227                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  9228                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  9229                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  9230                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  9231                              <1> ;	OR	AH,AL			; TO MAX HEAD
  9232                              <1> ;	MOV	[CMD_BLOCK+5],AH
  9233                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  9234                              <1> ;	MOV	[CMD_BLOCK+1],AL
  9235                              <1> ;	SUB	AX,AX
  9236                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  9237                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  9238                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  9239                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  9240                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  9241                              <1> ;	CALL	CHECK_STATUS
  9242                              <1> ;INIT_EXIT:
  9243                              <1> ;	RETn
  9244                              <1> 
  9245                              <1> ; 04/01/2015
  9246                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  9247                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  9248                              <1> INIT_DRV:
  9249                              <1> 	;xor	ah,ah
  9250 00002C09 31C0                <1> 	xor	eax, eax ; 21/02/2015
  9251 00002C0B B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  9252 00002C0D 3825[54710000]      <1>         cmp     [LBAMode], ah   ; 0
  9253 00002C13 7702                <1> 	ja	short idrv0
  9254 00002C15 B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  9255                              <1> idrv0:
  9256                              <1> 	; DL = drive number (0 based)
  9257 00002C17 E8BE030000          <1> 	call	GET_VEC
  9258                              <1> 	;push	bx
  9259 00002C1C 53                  <1> 	push	ebx ; 21/02/2015
  9260                              <1> 	;add	bx,ax
  9261 00002C1D 01C3                <1> 	add	ebx, eax
  9262                              <1> 	;; 05/01/2015
  9263 00002C1F 8A25[586B0000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  9264                              <1> 	;;and 	ah,1 
  9265 00002C25 C0E404              <1> 	shl	ah,4
  9266 00002C28 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  9267                              <1> 	;mov	al,[es:bx]
  9268 00002C2B 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  9269 00002C2D FEC8                <1> 	dec	al	 ; last head number 
  9270                              <1> 	;and	al,0Fh
  9271 00002C2F 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  9272                              <1> 	;
  9273 00002C31 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  9274 00002C35 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  9275                              <1> 	;pop	bx
  9276 00002C38 5B                  <1> 	pop	ebx
  9277 00002C39 29C0                <1> 	sub	eax, eax ; 21/02/2015
  9278 00002C3B B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  9279 00002C3D 803D[54710000]00    <1> 	cmp	byte [LBAMode], 0
  9280 00002C44 7702                <1> 	ja	short idrv1
  9281 00002C46 B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  9282                              <1> idrv1:
  9283                              <1> 	;xor	ah,ah
  9284                              <1> 	;add	bx,ax
  9285 00002C48 01C3                <1> 	add	ebx, eax ; 21/02/2015
  9286                              <1> 	;mov	al,[es:bx]
  9287                              <1> 			; sector number
  9288 00002C4A 8A03                <1> 	mov	al, [ebx]
  9289 00002C4C 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  9290 00002C4F 28C0                <1> 	sub	al,al
  9291 00002C51 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  9292 00002C54 E8C4010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  9293 00002C59 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  9294 00002C5B E872020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  9295 00002C60 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  9296 00002C62 E8C3020000          <1> 	call	CHECK_STATUS
  9297                              <1> INIT_EXIT:
  9298 00002C67 C3                  <1> 	RETn
  9299                              <1> 
  9300                              <1> ;----------------------------------------
  9301                              <1> ;	READ LONG	     (AH = 0AH) :
  9302                              <1> ;----------------------------------------
  9303                              <1> 
  9304                              <1> RD_LONG:
  9305                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  9306 00002C68 C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  9307 00002C6C E9E0000000          <1>         JMP     COMMANDI
  9308                              <1> 
  9309                              <1> ;----------------------------------------
  9310                              <1> ;	WRITE LONG	     (AH = 0BH) :
  9311                              <1> ;----------------------------------------
  9312                              <1> 
  9313                              <1> WR_LONG:
  9314                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  9315 00002C71 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  9316 00002C75 E92C010000          <1>         JMP     COMMANDO
  9317                              <1> 
  9318                              <1> ;----------------------------------------
  9319                              <1> ;	SEEK		     (AH = 0CH) :
  9320                              <1> ;----------------------------------------
  9321                              <1> 
  9322                              <1> DISK_SEEK:
  9323 00002C7A C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  9324 00002C7E E89A010000          <1> 	CALL	COMMAND
  9325 00002C83 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  9326 00002C85 E80C020000          <1> 	CALL	_WAIT
  9327 00002C8A 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  9328 00002C8C E899020000          <1> 	CALL	CHECK_STATUS
  9329 00002C91 803D[3F710000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  9330 00002C98 7507                <1> 	JNE	short DS_EXIT
  9331 00002C9A C605[3F710000]00    <1>         MOV     byte [DISK_STATUS1],0
  9332                              <1> DS_EXIT:
  9333 00002CA1 C3                  <1> 	RETn
  9334                              <1> 
  9335                              <1> ;----------------------------------------
  9336                              <1> ;	TEST DISK READY      (AH = 10H) :
  9337                              <1> ;----------------------------------------
  9338                              <1> 
  9339                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  9340 00002CA2 E82B020000          <1> 	CALL	NOT_BUSY
  9341 00002CA7 751C                <1> 	JNZ	short TR_EX
  9342 00002CA9 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  9343 00002CAC 668B15[546B0000]    <1> 	MOV	DX,[HF_PORT]
  9344 00002CB3 80C206              <1> 	add	dl,6
  9345 00002CB6 EE                  <1> 	OUT	DX,AL
  9346 00002CB7 E886020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  9347 00002CBC 7507                <1> 	JNZ	short TR_EX
  9348 00002CBE C605[3F710000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  9349                              <1> TR_EX:	
  9350 00002CC5 C3                  <1> 	RETn
  9351                              <1> 
  9352                              <1> ;----------------------------------------
  9353                              <1> ;	RECALIBRATE	     (AH = 11H) :
  9354                              <1> ;----------------------------------------
  9355                              <1> 
  9356                              <1> HDISK_RECAL:
  9357 00002CC6 C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  9358 00002CCA E84E010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  9359 00002CCF 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  9360 00002CD1 E8C0010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  9361 00002CD6 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  9362 00002CD8 E8B9010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  9363 00002CDD 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  9364                              <1> RECAL_X:
  9365 00002CDF E846020000          <1> 	CALL	CHECK_STATUS
  9366 00002CE4 803D[3F710000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  9367 00002CEB 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  9368 00002CED C605[3F710000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9369                              <1> RECAL_EXIT:
  9370 00002CF4 803D[3F710000]00    <1>         CMP     byte [DISK_STATUS1],0
  9371 00002CFB C3                  <1> 	RETn
  9372                              <1> 
  9373                              <1> ;----------------------------------------
  9374                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  9375                              <1> ;----------------------------------------
  9376                              <1> 
  9377                              <1> CTLR_DIAGNOSTIC:
  9378 00002CFC FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  9379 00002CFD E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9380                              <1> 	;AND	AL,0BFH
  9381 00002CFF 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  9382                              <1> 	;JMP	$+2
  9383                              <1> 	IODELAY
  9384 00002D01 EB00                <2>  jmp short $+2
  9385 00002D03 EB00                <2>  jmp short $+2
  9386 00002D05 E6A1                <1> 	OUT	INTB01,AL
  9387                              <1> 	IODELAY
  9388 00002D07 EB00                <2>  jmp short $+2
  9389 00002D09 EB00                <2>  jmp short $+2
  9390 00002D0B E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9391 00002D0D 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9392                              <1> 	;JMP	$+2
  9393                              <1> 	IODELAY
  9394 00002D0F EB00                <2>  jmp short $+2
  9395 00002D11 EB00                <2>  jmp short $+2
  9396 00002D13 E621                <1> 	OUT	INTA01,AL
  9397 00002D15 FB                  <1> 	STI
  9398 00002D16 E8B7010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  9399 00002D1B 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  9400                              <1> 	;MOV	DX, HF_PORT+7
  9401 00002D1D 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]
  9402 00002D24 80C207              <1> 	add	dl, 7
  9403 00002D27 B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  9404 00002D29 EE                  <1> 	OUT	DX,AL
  9405 00002D2A E8A3010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  9406 00002D2F B480                <1> 	MOV	AH,TIME_OUT
  9407 00002D31 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  9408                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  9409 00002D33 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]
  9410 00002D3A FEC2                <1> 	inc	dl
  9411 00002D3C EC                  <1> 	IN	AL,DX
  9412 00002D3D A2[36710000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  9413 00002D42 B400                <1> 	MOV	AH,0
  9414 00002D44 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  9415 00002D46 7402                <1> 	JE	SHORT CD_EXIT
  9416 00002D48 B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  9417                              <1> CD_EXIT:
  9418 00002D4A 8825[3F710000]      <1> 	MOV	[DISK_STATUS1],AH
  9419 00002D50 C3                  <1> 	RETn
  9420                              <1> 
  9421                              <1> ;----------------------------------------
  9422                              <1> ; COMMANDI				:
  9423                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  9424                              <1> ;	NSECTOR RETURNS ZERO		:
  9425                              <1> ;----------------------------------------
  9426                              <1> COMMANDI:
  9427 00002D51 E85A020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9428 00002D56 724D                <1> 	JC	short CMD_ABORT
  9429                              <1> 	;MOV	DI,BX
  9430 00002D58 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  9431 00002D5A E8BE000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9432 00002D5F 7544                <1> 	JNZ	short CMD_ABORT
  9433                              <1> CMD_I1:
  9434 00002D61 E830010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  9435 00002D66 753D                <1> 	JNZ	short TM_OUT		; TIME OUT
  9436                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  9437 00002D68 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  9438                              <1> 	;MOV	DX,HF_PORT
  9439 00002D6D 668B15[546B0000]    <1> 	mov	dx,[HF_PORT]
  9440 00002D74 FA                  <1> 	CLI
  9441 00002D75 FC                  <1> 	CLD
  9442 00002D76 F3666D              <1> 	REP	INSW			; GET THE SECTOR
  9443 00002D79 FB                  <1> 	STI
  9444 00002D7A F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  9445 00002D7E 7419                <1> 	JZ	CMD_I3
  9446 00002D80 E87A010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9447 00002D85 721E                <1> 	JC	short TM_OUT
  9448                              <1> 	;MOV	DX,HF_PORT
  9449 00002D87 668B15[546B0000]    <1> 	mov	dx,[HF_PORT]
  9450                              <1> 	;MOV	CX,4			; GET ECC BYTES
  9451 00002D8E B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  9452 00002D93 EC                  <1> CMD_I2: IN	AL,DX
  9453                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  9454 00002D94 8807                <1> 	mov 	[edi], al ; 21/02/2015
  9455 00002D96 47                  <1> 	INC	eDI
  9456 00002D97 E2FA                <1> 	LOOP	CMD_I2
  9457 00002D99 E88C010000          <1> CMD_I3: CALL	CHECK_STATUS
  9458 00002D9E 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  9459 00002DA0 FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  9460 00002DA3 75BC                <1> 	JNZ	SHORT CMD_I1
  9461                              <1> CMD_ABORT:
  9462 00002DA5 C3                  <1> TM_OUT: RETn
  9463                              <1> 
  9464                              <1> ;----------------------------------------
  9465                              <1> ; COMMANDO				:
  9466                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  9467                              <1> ;	NSECTOR RETURNS ZERO		:
  9468                              <1> ;----------------------------------------
  9469                              <1> COMMANDO:
  9470 00002DA6 E805020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9471 00002DAB 72F8                <1> 	JC	short CMD_ABORT
  9472 00002DAD 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  9473 00002DAF E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9474 00002DB4 75EF                <1> 	JNZ	short CMD_ABORT
  9475 00002DB6 E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9476 00002DBB 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  9477                              <1> CMD_O1: ;PUSH	DS
  9478                              <1> 	;PUSH	ES			; MOVE ES TO DS
  9479                              <1> 	;POP	DS
  9480                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  9481                              <1> 	;MOV	DX,HF_PORT
  9482                              <1> 	; 01/02/2015
  9483 00002DBD 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]
  9484                              <1> 	;push	es
  9485                              <1> 	;pop	ds
  9486                              <1> 	;mov	cx, 256
  9487 00002DC4 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  9488 00002DC9 FA                  <1> 	CLI
  9489 00002DCA FC                  <1> 	CLD
  9490 00002DCB F3666F              <1> 	REP	OUTSW
  9491 00002DCE FB                  <1> 	STI
  9492                              <1> 	;POP	DS			; RESTORE DS
  9493 00002DCF F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  9494 00002DD3 7419                <1> 	JZ	short CMD_O3
  9495 00002DD5 E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9496 00002DDA 72C9                <1> 	JC	short TM_OUT
  9497                              <1> 	;MOV	DX,HF_PORT
  9498 00002DDC 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]
  9499                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  9500 00002DE3 B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  9501                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  9502 00002DE8 8A06                <1> 	mov	al, [esi]
  9503 00002DEA EE                  <1> 	OUT	DX,AL
  9504 00002DEB 46                  <1> 	INC	eSI
  9505 00002DEC E2FA                <1> 	LOOP	CMD_O2
  9506                              <1> CMD_O3:
  9507 00002DEE E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  9508 00002DF3 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  9509 00002DF5 E830010000          <1> 	CALL	CHECK_STATUS
  9510 00002DFA 75A9                <1> 	JNZ	short CMD_ABORT
  9511 00002DFC F605[35710000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  9512 00002E03 75B8                <1> 	JNZ	SHORT CMD_O1
  9513                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  9514 00002E05 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]
  9515                              <1> 	;add	dl, 2
  9516 00002E0C FEC2                <1> 	inc	dl
  9517 00002E0E FEC2                <1> 	inc	dl
  9518 00002E10 EC                  <1> 	IN	AL,DX			;
  9519 00002E11 A8FF                <1> 	TEST	AL,0FFH 		;
  9520 00002E13 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  9521 00002E15 C605[3F710000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  9522                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  9523                              <1> CMD_O4:
  9524 00002E1C C3                  <1> 	RETn
  9525                              <1> 
  9526                              <1> ;--------------------------------------------------------
  9527                              <1> ; COMMAND						:
  9528                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  9529                              <1> ; OUTPUT						:
  9530                              <1> ;	BL = STATUS					:
  9531                              <1> ;	BH = ERROR REGISTER				:
  9532                              <1> ;--------------------------------------------------------
  9533                              <1> 
  9534                              <1> COMMAND:
  9535 00002E1D 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  9536                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  9537                              <1> COMMAND1:
  9538                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  9539 00002E1E E87FFEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  9540                              <1> 	;;POP	CX
  9541 00002E23 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  9542 00002E25 803D[3F710000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  9543                              <1> 	;JZ	short CMD_TIMEOUT
  9544                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  9545                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  9546 00002E2C 7507                <1> 	jne	short COMMAND4
  9547                              <1> CMD_TIMEOUT:
  9548 00002E2E C605[3F710000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9549                              <1> COMMAND4:
  9550 00002E35 5B                  <1> 	POP	eBX
  9551 00002E36 803D[3F710000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  9552 00002E3D C3                  <1> 	RETn
  9553                              <1> COMMAND2:
  9554 00002E3E 5B                  <1> 	POP	eBX
  9555 00002E3F 57                  <1> 	PUSH	eDI
  9556 00002E40 C605[37710000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  9557 00002E47 FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  9558 00002E48 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9559                              <1> 	;AND	AL,0BFH
  9560 00002E4A 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  9561                              <1> 	;JMP	$+2
  9562                              <1> 	IODELAY
  9563 00002E4C EB00                <2>  jmp short $+2
  9564 00002E4E EB00                <2>  jmp short $+2
  9565 00002E50 E6A1                <1> 	OUT	INTB01,AL
  9566 00002E52 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9567 00002E54 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9568                              <1> 	;JMP	$+2
  9569                              <1> 	IODELAY
  9570 00002E56 EB00                <2>  jmp short $+2
  9571 00002E58 EB00                <2>  jmp short $+2
  9572 00002E5A E621                <1> 	OUT	INTA01,AL
  9573 00002E5C FB                  <1> 	STI
  9574 00002E5D 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  9575                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  9576 00002E5F 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]
  9577 00002E66 FEC2                <1> 	inc	dl
  9578 00002E68 F605[41710000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  9579 00002E6F 7411                <1> 	JZ	short COMMAND3
  9580 00002E71 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  9581 00002E74 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  9582 00002E76 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  9583 00002E78 7208                <1> 	JB	short COMMAND3
  9584 00002E7A 3C40                <1> 	CMP	AL,40H
  9585 00002E7C 7704                <1> 	JA	short COMMAND3
  9586 00002E7E 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  9587                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  9588                              <1> COMMAND3:
  9589 00002E82 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  9590 00002E86 EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  9591                              <1> 	IODELAY
  9592 00002E87 EB00                <2>  jmp short $+2
  9593 00002E89 EB00                <2>  jmp short $+2
  9594 00002E8B 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  9595 00002E8C 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  9596 00002E8E 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  9597 00002E92 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  9598 00002E94 5F                  <1> 	POP	eDI
  9599 00002E95 C3                  <1> 	RETn				; ZERO FLAG IS SET
  9600                              <1> 
  9601                              <1> ;CMD_TIMEOUT:
  9602                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9603                              <1> ;COMMAND4:
  9604                              <1> ;	POP	BX
  9605                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9606                              <1> ;	RETn
  9607                              <1> 
  9608                              <1> ;----------------------------------------
  9609                              <1> ;	WAIT FOR INTERRUPT		:
  9610                              <1> ;----------------------------------------
  9611                              <1> ;WAIT:
  9612                              <1> _WAIT:
  9613 00002E96 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  9614                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  9615                              <1> 	;CLC
  9616                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  9617                              <1> 	;INT	15H
  9618                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  9619                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  9620                              <1> 
  9621                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  9622                              <1> 	;; 21/02/2015
  9623                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  9624                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  9625 00002E97 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  9626                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  9627                              <1> ;-----	WAIT LOOP
  9628                              <1> 
  9629                              <1> WT1:	
  9630                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
  9631 00002E9C F605[37710000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  9632                              <1> 	;LOOPZ	WT1
  9633 00002EA3 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
  9634                              <1> 	;DEC	BL
  9635                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
  9636                              <1> 
  9637                              <1> WT1_hi:
  9638 00002EA5 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  9639 00002EA7 A810                <1> 	test	al, 10h			; transition on memory
  9640 00002EA9 75FA                <1> 	jnz	short WT1_hi		; refresh.
  9641                              <1> WT1_lo:
  9642 00002EAB E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  9643 00002EAD A810                <1> 	test	al, 10h			
  9644 00002EAF 74FA                <1> 	jz	short WT1_lo
  9645 00002EB1 E2E9                <1> 	loop	WT1
  9646                              <1> 	;;or	bl, bl
  9647                              <1> 	;;jz	short WT2	
  9648                              <1> 	;;dec	bl
  9649                              <1> 	;;jmp	short WT1
  9650                              <1> 	;dec	bl
  9651                              <1> 	;jnz	short WT1	
  9652                              <1> 
  9653 00002EB3 C605[3F710000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  9654 00002EBA EB0E                <1> 	JMP	SHORT WT4
  9655 00002EBC C605[3F710000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  9656 00002EC3 C605[37710000]00    <1> 	MOV	byte [HF_INT_FLAG],0
  9657 00002ECA 803D[3F710000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9658 00002ED1 C3                  <1> 	RETn
  9659                              <1> 
  9660                              <1> ;----------------------------------------
  9661                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  9662                              <1> ;----------------------------------------
  9663                              <1> NOT_BUSY:
  9664 00002ED2 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  9665                              <1> 	;PUSH	eBX
  9666                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  9667 00002ED3 668B15[546B0000]    <1> 	mov	DX, [HF_PORT]
  9668 00002EDA 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  9669                              <1> 	;MOV	BL,DELAY_1
  9670                              <1> 					; wait for 10 seconds
  9671                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  9672                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  9673                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  9674 00002EDD B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  9675                              <1> 	;
  9676                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
  9677                              <1> NB1:	
  9678 00002EE2 EC                  <1> 	IN	AL,DX			; CHECK STATUS
  9679                              <1> 	;TEST	AL,ST_BUSY
  9680 00002EE3 2480                <1> 	and	al, ST_BUSY
  9681                              <1> 	;LOOPNZ	NB1
  9682 00002EE5 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
  9683                              <1> 	;DEC	BL			
  9684                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
  9685                              <1> 
  9686 00002EE7 E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  9687 00002EE9 A810                <1> 	TEST	AL,010H			; transition on memory
  9688 00002EEB 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  9689 00002EED E461                <1> NB1_lo: IN	AL,SYS1
  9690 00002EEF A810                <1> 	TEST	AL,010H
  9691 00002EF1 74FA                <1> 	JZ	short NB1_lo
  9692 00002EF3 E2ED                <1> 	LOOP	NB1
  9693                              <1> 	;dec	bl
  9694                              <1> 	;jnz	short NB1
  9695                              <1> 	;
  9696                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  9697                              <1> ;;	jb	short NB1
  9698                              <1> 	;
  9699                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
  9700                              <1> 	;JMP	SHORT NB3
  9701 00002EF5 B080                <1> 	mov	al, TIME_OUT
  9702                              <1> NB2:	
  9703                              <1> 	;MOV	byte [DISK_STATUS1],0
  9704                              <1> ;NB3:	
  9705                              <1> 	;POP	eBX
  9706 00002EF7 A2[3F710000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  9707                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9708 00002EFC 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  9709 00002EFE C3                  <1> 	RETn
  9710                              <1> 
  9711                              <1> ;----------------------------------------
  9712                              <1> ;	WAIT FOR DATA REQUEST		:
  9713                              <1> ;----------------------------------------
  9714                              <1> WAIT_DRQ:
  9715                              <1> 	;MOV	CX,DELAY_3
  9716                              <1> 	;MOV	DX,HF_PORT+7
  9717 00002EFF 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]
  9718 00002F06 80C207              <1> 	add	dl, 7
  9719                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
  9720                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  9721                              <1> 					; (but it is written as 2000
  9722                              <1> 					; micro seconds in ATORGS.ASM file
  9723                              <1> 					; of Award Bios - 1999, D1A0622)
  9724 00002F09 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  9725 00002F0E EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  9726 00002F0F A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  9727 00002F11 7516                <1> 	JNZ	short WQ_OK
  9728                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  9729                              <1> WQ_hi:	
  9730 00002F13 E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  9731 00002F15 A810                <1> 	TEST	AL,010H			; transition on memory
  9732 00002F17 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  9733 00002F19 E461                <1> WQ_lo:  IN      AL,SYS1
  9734 00002F1B A810                <1> 	TEST	AL,010H
  9735 00002F1D 74FA                <1> 	JZ	SHORT WQ_lo
  9736 00002F1F E2ED                <1> 	LOOP	WQ_1
  9737                              <1> 
  9738 00002F21 C605[3F710000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  9739 00002F28 F9                  <1> 	STC
  9740                              <1> WQ_OK:
  9741 00002F29 C3                  <1> 	RETn
  9742                              <1> ;WQ_OK:	;CLC
  9743                              <1> ;	RETn
  9744                              <1> 
  9745                              <1> ;----------------------------------------
  9746                              <1> ;	CHECK FIXED DISK STATUS 	:
  9747                              <1> ;----------------------------------------
  9748                              <1> CHECK_STATUS:
  9749 00002F2A E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  9750 00002F2F 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  9751 00002F31 A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  9752 00002F33 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  9753 00002F35 E847000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  9754                              <1> CHECK_S1:
  9755 00002F3A 803D[3F710000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  9756 00002F41 C3                  <1> 	RETn
  9757                              <1> 
  9758                              <1> ;----------------------------------------
  9759                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  9760                              <1> ;----------------------------------------
  9761                              <1> CHECK_ST:
  9762                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
  9763 00002F42 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]
  9764 00002F49 80C207              <1> 	add	dl, 7
  9765 00002F4C EC                  <1> 	IN	AL,DX
  9766 00002F4D A2[35710000]        <1> 	MOV	[HF_STATUS],AL
  9767 00002F52 B400                <1> 	MOV	AH,0
  9768 00002F54 A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  9769 00002F56 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  9770 00002F58 B4CC                <1> 	MOV	AH,WRITE_FAULT
  9771 00002F5A A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  9772 00002F5C 7514                <1> 	JNZ	short CKST_EXIT
  9773 00002F5E B4AA                <1> 	MOV	AH,NOT_RDY
  9774 00002F60 A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  9775 00002F62 740E                <1> 	JZ	short CKST_EXIT
  9776 00002F64 B440                <1> 	MOV	AH,BAD_SEEK
  9777 00002F66 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  9778 00002F68 7408                <1> 	JZ	short CKST_EXIT
  9779 00002F6A B411                <1> 	MOV	AH,DATA_CORRECTED
  9780 00002F6C A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  9781 00002F6E 7502                <1> 	JNZ	short CKST_EXIT
  9782 00002F70 B400                <1> 	MOV	AH,0
  9783                              <1> CKST_EXIT:
  9784 00002F72 8825[3F710000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  9785 00002F78 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  9786 00002F7B 7403                <1> 	JZ	short CKST_EX1
  9787 00002F7D 80FC00              <1> 	CMP	AH,0
  9788                              <1> CKST_EX1:
  9789 00002F80 C3                  <1> 	RETn
  9790                              <1> 
  9791                              <1> ;----------------------------------------
  9792                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  9793                              <1> ;----------------------------------------
  9794                              <1> CHECK_ER:
  9795                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
  9796 00002F81 668B15[546B0000]    <1> 	mov	dx, [HF_PORT]		;
  9797 00002F88 FEC2                <1> 	inc	dl
  9798 00002F8A EC                  <1> 	IN	AL,DX
  9799 00002F8B A2[36710000]        <1> 	MOV	[HF_ERROR],AL
  9800 00002F90 53                  <1> 	PUSH	eBX ; 21/02/2015
  9801 00002F91 B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  9802 00002F96 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  9803 00002F98 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  9804 00002F9A E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  9805 00002F9C BB[486B0000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  9806 00002FA1 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  9807                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  9808                              <1> 	;mov	ah, [bx]
  9809 00002FA3 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  9810 00002FA5 8825[3F710000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  9811 00002FAB 5B                  <1> 	POP	eBX
  9812 00002FAC 80FC00              <1> 	CMP	AH,0
  9813 00002FAF C3                  <1> 	RETn
  9814                              <1> 
  9815                              <1> ;--------------------------------------------------------
  9816                              <1> ; CHECK_DMA						:
  9817                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  9818                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  9819                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  9820                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  9821                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  9822                              <1> ;  -ERROR OTHERWISE					:
  9823                              <1> ;--------------------------------------------------------
  9824                              <1> CHECK_DMA:
  9825 00002FB0 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  9826 00002FB2 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  9827 00002FB6 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  9828 00002FBA 7404                <1> 	JZ	short CKD1
  9829 00002FBC 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  9830 00002FC0 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  9831 00002FC3 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  9832 00002FC5 7208                <1> 	JB	short CKDERR		; TOO MANY
  9833 00002FC7 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  9834 00002FC9 7204                <1> 	JB	short CKDERR		; ERROR
  9835 00002FCB F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  9836 00002FCC 6658                <1> 	POP	AX
  9837 00002FCE C3                  <1> 	RETn				; NORMAL RETURN
  9838 00002FCF F9                  <1> CKDERR: STC				; INDICATE ERROR
  9839 00002FD0 C605[3F710000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  9840 00002FD7 6658                <1> 	POP	AX
  9841 00002FD9 C3                  <1> 	RETn
  9842                              <1> 
  9843                              <1> ;----------------------------------------
  9844                              <1> ;	SET UP ES:BX-> DISK PARMS	:
  9845                              <1> ;----------------------------------------
  9846                              <1> 					
  9847                              <1> ; INPUT -> DL = 0 based drive number
  9848                              <1> ; OUTPUT -> ES:BX = disk parameter table address
  9849                              <1> 
  9850                              <1> GET_VEC:
  9851                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
  9852                              <1> 	;MOV	ES,AX
  9853                              <1> 	;TEST	DL,1
  9854                              <1> 	;JZ	short GV_0
  9855                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  9856                              <1> ;	JMP	SHORT GV_EXIT
  9857                              <1> ;GV_0:
  9858                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  9859                              <1> ;
  9860                              <1> 	;xor	bh, bh
  9861 00002FDA 31DB                <1> 	xor	ebx, ebx
  9862 00002FDC 88D3                <1> 	mov	bl, dl
  9863                              <1> 	;;02/01/2015
  9864                              <1> 	;;shl	bl, 1			; port address offset
  9865                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  9866                              <1> 	;;shl	bl, 1			; dpt pointer offset
  9867 00002FDE C0E302              <1> 	shl	bl, 2	;;
  9868                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  9869 00002FE1 81C3[44710000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  9870                              <1> 	;push	word [bx+2]		; dpt segment
  9871                              <1> 	;pop	es
  9872                              <1> 	;mov	bx, [bx]		; dpt offset
  9873 00002FE7 8B1B                <1> 	mov	ebx, [ebx]		
  9874                              <1> ;GV_EXIT:
  9875 00002FE9 C3                  <1> 	RETn
  9876                              <1> 
  9877                              <1> hdc1_int: ; 21/02/2015
  9878                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  9879                              <1> ;								:
  9880                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  9881                              <1> ;								:
  9882                              <1> ;----------------------------------------------------------------
  9883                              <1> 
  9884                              <1> ; 22/12/2014
  9885                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  9886                              <1> ;	 '11/15/85'
  9887                              <1> ; AWARD BIOS 1999 (D1A0622) 
  9888                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  9889                              <1> 
  9890                              <1> ;int_76h:
  9891                              <1> HD_INT:
  9892 00002FEA 6650                <1> 	PUSH	AX
  9893 00002FEC 1E                  <1> 	PUSH	DS
  9894                              <1> 	;CALL	DDS
  9895                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  9896 00002FED 66B81000            <1> 	mov	ax, KDATA
  9897 00002FF1 8ED8                <1> 	mov 	ds, ax
  9898                              <1> 	;
  9899                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  9900                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
  9901 00002FF3 C605[37710000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  9902                              <1> 	;
  9903 00002FFA 6652                <1> 	push	dx
  9904 00002FFC 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  9905                              <1> 					; Clear Controller
  9906                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  9907 00003000 EC                  <1> 	in	al, dx			;
  9908 00003001 665A                <1> 	pop	dx
  9909                              <1> 	NEWIODELAY
  9910 00003003 E6EB                <2>  out 0ebh,al
  9911                              <1> 	;
  9912 00003005 B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  9913 00003007 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  9914                              <1> 	;JMP	$+2			; WAIT
  9915                              <1> 	NEWIODELAY
  9916 00003009 E6EB                <2>  out 0ebh,al
  9917 0000300B E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  9918 0000300D 1F                  <1> 	POP	DS
  9919                              <1> 	;STI				; RE-ENABLE INTERRUPTS
  9920                              <1> 	;MOV	AX,9100H		; DEVICE POST
  9921                              <1> 	;INT	15H			;  INTERRUPT
  9922                              <1> irq15_iret: ; 25/02/2015
  9923 0000300E 6658                <1> 	POP	AX
  9924 00003010 CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  9925                              <1> 
  9926                              <1> hdc2_int: ; 21/02/2015
  9927                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
  9928                              <1> ;								:
  9929                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  9930                              <1> ;								:
  9931                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9932                              <1> 
  9933                              <1> ;int_77h:
  9934                              <1> HD1_INT:
  9935 00003011 6650                <1> 	PUSH	AX
  9936                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  9937                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  9938 00003013 B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  9939 00003015 E6A0                <1> 	out	0A0h, al
  9940 00003017 EB00                <1>         jmp short $+2
  9941 00003019 EB00                <1> 	jmp short $+2
  9942 0000301B E4A0                <1> 	in	al, 0A0h
  9943 0000301D 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  9944 0000301F 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  9945                              <1> 	;
  9946 00003021 1E                  <1> 	PUSH	DS
  9947                              <1> 	;CALL	DDS
  9948                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  9949 00003022 66B81000            <1> 	mov	ax, KDATA
  9950 00003026 8ED8                <1> 	mov 	ds, ax
  9951                              <1> 	;
  9952                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  9953                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
  9954 00003028 800D[37710000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  9955                              <1> 	;
  9956 0000302F 6652                <1> 	push	dx
  9957 00003031 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  9958                              <1> 					; Clear Controller (Award BIOS 1999)
  9959 00003035 EBC9                <1> 	jmp	short Clear_IRQ1415
  9960                              <1> 
  9961                              <1> 
  9962                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  9963                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  9964                              <1> 
  9965                              <1> 
  9966                              <1> ;////////////////////////////////////////////////////////////////////
  9967                              <1> ;; END OF DISK I/O SYTEM ///
  9968                                  %include 'memory.inc'  ; 09/03/2015
  9969                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
  9970                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
  9971                              <1> ; Last Modification: 18/10/2015 (!not completed!)
  9972                              <1> ;
  9973                              <1> ; Source code for NASM - Netwide Assembler (2.11)
  9974                              <1> 
  9975                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
  9976                              <1> 
  9977                              <1> ;;04/11/2014 (unix386.s)	
  9978                              <1> ;PDE_A_PRESENT	equ	1		; Present flag for PDE
  9979                              <1> ;PDE_A_WRITE	equ 	2		; Writable (write permission) flag
  9980                              <1> ;PDE_A_USER	equ	4		; User (non-system/kernel) page flag
  9981                              <1> ;;
  9982                              <1> ;PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
  9983                              <1> ;PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
  9984                              <1> ;PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
  9985                              <1> ;PTE_A_ACCESS   equ	32		; Accessed flag (bit 5) ; 09/03/2015
  9986                              <1> 
  9987                              <1> ; 27/04/2015
  9988                              <1> ; 09/03/2015
  9989                              <1> PAGE_SIZE 	equ 4096		; page size in bytes
  9990                              <1> PAGE_SHIFT 	equ 12			; page table shift count
  9991                              <1> PAGE_D_SHIFT 	equ 22	; 12 + 10	; page directory shift count
  9992                              <1> PAGE_OFF	equ 0FFFh		; 12 bit byte offset in page frame
  9993                              <1> PTE_MASK 	equ 03FFh		; page table entry mask
  9994                              <1> PTE_DUPLICATED  equ 200h		; duplicated page sign (AVL bit 0)
  9995                              <1> PDE_A_CLEAR	equ 0F000h		; to clear PDE attribute bits
  9996                              <1> PTE_A_CLEAR	equ 0F000h		; to clear PTE attribute bits
  9997                              <1> LOGIC_SECT_SIZE equ 512			; logical sector size
  9998                              <1> ERR_MAJOR_PF	equ 0E0h		; major error: page fault
  9999                              <1> ERR_MINOR_IM	equ 1			; insufficient (out of) memory
 10000                              <1> ERR_MINOR_DSK	equ 2			; disk read/write error
 10001                              <1> ERR_MINOR_PV	equ 3			; protection violation
 10002                              <1> SWP_DISK_READ_ERR equ 4
 10003                              <1> SWP_DISK_NOT_PRESENT_ERR equ 5
 10004                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 6
 10005                              <1> SWP_NO_FREE_SPACE_ERR equ 7
 10006                              <1> SWP_DISK_WRITE_ERR equ 8
 10007                              <1> SWP_NO_PAGE_TO_SWAP_ERR equ 9
 10008                              <1> PTE_A_ACCESS_BIT equ 5  ; Bit 5 (accessed flag)        
 10009                              <1> SECTOR_SHIFT    equ 3   ; sector shift (to convert page block number)
 10010                              <1> 
 10011                              <1> ;
 10012                              <1> ;; Retro Unix 386 v1 - paging method/principles
 10013                              <1> ;;
 10014                              <1> ;; 10/10/2014
 10015                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
 10016                              <1> ;;
 10017                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
 10018                              <1> ;;	(virtual address = physical address)
 10019                              <1> ;; KERNEL PAGE TABLES:
 10020                              <1> ;;	Kernel page directory and all page tables are
 10021                              <1> ;;	on memory as initialized, as equal to physical memory
 10022                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
 10023                              <1> ;;
 10024                              <1> ;;	what for: User pages may be swapped out, when accessing
 10025                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
 10026                              <1> ;;	kernel would have to swap it in! But it is also may be
 10027                              <1> ;;	in use by a user process. (In system/kernel mode
 10028                              <1> ;;	kernel can access all memory pages even if they are
 10029                              <1> ;;	reserved/allocated for user processes. Swap out/in would
 10030                              <1> ;;	cause conflicts.) 
 10031                              <1> ;;	
 10032                              <1> ;;	As result of these conditions,
 10033                              <1> ;;	all kernel pages must be initialized as equal to 
 10034                              <1> ;;	physical layout for preventing page faults. 
 10035                              <1> ;;	Also, calling "allocate page" procedure after
 10036                              <1> ;;	a page fault can cause another page fault (double fault)
 10037                              <1> ;;	if all kernel page tables would not be initialized.
 10038                              <1> ;;
 10039                              <1> ;;	[first_page] = Beginning of users space, as offset to 
 10040                              <1> ;;	memory allocation table. (double word aligned)
 10041                              <1> ;;
 10042                              <1> ;;	[next_page] = first/next free space to be searched
 10043                              <1> ;;	as offset to memory allocation table. (dw aligned)
 10044                              <1> ;;
 10045                              <1> ;;	[last_page] = End of memory (users space), as offset
 10046                              <1> ;;	to memory allocation table. (double word aligned)
 10047                              <1> ;;
 10048                              <1> ;; USER PAGE TABLES:
 10049                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
 10050                              <1> ;;		'ready only' marked copies of the 
 10051                              <1> ;;		parent process's page table entries (for
 10052                              <1> ;;		same physical memory).
 10053                              <1> ;;		(A page will be copied to a new page after
 10054                              <1> ;;		 if it causes R/W page fault.)
 10055                              <1> ;;
 10056                              <1> ;;	Every user process has own (different)
 10057                              <1> ;;	page directory and page tables.	
 10058                              <1> ;;
 10059                              <1> ;;	Code starts at virtual address 0, always.
 10060                              <1> ;;	(Initial value of EIP is 0 in user mode.)
 10061                              <1> ;;	(Programs can be written/developed as simple
 10062                              <1> ;;	 flat memory programs.)
 10063                              <1> ;;
 10064                              <1> ;; MEMORY ALLOCATION STRATEGY:
 10065                              <1> ;;	Memory page will be allocated by kernel only 
 10066                              <1> ;;		(in kernel/system mode only).
 10067                              <1> ;;	* After a
 10068                              <1> ;;	  - 'not present' page fault
 10069                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
 10070                              <1> ;;	* For loading (opening, reading) a file or disk/drive
 10071                              <1> ;;	* As responce to 'allocate additional memory blocks' 
 10072                              <1> ;;	  request by running process.
 10073                              <1> ;;	* While creating a process, allocating a new buffer,
 10074                              <1> ;;	  new page tables etc.
 10075                              <1> ;;
 10076                              <1> ;;	At first,
 10077                              <1> ;;	- 'allocate page' procedure will be called;
 10078                              <1> ;,	   if it will return with a valid (>0) physical address
 10079                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
 10080                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
 10081                              <1> ;;	- 'allocate page' will be called for allocating page
 10082                              <1> ;;	   directory, page table and running space (data/code).
 10083                              <1> ;;	- every successful 'allocate page' call will decrease
 10084                              <1> ;;	  'free_pages' count (pointer).
 10085                              <1> ;;	- 'out of (insufficient) memory error' will be returned
 10086                              <1> ;;	  if 'free_pages' points to a ZERO.
 10087                              <1> ;;	- swapping out and swapping in (if it is not a new page)
 10088                              <1> ;;	  procedures will be called as responce to 'out of memory'
 10089                              <1> ;;	  error except errors caused by attribute conflicts.
 10090                              <1> ;;	 (swapper functions)	 
 10091                              <1> ;;					
 10092                              <1> ;;	At second,
 10093                              <1> ;;	- page directory entry will be updated then page table
 10094                              <1> ;;	  entry will be updated.		
 10095                              <1> ;;
 10096                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
 10097                              <1> ;;	- M.A.T. has a size according to available memory as
 10098                              <1> ;;	  follows:
 10099                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
 10100                              <1> ;;		  - a bit with value of 0 means allocated page
 10101                              <1> ;;		  - a bit with value of 1 means a free page
 10102                              <1> ;,	- 'free_pages' pointer holds count of free pages
 10103                              <1> ;;	  depending on M.A.T.
 10104                              <1> ;;		(NOTE: Free page count will not be checked
 10105                              <1> ;;		again -on M.A.T.- after initialization. 
 10106                              <1> ;;		Kernel will trust on initial count.)
 10107                              <1> ;,	- 'free_pages' count will be decreased by allocation
 10108                              <1> ;;	  and it will be increased by deallocation procedures.
 10109                              <1> ;;	
 10110                              <1> ;;	- Available memory will be calculated during
 10111                              <1> ;;	  the kernel's initialization stage (in real mode).
 10112                              <1> ;;	  Memory allocation table and kernel page tables 
 10113                              <1> ;;	  will be formatted/sized as result of available
 10114                              <1> ;;	  memory calculation before paging is enabled.
 10115                              <1> ;;
 10116                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
 10117                              <1> ;;	- Memory Allocation Table size will be 128 KB.
 10118                              <1> ;;	- Memory allocation for kernel page directory size 
 10119                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10120                              <1> ;;	  for page tables)
 10121                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
 10122                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
 10123                              <1> ;;	- User (available) space will be started 
 10124                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
 10125                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10126                              <1> ;;	  memory allocation table and kernel's page directory
 10127                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10128                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10129                              <1> ;; 	  for buffers.
 10130                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10131                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10132                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
 10133                              <1> ;;
 10134                              <1> ;; For 1GB Available Memory:
 10135                              <1> ;;	- Memory Allocation Table size will be 32 KB.
 10136                              <1> ;;	- Memory allocation for kernel page directory size 
 10137                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10138                              <1> ;;	  for page tables)
 10139                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
 10140                              <1> ;;	  is 1 MB (256*4*1024 bytes).
 10141                              <1> ;;	- User (available) space will be started 
 10142                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
 10143                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10144                              <1> ;;	  memory allocation table and kernel's page directory
 10145                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10146                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10147                              <1> ;; 	  for buffers.
 10148                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10149                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10150                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
 10151                              <1> ;;
 10152                              <1> ;;
 10153                              <1> 
 10154                              <1> 
 10155                              <1> ;;************************************************************************************
 10156                              <1> ;; 
 10157                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
 10158                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
 10159                              <1> 
 10160                              <1> ;; Main factor: "sys fork" system call 
 10161                              <1> ;;	
 10162                              <1> ;; 		FORK
 10163                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
 10164                              <1> ;;  writable pages ---->|
 10165                              <1> ;;                      |----> child - duplicated PTEs, read only pages
 10166                              <1> ;; 
 10167                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
 10168                              <1> ;; 
 10169                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
 10170                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
 10171                              <1> ;;       -while R/W bit is 0-. 
 10172                              <1> ;; 
 10173                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
 10174                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
 10175                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
 10176                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
 10177                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
 10178                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
 10179                              <1> ;; 
 10180                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
 10181                              <1> ;; # Parent's read only pages are copied to new child pages. 
 10182                              <1> ;;   Parent's PTE attributes are not changed.
 10183                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
 10184                              <1> ;;    destroy/mix previous fork result).
 10185                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
 10186                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
 10187                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
 10188                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
 10189                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
 10190                              <1> ;;   as Child's Page Table Entries without copying actual page.
 10191                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
 10192                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
 10193                              <1> ;; 
 10194                              <1> ;; !? WHAT FOR (duplication after duplication):
 10195                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
 10196                              <1> ;; program/executable code continues from specified location as child process, 
 10197                              <1> ;; returns back previous code location as parent process, every child after 
 10198                              <1> ;; every sys fork uses last image of code and data just prior the fork.
 10199                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
 10200                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
 10201                              <1> ;; was copied to child's process segment (all of code and data) according to
 10202                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
 10203                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
 10204                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
 10205                              <1> ;; (complete running image of parent process) to the child process; 
 10206                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
 10207                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
 10208                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
 10209                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
 10210                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
 10211                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
 10212                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
 10213                              <1> ;; new/fresh pages will be used to load and run new executable/program.
 10214                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
 10215                              <1> ;; for sharing same read only pages between parent and child processes.
 10216                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
 10217                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
 10218                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
 10219                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
 10220                              <1> ;; -deallocation problem-.
 10221                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
 10222                              <1> ;; 
 10223                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10224                              <1> ;; # Page fault handler will do those:
 10225                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10226                              <1> ;;   - If it is reset/clear, there is a child uses same page.
 10227                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
 10228                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
 10229                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
 10230                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
 10231                              <1> ;;     read only page will be converted to writable and unique page which belongs
 10232                              <1> ;;     to child process.)	
 10233                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10234                              <1> ;; # Page fault handler will do those:
 10235                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10236                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
 10237                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
 10238                              <1> ;;     address or not. 
 10239                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
 10240                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
 10241                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
 10242                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
 10243                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
 10244                              <1> ;; 
 10245                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
 10246                              <1> ;;       will be set as writable (and unique) in case of child process was using 
 10247                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
 10248                              <1> ;;       duplication method details, it is not possible multiple child processes
 10249                              <1> ;;       were using same page with duplicated PTEs.
 10250                              <1> ;; 
 10251                              <1> ;;************************************************************************************   
 10252                              <1> 
 10253                              <1> ;; 08/10/2014
 10254                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
 10255                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
 10256                              <1> 
 10257                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
 10258                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
 10259                              <1> ;; (25/08/2014, Revision: 5057) file 
 10260                              <1> ;; by KolibriOS Team (2004-2012)
 10261                              <1> 
 10262                              <1> allocate_page:
 10263                              <1> 	; 01/07/2015
 10264                              <1> 	; 05/05/2015
 10265                              <1> 	; 30/04/2015
 10266                              <1> 	; 16/10/2014
 10267                              <1> 	; 08/10/2014
 10268                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
 10269                              <1> 	;
 10270                              <1> 	; INPUT -> none
 10271                              <1> 	;
 10272                              <1> 	; OUTPUT ->
 10273                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10274                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
 10275                              <1> 	;
 10276                              <1> 	;	CF = 1 and EAX = 0 
 10277                              <1> 	; 		   if there is not a free page to be allocated	
 10278                              <1> 	;
 10279                              <1> 	; Modified Registers -> none (except EAX)
 10280                              <1> 	;
 10281 00003037 A1[B0700000]        <1> 	mov	eax, [free_pages]
 10282 0000303C 21C0                <1> 	and	eax, eax
 10283 0000303E 7438                <1> 	jz	short out_of_memory
 10284                              <1> 	;
 10285 00003040 53                  <1> 	push	ebx
 10286 00003041 51                  <1> 	push	ecx
 10287                              <1> 	;
 10288 00003042 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
 10289 00003047 89D9                <1> 	mov	ecx, ebx
 10290                              <1>  				     ; NOTE: 32 (first_page) is initial
 10291                              <1> 				     ; value of [next_page].
 10292                              <1> 				     ; It points to the first available
 10293                              <1> 				     ; page block for users (ring 3) ...	
 10294                              <1> 				     ; (MAT offset 32 = 1024/32)	
 10295                              <1> 				     ; (at the of the first 4 MB)		
 10296 00003049 031D[B4700000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
 10297                              <1> 				 ; next_free_page >> 5
 10298 0000304F 030D[B8700000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
 10299                              <1> 				 ; (total_pages - 1) >> 5
 10300                              <1> al_p_scan:
 10301 00003055 39CB                <1> 	cmp	ebx, ecx
 10302 00003057 770A                <1> 	ja	short al_p_notfound
 10303                              <1> 	;
 10304                              <1> 	; 01/07/2015
 10305                              <1> 	; AMD64 Architecture Programmers Manual
 10306                              <1> 	; Volume 3:
 10307                              <1> 	; General-Purpose and System Instructions
 10308                              <1> 	;
 10309                              <1> 	; BSF - Bit Scan Forward
 10310                              <1> 	;
 10311                              <1> 	;   Searches the value in a register or a memory location
 10312                              <1> 	;   (second operand) for the least-significant set bit. 
 10313                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
 10314                              <1> 	;   and stores the index of the least-significant set bit in a destination
 10315                              <1> 	;   register (first operand). If the second operand contains 0, 
 10316                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
 10317                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
 10318                              <1> 	;   of the searched value
 10319                              <1> 	;
 10320 00003059 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 10321                              <1> 			   ; Clear ZF if a bit is found set (1) and 
 10322                              <1> 			   ; loads the destination with an index to
 10323                              <1> 			   ; first set bit. (0 -> 31) 
 10324                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 10325 0000305C 7525                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
 10326                              <1> 			 ;
 10327                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
 10328                              <1> 			 ;	  with value of 1 means 
 10329                              <1> 			 ;	  the corresponding page is free 
 10330                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
 10331 0000305E 83C304              <1> 	add	ebx, 4
 10332                              <1> 			 ; We return back for searching next page block
 10333                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
 10334                              <1> 			 ;	 we always will find at least 1 free page here.
 10335 00003061 EBF2                <1>         jmp     short al_p_scan
 10336                              <1> 	;
 10337                              <1> al_p_notfound:
 10338 00003063 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10339 00003069 890D[B4700000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
 10340                              <1> 				 ; (deallocate_page procedure will change it)
 10341 0000306F 31C0                <1> 	xor	eax, eax
 10342 00003071 A3[B0700000]        <1> 	mov	[free_pages], eax ; 0
 10343 00003076 59                  <1> 	pop	ecx
 10344 00003077 5B                  <1> 	pop	ebx
 10345                              <1> 	;
 10346                              <1> out_of_memory:
 10347 00003078 E857040000          <1> 	call	swap_out
 10348 0000307D 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
 10349                              <1> 	;
 10350 0000307F 29C0                <1> 	sub 	eax, eax ; 0
 10351 00003081 F9                  <1> 	stc
 10352 00003082 C3                  <1> 	retn
 10353                              <1> 
 10354                              <1> al_p_found:
 10355 00003083 89D9                <1> 	mov	ecx, ebx
 10356 00003085 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10357 0000308B 890D[B4700000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
 10358                              <1> 				 ; address/offset (to the next)
 10359 00003091 FF0D[B0700000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
 10360                              <1> 	;
 10361 00003097 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 10362                              <1> 				 ; is copied into the Carry Flag and then cleared
 10363                              <1> 				 ; in the destination.
 10364                              <1> 				 ;
 10365                              <1> 				 ; Reset the bit which is corresponding to the 
 10366                              <1> 				 ; (just) allocated page.
 10367                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
 10368 0000309A C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
 10369 0000309D 01C8                <1> 	add	eax, ecx	 ; = page number
 10370 0000309F C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
 10371                              <1> 	; EAX = physical address of memory page
 10372                              <1> 	;
 10373                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
 10374                              <1> 	;       according to this EAX value...
 10375 000030A2 59                  <1> 	pop	ecx
 10376 000030A3 5B                  <1> 	pop	ebx
 10377                              <1> al_p_ok:
 10378 000030A4 C3                  <1> 	retn
 10379                              <1> 
 10380                              <1> 
 10381                              <1> make_page_dir:
 10382                              <1> 	; 18/04/2015
 10383                              <1> 	; 12/04/2015
 10384                              <1> 	; 23/10/2014
 10385                              <1> 	; 16/10/2014
 10386                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10387                              <1> 	;
 10388                              <1> 	; INPUT ->
 10389                              <1> 	;	none
 10390                              <1> 	; OUTPUT ->
 10391                              <1> 	;	(EAX = 0)
 10392                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10393                              <1> 	;	cf = 0 ->
 10394                              <1> 	;	u.pgdir = page directory (physical) address of the current
 10395                              <1> 	;		  process/user.
 10396                              <1> 	;
 10397                              <1> 	; Modified Registers -> EAX
 10398                              <1> 	;
 10399 000030A5 E88DFFFFFF          <1> 	call	allocate_page
 10400 000030AA 7216                <1> 	jc	short mkpd_error
 10401                              <1> 	;
 10402 000030AC A3[D9740000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
 10403                              <1> 				  ; (Physical address)
 10404                              <1> clear_page:
 10405                              <1> 	; 18/04/2015
 10406                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10407                              <1> 	;
 10408                              <1> 	; INPUT ->
 10409                              <1> 	;	EAX = physical address of the page
 10410                              <1> 	; OUTPUT ->
 10411                              <1> 	;	all bytes of the page will be cleared
 10412                              <1> 	;
 10413                              <1> 	; Modified Registers -> none
 10414                              <1> 	;
 10415 000030B1 57                  <1> 	push	edi
 10416 000030B2 51                  <1> 	push	ecx
 10417 000030B3 50                  <1> 	push	eax
 10418 000030B4 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 10419 000030B9 89C7                <1> 	mov	edi, eax
 10420 000030BB 31C0                <1> 	xor	eax, eax
 10421 000030BD F3AB                <1> 	rep	stosd
 10422 000030BF 58                  <1> 	pop	eax
 10423 000030C0 59                  <1> 	pop	ecx
 10424 000030C1 5F                  <1> 	pop	edi
 10425                              <1> mkpd_error:
 10426                              <1> mkpt_error:
 10427 000030C2 C3                  <1> 	retn
 10428                              <1> 
 10429                              <1> make_page_table:
 10430                              <1> 	; 23/06/2015
 10431                              <1> 	; 18/04/2015
 10432                              <1> 	; 12/04/2015
 10433                              <1> 	; 16/10/2014
 10434                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10435                              <1> 	;
 10436                              <1> 	; INPUT ->
 10437                              <1> 	;	EBX = virtual (linear) address
 10438                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10439                              <1> 	;	      (higher 20 bits must be ZERO)
 10440                              <1> 	;	      (bit 0 must be 1)	 
 10441                              <1> 	;	u.pgdir = page directory (physical) address
 10442                              <1> 	; OUTPUT ->
 10443                              <1> 	;	EDX = Page directory entry address
 10444                              <1> 	;	EAX = Page table address
 10445                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10446                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
 10447                              <1> 	;
 10448                              <1> 	; Modified Registers -> EAX, EDX
 10449                              <1> 	;
 10450 000030C3 E86FFFFFFF          <1> 	call	allocate_page
 10451 000030C8 72F8                <1> 	jc	short mkpt_error
 10452 000030CA E811000000          <1> 	call	set_pde	
 10453 000030CF EBE0                <1> 	jmp	short clear_page
 10454                              <1> 
 10455                              <1> make_page:
 10456                              <1> 	; 24/07/2015
 10457                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
 10458                              <1> 	;
 10459                              <1> 	; INPUT ->
 10460                              <1> 	;	EBX = virtual (linear) address
 10461                              <1> 	;	ECX = page attributes (lower 12 bits)
 10462                              <1> 	;	      (higher 20 bits must be ZERO)
 10463                              <1> 	;	      (bit 0 must be 1)	 
 10464                              <1> 	;	u.pgdir = page directory (physical) address
 10465                              <1> 	; OUTPUT ->
 10466                              <1> 	;	EBX = Virtual address
 10467                              <1> 	;	(EDX = PTE value)
 10468                              <1> 	;	EAX = Physical address
 10469                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10470                              <1> 	;
 10471                              <1> 	; Modified Registers -> EAX, EDX
 10472                              <1> 	;
 10473 000030D1 E861FFFFFF          <1> 	call	allocate_page
 10474 000030D6 7207                <1> 	jc	short mkp_err
 10475 000030D8 E821000000          <1> 	call	set_pte	
 10476 000030DD 73D2                <1> 	jnc	short clear_page ; 18/04/2015
 10477                              <1> mkp_err:
 10478 000030DF C3                  <1> 	retn
 10479                              <1> 
 10480                              <1> 
 10481                              <1> set_pde:	; Set page directory entry (PDE)
 10482                              <1> 	; 20/07/2015
 10483                              <1> 	; 18/04/2015
 10484                              <1> 	; 12/04/2015
 10485                              <1> 	; 23/10/2014
 10486                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10487                              <1> 	;
 10488                              <1> 	; INPUT ->
 10489                              <1> 	;	EAX = physical address
 10490                              <1> 	;	      (use present value if EAX = 0)
 10491                              <1> 	;	EBX = virtual (linear) address
 10492                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10493                              <1> 	;	      (higher 20 bits must be ZERO)
 10494                              <1> 	;	      (bit 0 must be 1)	 
 10495                              <1> 	;	u.pgdir = page directory (physical) address
 10496                              <1> 	; OUTPUT ->
 10497                              <1> 	;	EDX = PDE address
 10498                              <1> 	;	EAX = page table address (physical)
 10499                              <1> 	;	;(CF=1 -> Invalid page address)
 10500                              <1> 	;
 10501                              <1> 	; Modified Registers -> EDX
 10502                              <1> 	;
 10503 000030E0 89DA                <1> 	mov	edx, ebx
 10504 000030E2 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
 10505 000030E5 C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
 10506 000030E8 0315[D9740000]      <1> 	add	edx, [u.pgdir]
 10507                              <1> 	;
 10508 000030EE 21C0                <1> 	and	eax, eax
 10509 000030F0 7506                <1> 	jnz	short spde_1
 10510                              <1> 	;
 10511 000030F2 8B02                <1> 	mov	eax, [edx]  ; old PDE value
 10512                              <1> 	;test	al, 1
 10513                              <1> 	;jz	short spde_2
 10514 000030F4 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
 10515                              <1> spde_1:
 10516                              <1> 	;and	cx, 0FFFh
 10517 000030F8 8902                <1> 	mov	[edx], eax
 10518 000030FA 66090A              <1> 	or	[edx], cx
 10519 000030FD C3                  <1> 	retn
 10520                              <1> ;spde_2: ; error
 10521                              <1> ;	stc
 10522                              <1> ;	retn
 10523                              <1> 
 10524                              <1> set_pte:	; Set page table entry (PTE)
 10525                              <1> 	; 24/07/2015
 10526                              <1> 	; 20/07/2015
 10527                              <1> 	; 23/06/2015
 10528                              <1> 	; 18/04/2015
 10529                              <1> 	; 12/04/2015
 10530                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10531                              <1> 	;
 10532                              <1> 	; INPUT ->
 10533                              <1> 	;	EAX = physical page address
 10534                              <1> 	;	      (use present value if EAX = 0)
 10535                              <1> 	;	EBX = virtual (linear) address
 10536                              <1> 	;	ECX = page attributes (lower 12 bits)
 10537                              <1> 	;	      (higher 20 bits must be ZERO)
 10538                              <1> 	;	      (bit 0 must be 1)	 
 10539                              <1> 	;	u.pgdir = page directory (physical) address
 10540                              <1> 	; OUTPUT ->
 10541                              <1> 	;	EAX = physical page address
 10542                              <1> 	;	(EDX = PTE value)
 10543                              <1> 	;	EBX = virtual address
 10544                              <1> 	;
 10545                              <1> 	;	CF = 1 -> error
 10546                              <1> 	;
 10547                              <1> 	; Modified Registers -> EAX, EDX
 10548                              <1> 	;
 10549 000030FE 50                  <1> 	push	eax
 10550 000030FF A1[D9740000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
 10551 00003104 E837000000          <1> 	call 	get_pde
 10552                              <1> 		; EDX = PDE address
 10553                              <1> 		; EAX = PDE value
 10554 00003109 5A                  <1> 	pop	edx ; physical page address
 10555 0000310A 722A                <1> 	jc	short spte_err ; PDE not present
 10556                              <1> 	;
 10557 0000310C 53                  <1> 	push	ebx ; 24/07/2015
 10558 0000310D 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10559                              <1> 			    ; EDX = PT address (physical)	
 10560 00003111 C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
 10561 00003114 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
 10562                              <1> 			 ; clear higher 10 bits (PD bits)
 10563 0000311A C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
 10564 0000311D 01C3                <1> 	add	ebx, eax
 10565                              <1> 	;
 10566 0000311F 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
 10567 00003121 A801                <1> 	test	al, 1
 10568 00003123 740C                <1> 	jz	short spte_0
 10569 00003125 09D2                <1> 	or	edx, edx
 10570 00003127 750F                <1> 	jnz	short spte_1
 10571 00003129 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10572 0000312D 89C2                <1> 	mov	edx, eax
 10573 0000312F EB09                <1> 	jmp	short spte_2	
 10574                              <1> spte_0:
 10575                              <1> 	; If this PTE contains a swap (disk) address,
 10576                              <1> 	; it can be updated by using 'swap_in' procedure
 10577                              <1> 	; only!
 10578 00003131 21C0                <1> 	and	eax, eax
 10579 00003133 7403                <1> 	jz	short spte_1
 10580                              <1> 	; 24/07/2015
 10581                              <1> 	; swapped page ! (on disk)
 10582 00003135 5B                  <1> 	pop	ebx
 10583                              <1> spte_err:
 10584 00003136 F9                  <1> 	stc
 10585 00003137 C3                  <1> 	retn
 10586                              <1> spte_1: 
 10587 00003138 89D0                <1> 	mov	eax, edx
 10588                              <1> spte_2:
 10589 0000313A 09CA                <1> 	or	edx, ecx
 10590                              <1> 	; 23/06/2015
 10591 0000313C 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
 10592                              <1> 	; 24/07/2015
 10593 0000313E 5B                  <1> 	pop	ebx
 10594 0000313F C3                  <1> 	retn
 10595                              <1> 
 10596                              <1> get_pde:	; Get present value of the relevant PDE
 10597                              <1> 	; 20/07/2015
 10598                              <1> 	; 18/04/2015
 10599                              <1> 	; 12/04/2015
 10600                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10601                              <1> 	;
 10602                              <1> 	; INPUT ->
 10603                              <1> 	;	EBX = virtual (linear) address
 10604                              <1> 	;	EAX = page directory (physical) address
 10605                              <1> 	; OUTPUT ->
 10606                              <1> 	;	EDX = Page directory entry address
 10607                              <1> 	;	EAX = Page directory entry value
 10608                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 10609                              <1> 	; Modified Registers -> EDX, EAX
 10610                              <1> 	;
 10611 00003140 89DA                <1> 	mov	edx, ebx
 10612 00003142 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
 10613 00003145 C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
 10614 00003148 01C2                <1> 	add	edx, eax ; page directory address (physical)
 10615 0000314A 8B02                <1> 	mov	eax, [edx]
 10616 0000314C A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
 10617 0000314E 751F                <1> 	jnz	short gpte_retn
 10618 00003150 F9                  <1> 	stc
 10619                              <1> gpde_retn:	
 10620 00003151 C3                  <1> 	retn
 10621                              <1> 
 10622                              <1> get_pte:
 10623                              <1> 		; Get present value of the relevant PTE
 10624                              <1> 	; 29/07/2015
 10625                              <1> 	; 20/07/2015
 10626                              <1> 	; 18/04/2015
 10627                              <1> 	; 12/04/2015
 10628                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10629                              <1> 	;
 10630                              <1> 	; INPUT ->
 10631                              <1> 	;	EBX = virtual (linear) address
 10632                              <1> 	;	EAX = page directory (physical) address
 10633                              <1> 	; OUTPUT ->
 10634                              <1> 	;	EDX = Page table entry address (if CF=0)
 10635                              <1> 	;	      Page directory entry address (if CF=1)
 10636                              <1> 	;            (Bit 0 value is 0 if PT is not present)
 10637                              <1> 	;	EAX = Page table entry value (page address)
 10638                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 10639                              <1> 	; Modified Registers -> EAX, EDX
 10640                              <1> 	;
 10641 00003152 E8E9FFFFFF          <1> 	call 	get_pde
 10642 00003157 72F8                <1> 	jc	short gpde_retn	; page table is not present
 10643                              <1> 	;jnc	short gpte_1
 10644                              <1> 	;retn
 10645                              <1> ;gpte_1:
 10646 00003159 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10647 0000315D 89DA                <1> 	mov	edx, ebx
 10648 0000315F C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
 10649 00003162 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
 10650                              <1> 			 ; clear higher 10 bits (PD bits)
 10651 00003168 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
 10652 0000316B 01C2                <1> 	add	edx, eax
 10653 0000316D 8B02                <1> 	mov	eax, [edx]
 10654                              <1> gpte_retn:
 10655 0000316F C3                  <1> 	retn
 10656                              <1> 
 10657                              <1> deallocate_page_dir:
 10658                              <1> 	; 15/09/2015
 10659                              <1> 	; 05/08/2015
 10660                              <1> 	; 30/04/2015
 10661                              <1> 	; 28/04/2015
 10662                              <1> 	; 17/10/2014
 10663                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10664                              <1> 	;
 10665                              <1> 	; INPUT ->
 10666                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
 10667                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 10668                              <1> 	; OUTPUT ->
 10669                              <1> 	;	All of page tables in the page directory
 10670                              <1> 	;	and page dir's itself will be deallocated
 10671                              <1> 	;	except 'read only' duplicated pages (will be converted
 10672                              <1> 	;	to writable pages).
 10673                              <1> 	;
 10674                              <1> 	; Modified Registers -> EAX
 10675                              <1> 	;
 10676                              <1> 	;
 10677 00003170 56                  <1> 	push	esi
 10678 00003171 51                  <1> 	push	ecx
 10679 00003172 50                  <1> 	push	eax
 10680 00003173 89C6                <1> 	mov	esi, eax 
 10681 00003175 31C9                <1> 	xor	ecx, ecx
 10682                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
 10683                              <1> 	; it must not be deallocated
 10684 00003177 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
 10685                              <1> dapd_0:
 10686 00003179 AD                  <1> 	lodsd
 10687 0000317A A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
 10688 0000317C 7409                <1> 	jz	short dapd_1	
 10689 0000317E 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 10690 00003182 E812000000          <1> 	call	deallocate_page_table			
 10691                              <1> dapd_1:
 10692 00003187 41                  <1> 	inc	ecx ; page directory entry index
 10693 00003188 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
 10694 0000318E 72E9                <1> 	jb	short dapd_0
 10695                              <1> dapd_2:
 10696 00003190 58                  <1> 	pop	eax
 10697 00003191 E879000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
 10698 00003196 59                  <1> 	pop	ecx
 10699 00003197 5E                  <1> 	pop	esi
 10700 00003198 C3                  <1> 	retn
 10701                              <1> 
 10702                              <1> deallocate_page_table:
 10703                              <1> 	; 19/09/2015
 10704                              <1> 	; 15/09/2015
 10705                              <1> 	; 05/08/2015
 10706                              <1> 	; 30/04/2015
 10707                              <1> 	; 28/04/2015
 10708                              <1> 	; 24/10/2014
 10709                              <1> 	; 23/10/2014
 10710                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10711                              <1> 	;
 10712                              <1> 	; INPUT ->
 10713                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
 10714                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 10715                              <1> 	;	(ECX = page directory entry index)
 10716                              <1> 	; OUTPUT ->
 10717                              <1> 	;	All of pages in the page table and page table's itself
 10718                              <1> 	;	will be deallocated except 'read only' duplicated pages
 10719                              <1> 	;	(will be converted to writable pages).
 10720                              <1> 	;
 10721                              <1> 	; Modified Registers -> EAX
 10722                              <1> 	;
 10723 00003199 56                  <1> 	push	esi
 10724 0000319A 57                  <1> 	push	edi
 10725 0000319B 52                  <1> 	push	edx
 10726 0000319C 50                  <1> 	push	eax ; *
 10727 0000319D 89C6                <1> 	mov	esi, eax 
 10728 0000319F 31FF                <1> 	xor	edi, edi ; 0
 10729                              <1> dapt_0:
 10730 000031A1 AD                  <1> 	lodsd
 10731 000031A2 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
 10732 000031A4 7441                <1> 	jz	short dapt_1
 10733                              <1> 	;
 10734 000031A6 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
 10735                              <1> 				  ; (must be 1)
 10736 000031A8 754C                <1> 	jnz	short dapt_3
 10737                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
 10738 000031AA 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
 10739                              <1> 				   ; as child's page ?
 10740 000031AE 744B                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
 10741                              <1> 	; check the parent's PTE value is read only & same page or not.. 
 10742                              <1> 	; ECX = page directory entry index (0-1023)
 10743 000031B0 53                  <1> 	push	ebx
 10744 000031B1 51                  <1> 	push	ecx
 10745 000031B2 66C1E102            <1> 	shl	cx, 2 ; *4 
 10746 000031B6 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
 10747 000031B8 8B0B                <1> 	mov	ecx, [ebx]
 10748 000031BA F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
 10749 000031BD 7435                <1> 	jz	short dapt_2	; parent process does not use this page
 10750 000031BF 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 10751                              <1> 	; EDI = page table entry index (0-1023)
 10752 000031C4 89FA                <1> 	mov	edx, edi 
 10753 000031C6 66C1E202            <1> 	shl	dx, 2 ; *4 
 10754 000031CA 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
 10755 000031CC 8B1A                <1> 	mov	ebx, [edx]
 10756 000031CE F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
 10757 000031D1 7421                <1> 	jz	short dapt_2	; parent process does not use this page
 10758 000031D3 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
 10759 000031D7 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
 10760 000031DC 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
 10761 000031DE 7514                <1> 	jne	short dapt_2	; not same page
 10762                              <1> 				; deallocate the child's page
 10763 000031E0 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
 10764 000031E3 59                  <1> 	pop	ecx
 10765 000031E4 5B                  <1> 	pop	ebx
 10766 000031E5 EB14                <1> 	jmp	short dapt_4
 10767                              <1> dapt_1:
 10768 000031E7 09C0                <1> 	or	eax, eax	; swapped page ?
 10769 000031E9 7417                <1> 	jz	short dapt_5	; no
 10770                              <1> 				; yes
 10771 000031EB D1E8                <1> 	shr	eax, 1
 10772 000031ED E848040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
 10773                              <1> 				  ; on the swap disk (or in file)
 10774 000031F2 EB0E                <1> 	jmp	short dapt_5
 10775                              <1> dapt_2:
 10776 000031F4 59                  <1> 	pop	ecx
 10777 000031F5 5B                  <1> 	pop	ebx
 10778                              <1> dapt_3:	
 10779                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 10780 000031F6 E814000000          <1> 	call	deallocate_page
 10781                              <1> dapt_4:
 10782 000031FB C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
 10783                              <1> dapt_5:
 10784 00003202 47                  <1> 	inc	edi ; page table entry index
 10785 00003203 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
 10786 00003209 7296                <1> 	jb	short dapt_0
 10787                              <1> 	;
 10788 0000320B 58                  <1> 	pop	eax ; *
 10789 0000320C 5A                  <1> 	pop	edx
 10790 0000320D 5F                  <1> 	pop	edi	
 10791 0000320E 5E                  <1> 	pop	esi
 10792                              <1> 	;
 10793                              <1> 	;call	deallocate_page	; deallocate the page table's itself
 10794                              <1> 	;retn
 10795                              <1> 
 10796                              <1> deallocate_page:
 10797                              <1> 	; 15/09/2015
 10798                              <1> 	; 28/04/2015
 10799                              <1> 	; 10/03/2015
 10800                              <1> 	; 17/10/2014
 10801                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10802                              <1> 	;
 10803                              <1> 	; INPUT -> 
 10804                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10805                              <1> 	; OUTPUT ->
 10806                              <1> 	;	[free_pages] is increased
 10807                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
 10808                              <1> 	;	CF = 1 if the page is already deallocated
 10809                              <1> 	; 	       (or not allocated) before.  
 10810                              <1> 	;
 10811                              <1> 	; Modified Registers -> EAX
 10812                              <1> 	;
 10813 0000320F 53                  <1> 	push	ebx
 10814 00003210 52                  <1> 	push	edx
 10815                              <1> 	;
 10816 00003211 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
 10817                              <1> 				     ; 12 bits right
 10818                              <1> 				     ; to get page number
 10819 00003214 89C2                <1> 	mov	edx, eax
 10820                              <1> 	; 15/09/2015
 10821 00003216 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
 10822                              <1> 				     ; (1 allocation bit = 1 page)
 10823                              <1> 				     ; (1 allocation bytes = 8 pages)
 10824 00003219 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 10825                              <1> 				     ; (to get 32 bit position)			
 10826                              <1> 	;
 10827 0000321C BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
 10828 00003221 01D3                <1> 	add	ebx, edx
 10829 00003223 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 10830                              <1> 				     ; (allocation bit position)	 
 10831 00003226 3B15[B4700000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
 10832                              <1> 				     ; than the address in 'next_page' ?
 10833                              <1> 				     ; (next/first free page value)		
 10834 0000322C 7306                <1> 	jnb	short dap_1	     ; no	
 10835 0000322E 8915[B4700000]      <1> 	mov	[next_page], edx     ; yes
 10836                              <1> dap_1:
 10837 00003234 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
 10838                              <1> 				     ; set relevant bit to 1.
 10839                              <1> 				     ; set CF to the previous bit value	
 10840                              <1> 	;cmc			     ; complement carry flag	
 10841                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
 10842                              <1> 				     ; if the page is already deallocated
 10843                              <1> 				     ; before.	
 10844 00003237 FF05[B0700000]      <1>         inc     dword [free_pages]
 10845                              <1> dap_2:
 10846 0000323D 5A                  <1> 	pop	edx
 10847 0000323E 5B                  <1> 	pop	ebx
 10848 0000323F C3                  <1> 	retn
 10849                              <1> 
 10850                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 10851                              <1> ;;                                                              ;;
 10852                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
 10853                              <1> ;; Distributed under terms of the GNU General Public License    ;;
 10854                              <1> ;;                                                              ;;
 10855                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 10856                              <1> 
 10857                              <1> ;;$Revision: 5057 $
 10858                              <1> 
 10859                              <1> 
 10860                              <1> ;;align 4
 10861                              <1> ;;proc alloc_page
 10862                              <1> 
 10863                              <1> ;;        pushfd
 10864                              <1> ;;        cli
 10865                              <1> ;;        push    ebx
 10866                              <1> ;;;//-
 10867                              <1> ;;        cmp     [pg_data.pages_free], 1
 10868                              <1> ;;        jle     .out_of_memory
 10869                              <1> ;;;//-
 10870                              <1> ;;
 10871                              <1> ;;        mov     ebx, [page_start]
 10872                              <1> ;;        mov     ecx, [page_end]
 10873                              <1> ;;.l1:
 10874                              <1> ;;        bsf     eax, [ebx];
 10875                              <1> ;;        jnz     .found
 10876                              <1> ;;        add     ebx, 4
 10877                              <1> ;;        cmp     ebx, ecx
 10878                              <1> ;;        jb      .l1
 10879                              <1> ;;        pop     ebx
 10880                              <1> ;;        popfd
 10881                              <1> ;;        xor     eax, eax
 10882                              <1> ;;        ret
 10883                              <1> ;;.found:
 10884                              <1> ;;;//-
 10885                              <1> ;;        dec     [pg_data.pages_free]
 10886                              <1> ;;        jz      .out_of_memory
 10887                              <1> ;;;//-
 10888                              <1> ;;        btr     [ebx], eax
 10889                              <1> ;;        mov     [page_start], ebx
 10890                              <1> ;;        sub     ebx, sys_pgmap
 10891                              <1> ;;        lea     eax, [eax+ebx*8]
 10892                              <1> ;;        shl     eax, 12
 10893                              <1> ;;;//-       dec [pg_data.pages_free]
 10894                              <1> ;;        pop     ebx
 10895                              <1> ;;        popfd
 10896                              <1> ;;        ret
 10897                              <1> ;;;//-
 10898                              <1> ;;.out_of_memory:
 10899                              <1> ;;        mov     [pg_data.pages_free], 1
 10900                              <1> ;;        xor     eax, eax
 10901                              <1> ;;        pop     ebx
 10902                              <1> ;;        popfd
 10903                              <1> ;;        ret
 10904                              <1> ;;;//-
 10905                              <1> ;;endp
 10906                              <1> 
 10907                              <1> duplicate_page_dir:
 10908                              <1> 	; 21/09/2015
 10909                              <1> 	; 31/08/2015
 10910                              <1> 	; 20/07/2015
 10911                              <1> 	; 28/04/2015
 10912                              <1> 	; 27/04/2015
 10913                              <1> 	; 18/04/2015
 10914                              <1> 	; 12/04/2015
 10915                              <1> 	; 18/10/2014
 10916                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 10917                              <1> 	;
 10918                              <1> 	; INPUT -> 
 10919                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 10920                              <1> 	;		    page directory.
 10921                              <1> 	; OUTPUT ->
 10922                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 10923                              <1> 	;	       page directory.
 10924                              <1> 	;	(New page directory with new page table entries.)
 10925                              <1> 	;	(New page tables with read only copies of the parent's
 10926                              <1> 	;	pages.)
 10927                              <1> 	;	EAX = 0 -> Error (CF = 1)
 10928                              <1> 	;
 10929                              <1> 	; Modified Registers -> none (except EAX)
 10930                              <1> 	;
 10931 00003240 E8F2FDFFFF          <1> 	call	allocate_page
 10932 00003245 723E                <1> 	jc	short dpd_err
 10933                              <1> 	;
 10934 00003247 55                  <1> 	push	ebp ; 20/07/2015
 10935 00003248 56                  <1> 	push	esi
 10936 00003249 57                  <1> 	push	edi
 10937 0000324A 53                  <1> 	push	ebx
 10938 0000324B 51                  <1> 	push	ecx
 10939 0000324C 8B35[D9740000]      <1> 	mov	esi, [u.pgdir]
 10940 00003252 89C7                <1> 	mov	edi, eax
 10941 00003254 50                  <1> 	push	eax ; save child's page directory address
 10942                              <1> 	; 31/08/2015
 10943                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 10944                              <1> 	; (use same system space for all user page tables) 
 10945 00003255 A5                  <1> 	movsd
 10946 00003256 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 10947 0000325B B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 10948                              <1> dpd_0:	
 10949 00003260 AD                  <1> 	lodsd
 10950                              <1> 	;or	eax, eax
 10951                              <1>         ;jnz     short dpd_1
 10952 00003261 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 10953 00003263 7508                <1> 	jnz	short dpd_1
 10954                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
 10955 00003265 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 10956 0000326B EB0F                <1> 	jmp	short dpd_2
 10957                              <1> dpd_1:	
 10958 0000326D 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 10959 00003271 89C3                <1> 	mov	ebx, eax
 10960                              <1> 	; EBX = Parent's page table address
 10961 00003273 E81F000000          <1> 	call	duplicate_page_table
 10962 00003278 720C                <1> 	jc	short dpd_p_err
 10963                              <1> 	; EAX = Child's page table address
 10964 0000327A 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 10965                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 10966                              <1> 			 ; (present, writable, user)
 10967                              <1> dpd_2:
 10968 0000327C AB                  <1> 	stosd
 10969 0000327D E2E1                <1> 	loop	dpd_0
 10970                              <1> 	;
 10971 0000327F 58                  <1> 	pop	eax  ; restore child's page directory address
 10972                              <1> dpd_3:
 10973 00003280 59                  <1> 	pop	ecx
 10974 00003281 5B                  <1> 	pop	ebx
 10975 00003282 5F                  <1> 	pop	edi
 10976 00003283 5E                  <1> 	pop	esi
 10977 00003284 5D                  <1> 	pop	ebp ; 20/07/2015
 10978                              <1> dpd_err:
 10979 00003285 C3                  <1> 	retn
 10980                              <1> dpd_p_err:
 10981                              <1> 	; release the allocated pages missing (recover free space)
 10982 00003286 58                  <1> 	pop	eax  ; the new page directory address (physical)
 10983 00003287 8B1D[D9740000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 10984 0000328D E8DEFEFFFF          <1> 	call 	deallocate_page_dir
 10985 00003292 29C0                <1> 	sub	eax, eax ; 0
 10986 00003294 F9                  <1> 	stc
 10987 00003295 EBE9                <1> 	jmp	short dpd_3	
 10988                              <1> 
 10989                              <1> duplicate_page_table:
 10990                              <1> 	; 21/09/2015
 10991                              <1> 	; 20/07/2015
 10992                              <1> 	; 05/05/2015
 10993                              <1> 	; 28/04/2015
 10994                              <1> 	; 27/04/2015
 10995                              <1> 	; 18/04/2015
 10996                              <1> 	; 18/10/2014
 10997                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 10998                              <1> 	;
 10999                              <1> 	; INPUT -> 
 11000                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 11001                              <1> 	;	EBP = page table entry index (from 'duplicate_page_dir')
 11002                              <1> 	; OUTPUT ->
 11003                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 11004                              <1> 	;	      (with 'read only' attribute of page table entries)
 11005                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 11006                              <1> 	;	CF = 1 -> error 
 11007                              <1> 	;
 11008                              <1> 	; Modified Registers -> EBP (except EAX)
 11009                              <1> 	;
 11010 00003297 E89BFDFFFF          <1> 	call	allocate_page
 11011 0000329C 726A                <1> 	jc	short dpt_err
 11012                              <1> 	;
 11013 0000329E 50                  <1> 	push	eax ; *
 11014 0000329F 56                  <1> 	push	esi
 11015 000032A0 57                  <1> 	push	edi
 11016 000032A1 52                  <1> 	push	edx
 11017 000032A2 51                  <1> 	push	ecx
 11018                              <1> 	;
 11019 000032A3 89DE                <1> 	mov	esi, ebx
 11020 000032A5 89C7                <1> 	mov	edi, eax
 11021 000032A7 89C2                <1> 	mov	edx, eax
 11022 000032A9 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 11023                              <1> dpt_0:
 11024 000032AF AD                  <1> 	lodsd
 11025 000032B0 21C0                <1> 	and	eax, eax
 11026 000032B2 7444                <1> 	jz	short dpt_3
 11027 000032B4 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 11028 000032B6 7507                <1> 	jnz	short dpt_1
 11029                              <1> 	; 20/07/2015
 11030                              <1> 	; ebp = virtual (linear) address of the memory page
 11031 000032B8 E887040000          <1> 	call	reload_page ; 28/04/2015
 11032 000032BD 7244                <1> 	jc	short dpt_p_err
 11033                              <1> dpt_1:
 11034                              <1> 	; 21/09/2015
 11035 000032BF 89C1                <1> 	mov	ecx, eax
 11036 000032C1 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11037 000032C5 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
 11038 000032C8 7525                <1> 	jnz	short dpt_2
 11039                              <1> 	; Read only (parent) page
 11040                              <1> 	; 	- there is a third process which uses this page -
 11041                              <1> 	; Allocate a new page for the child process
 11042 000032CA E868FDFFFF          <1> 	call	allocate_page
 11043 000032CF 7232                <1> 	jc	short dpt_p_err
 11044 000032D1 57                  <1> 	push	edi
 11045 000032D2 56                  <1> 	push	esi
 11046 000032D3 89CE                <1> 	mov	esi, ecx
 11047 000032D5 89C7                <1> 	mov	edi, eax
 11048 000032D7 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 11049 000032DC F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 11050 000032DE 5E                  <1> 	pop	esi
 11051 000032DF 5F                  <1> 	pop	edi
 11052                              <1> 	; 
 11053 000032E0 53                  <1> 	push	ebx
 11054 000032E1 50                  <1> 	push	eax
 11055                              <1> 	; 20/07/2015
 11056 000032E2 89EB                <1> 	mov	ebx, ebp
 11057                              <1> 	; ebx = virtual address of the memory page
 11058 000032E4 E80B030000          <1> 	call	add_to_swap_queue
 11059 000032E9 58                  <1> 	pop	eax
 11060 000032EA 5B                  <1> 	pop	ebx
 11061                              <1> 	; 21/09/2015
 11062 000032EB 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 11063                              <1> 		; user + writable + present page
 11064 000032ED EB09                <1> 	jmp	short dpt_3
 11065                              <1> dpt_2:
 11066                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 11067 000032EF 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
 11068                              <1> 		    ; (read only page!)
 11069 000032F1 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
 11070 000032F4 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
 11071                              <1> dpt_3:
 11072 000032F8 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 11073                              <1> 	;
 11074 000032F9 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 11075                              <1> 	;
 11076 000032FF 39D7                <1> 	cmp	edi, edx
 11077 00003301 72AC                <1> 	jb	short dpt_0
 11078                              <1> dpt_p_err:
 11079 00003303 59                  <1> 	pop	ecx
 11080 00003304 5A                  <1> 	pop	edx
 11081 00003305 5F                  <1> 	pop	edi
 11082 00003306 5E                  <1> 	pop	esi
 11083 00003307 58                  <1> 	pop	eax ; *
 11084                              <1> dpt_err:
 11085 00003308 C3                  <1> 	retn
 11086                              <1> 
 11087                              <1> page_fault_handler:	; CPU EXCEPTION 0Eh (14) : Page Fault !
 11088                              <1> 	; 21/09/2015
 11089                              <1> 	; 19/09/2015
 11090                              <1> 	; 17/09/2015
 11091                              <1> 	; 28/08/2015
 11092                              <1> 	; 20/07/2015
 11093                              <1> 	; 28/06/2015
 11094                              <1> 	; 03/05/2015
 11095                              <1> 	; 30/04/2015
 11096                              <1> 	; 18/04/2015
 11097                              <1> 	; 12/04/2015
 11098                              <1> 	; 30/10/2014
 11099                              <1> 	; 11/09/2014
 11100                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
 11101                              <1> 	;
 11102                              <1> 	; Note: This is not an interrupt/exception handler.
 11103                              <1> 	;	This is a 'page fault remedy' subroutine 
 11104                              <1> 	;	which will be called by standard/uniform
 11105                              <1> 	;	exception handler.
 11106                              <1> 	;
 11107                              <1> 	; INPUT -> 
 11108                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
 11109                              <1> 	;
 11110                              <1> 	;	cr2 = the virtual (linear) address 
 11111                              <1> 	;	      which has caused to page fault (19/09/2015)
 11112                              <1> 	;
 11113                              <1> 	; OUTPUT ->
 11114                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11115                              <1> 	;	EAX = 0 -> no error
 11116                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
 11117                              <1> 	;
 11118                              <1> 	; Modified Registers -> none (except EAX)
 11119                              <1> 	;	
 11120                              <1>         ;
 11121                              <1>         ; ERROR CODE:
 11122                              <1> 	;	 31  .....	4   3	2   1	0
 11123                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11124                              <1> 	;	|   Reserved  | I | R | U | W | P |
 11125                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11126                              <1> 	;
 11127                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
 11128                              <1>     	;		a page-protection violation. When not set,
 11129                              <1> 	;		it was caused by a non-present page.
 11130                              <1> 	; W : WRITE   -	When set, the page fault was caused by
 11131                              <1> 	;		a page write. When not set, it was caused
 11132                              <1> 	;		by a page read.
 11133                              <1> 	; U : USER    -	When set, the page fault was caused 
 11134                              <1> 	;		while CPL = 3. 
 11135                              <1> 	;		This does not necessarily mean that
 11136                              <1> 	;		the page fault was a privilege violation.
 11137                              <1> 	; R : RESERVD -	When set, the page fault was caused by
 11138                              <1> 	;     WRITE	reading a 1 in a reserved field.
 11139                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
 11140                              <1> 	;     FETCH	an instruction fetch
 11141                              <1> 	;
 11142                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
 11143                              <1> 	;  31               22                  12 11                    0
 11144                              <1> 	; +-------------------+-------------------+-----------------------+
 11145                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
 11146                              <1>        	; +-------------------+-------------------+-----------------------+
 11147                              <1> 	;
 11148                              <1> 
 11149                              <1> 	;; CR3 REGISTER (Control Register 3)
 11150                              <1> 	;  31                                   12             5 4 3 2   0
 11151                              <1> 	; +---------------------------------------+-------------+---+-----+
 11152                              <1>       	; |                                       |  		|P|P|     |
 11153                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
 11154                              <1>       	; |                                       | 		|D|T|     |
 11155                              <1>    	; +---------------------------------------+-------------+---+-----+
 11156                              <1> 	;
 11157                              <1> 	;	PWT    - WRITE THROUGH
 11158                              <1> 	;	PCD    - CACHE DISABLE		
 11159                              <1> 	;
 11160                              <1> 	;
 11161                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
 11162                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11163                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11164                              <1>       	; |                                       |     | | | | |P|P|U|R| |
 11165                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
 11166                              <1>       	; |                                       |     | | | | |D|T|S|W| |
 11167                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11168                              <1> 	;
 11169                              <1>         ;       P      - PRESENT
 11170                              <1>         ;       R/W    - READ/WRITE
 11171                              <1>         ;       U/S    - USER/SUPERVISOR
 11172                              <1> 	;	PWT    - WRITE THROUGH
 11173                              <1> 	;	PCD    - CACHE DISABLE	
 11174                              <1> 	;	A      - ACCESSED	
 11175                              <1>         ;       D      - DIRTY (IGNORED)
 11176                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11177                              <1> 	;	G      - GLOBAL	(IGNORED) 
 11178                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11179                              <1> 	;
 11180                              <1> 	;
 11181                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
 11182                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11183                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11184                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
 11185                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
 11186                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
 11187                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11188                              <1> 	;
 11189                              <1>         ;       P      - PRESENT
 11190                              <1>         ;       R/W    - READ/WRITE
 11191                              <1>         ;       U/S    - USER/SUPERVISOR
 11192                              <1> 	;	PWT    - WRITE THROUGH
 11193                              <1> 	;	PCD    - CACHE DISABLE	
 11194                              <1> 	;	A      - ACCESSED	
 11195                              <1>         ;       D      - DIRTY
 11196                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11197                              <1> 	;	G      - GLOBAL	 
 11198                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11199                              <1> 	;
 11200                              <1> 	;
 11201                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
 11202                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11203                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11204                              <1>       	; |                                       |     | | | | | | |U|R| |
 11205                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
 11206                              <1>       	; |                                       |     | | | | | | |S|W| |
 11207                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11208                              <1> 	;
 11209                              <1>         ;       P      - PRESENT
 11210                              <1>         ;       R/W    - READ/WRITE
 11211                              <1>         ;       U/S    - USER/SUPERVISOR
 11212                              <1>         ;       D      - DIRTY
 11213                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11214                              <1> 	;
 11215                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
 11216                              <1> 	;
 11217                              <1> 	;
 11218                              <1> 	;; Invalid Page Table Entry
 11219                              <1> 	; 31                                                           1 0
 11220                              <1>       	; +-------------------------------------------------------------+-+
 11221                              <1>       	; |                                                             | |
 11222                              <1>       	; |                          AVAILABLE                          |0|
 11223                              <1>       	; |                                                             | |
 11224                              <1>       	; +-------------------------------------------------------------+-+
 11225                              <1> 	;
 11226                              <1> 
 11227 00003309 53                  <1> 	push	ebx
 11228 0000330A 52                  <1> 	push	edx
 11229 0000330B 51                  <1> 	push	ecx
 11230                              <1> 	;
 11231                              <1> 	; 21/09/2015 (debugging)
 11232 0000330C FF05[E9740000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
 11233 00003312 FF05[58810000]      <1> 	inc	dword [PF_Count] ; total page fault count	
 11234                              <1> 	; 28/06/2015
 11235                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
 11236 00003318 8A15[50810000]      <1> 	mov	dl, [error_code]
 11237                              <1> 	;
 11238 0000331E F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
 11239                              <1> 			; sign
 11240 00003321 7422                <1> 	jz	short pfh_alloc_np
 11241                              <1> 	; 
 11242                              <1> 	; If it is not a 'write on read only page' type page fault
 11243                              <1> 	; major page fault error with minor reason must be returned without 
 11244                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
 11245                              <1> 	; after return here!
 11246                              <1> 	; Page fault will be remedied, by copying page contents
 11247                              <1> 	; to newly allocated page with write permission;
 11248                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
 11249                              <1> 	; used for working with minimum possible memory usage. 
 11250                              <1> 	; sys_fork will duplicate page directory and tables of parent  
 11251                              <1> 	; process with 'read only' flag. If the child process attempts to
 11252                              <1> 	; write on these read only pages, page fault will be directed here
 11253                              <1> 	; for allocating a new page with same data/content. 
 11254                              <1> 	;
 11255                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
 11256                              <1> 	; will not force to separate CODE and DATA space 
 11257                              <1> 	; in a process/program... 
 11258                              <1> 	; CODE segment/section may contain DATA!
 11259                              <1> 	; It is flat, smoth and simplest programming method already as in 
 11260                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
 11261                              <1> 	;	
 11262 00003323 F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
 11263                              <1> 			; sign
 11264 00003326 0F84AB000000        <1>         jz      pfh_p_err
 11265                              <1> 	; 31/08/2015
 11266 0000332C F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
 11267                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
 11268 0000332F 0F84A2000000        <1>         jz	pfh_pv_err
 11269                              <1> 	;
 11270                              <1> 	; make a new page and copy the parent's page content
 11271                              <1> 	; as the child's new page content
 11272                              <1> 	;
 11273 00003335 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
 11274                              <1> 			 ; which has caused to page fault
 11275 00003338 E8A2000000          <1> 	call 	copy_page
 11276 0000333D 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
 11277                              <1> 	;
 11278 00003343 EB7D                <1>         jmp     pfh_cpp_ok
 11279                              <1> 	;
 11280                              <1> pfh_alloc_np:
 11281 00003345 E8EDFCFFFF          <1> 	call	allocate_page	; (allocate a new page)
 11282 0000334A 0F8280000000        <1>         jc      pfh_im_err	; 'insufficient memory' error
 11283                              <1> pfh_chk_cpl:
 11284                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11285                              <1> 		; (Lower 12 bits are ZERO, because 
 11286                              <1> 		;	the address is on a page boundary)
 11287 00003350 80E204              <1> 	and	dl, 4	; CPL = 3 ?
 11288 00003353 7505                <1> 	jnz	short pfh_um
 11289                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
 11290 00003355 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
 11291                              <1> 			 ; of the current/active page directory
 11292                              <1> 			 ; (Always kernel/system mode page directory, here!)
 11293                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
 11294 00003358 EB06                <1> 	jmp	short pfh_get_pde
 11295                              <1> 	;
 11296                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
 11297 0000335A 8B1D[D9740000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
 11298                              <1> 			; Physical address of the USER's page directory
 11299                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
 11300                              <1> pfh_get_pde:
 11301 00003360 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
 11302 00003363 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
 11303                              <1> 			 ; which has been caused to page fault
 11304                              <1> 			 ;
 11305 00003366 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
 11306 00003369 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
 11307                              <1> 	;
 11308 0000336C 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
 11309 0000336E 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
 11310 00003370 F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
 11311 00003373 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
 11312                              <1> 			  	  ; set/validate page directory entry
 11313 00003375 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 11314 0000337A 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
 11315 0000337C 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
 11316 0000337E EB16                <1> 	jmp	short pfh_get_pte
 11317                              <1> pfh_set_pde:
 11318                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
 11319                              <1> 	;;	 (So, we know this PDE is empty or invalid)
 11320                              <1> 	;
 11321 00003380 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
 11322 00003382 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
 11323 00003384 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
 11324 00003386 89C3                <1> 	mov	ebx, eax
 11325 00003388 E8AAFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
 11326 0000338D 7241                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
 11327                              <1> pfh_spde_1:
 11328                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11329 0000338F 89C1                <1> 	mov	ecx, eax
 11330 00003391 E81BFDFFFF          <1> 	call	clear_page ; Clear page content
 11331                              <1> pfh_get_pte:
 11332 00003396 0F20D0              <1> 	mov	eax, cr2 ; virtual address
 11333                              <1> 			 ; which has been caused to page fault
 11334 00003399 89C7                <1> 	mov	edi, eax ; 20/07/2015
 11335 0000339B C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
 11336                              <1> 			 ; higher 20 bits of the page fault address 
 11337 0000339E 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
 11338 000033A3 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
 11339 000033A6 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
 11340 000033A8 8B03                <1> 	mov	eax, [ebx] ; get previous value of pte
 11341                              <1> 		; bit 0 of EAX is always 0 (otherwise we would not be here)
 11342 000033AA 21C0                <1> 	and	eax, eax
 11343 000033AC 7410                <1> 	jz	short pfh_gpte_1
 11344                              <1> 	; 20/07/2015
 11345 000033AE 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
 11346 000033B0 55                  <1> 	push	ebp ; 20/07/2015
 11347 000033B1 0F20D5              <1> 	mov	ebp, cr2
 11348                              <1> 		; ECX = physical address of the page table entry
 11349                              <1> 		; EBX = Memory page address (physical!)
 11350                              <1> 		; EAX = Swap disk (offset) address
 11351                              <1> 		; EBP = virtual address (page fault address)
 11352 000033B4 E8B7000000          <1> 	call	swap_in
 11353 000033B9 5D                  <1> 	pop	ebp
 11354 000033BA 7210                <1> 	jc      short pfh_err_retn
 11355 000033BC 87CB                <1> 	xchg	ecx, ebx
 11356                              <1> 		; EBX = physical address of the page table entry
 11357                              <1> 		; ECX = new page
 11358                              <1> pfh_gpte_1:
 11359 000033BE 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
 11360 000033C0 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
 11361                              <1> pfh_cpp_ok:
 11362                              <1> 	; 20/07/2015
 11363 000033C2 0F20D3              <1> 	mov	ebx, cr2
 11364 000033C5 E82A020000          <1> 	call 	add_to_swap_queue
 11365                              <1> 	;
 11366                              <1> 	; The new PTE (which contains the new page) will be added to 
 11367                              <1> 	; the swap queue, here. 
 11368                              <1> 	; (Later, if memory will become insufficient, 
 11369                              <1> 	; one page will be swapped out which is at the head of 
 11370                              <1> 	; the swap queue by using FIFO and access check methods.)
 11371                              <1> 	;
 11372 000033CA 31C0                <1> 	xor	eax, eax  ; 0
 11373                              <1> 	;
 11374                              <1> pfh_err_retn:
 11375 000033CC 59                  <1> 	pop	ecx
 11376 000033CD 5A                  <1> 	pop	edx
 11377 000033CE 5B                  <1> 	pop	ebx
 11378 000033CF C3                  <1> 	retn 
 11379                              <1> 	
 11380                              <1> pfh_im_err:
 11381 000033D0 B8E1000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
 11382                              <1> 			; Major (Primary) Error: Page Fault
 11383                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
 11384 000033D5 EBF5                <1> 	jmp	short pfh_err_retn
 11385                              <1> 
 11386                              <1> 
 11387                              <1> pfh_p_err: ; 09/03/2015
 11388                              <1> pfh_pv_err:
 11389                              <1> 	; Page fault was caused by a protection-violation
 11390 000033D7 B8E3000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
 11391                              <1> 			; Major (Primary) Error: Page Fault
 11392                              <1> 			; Minor (Secondary) Error: Protection violation !
 11393 000033DC F9                  <1> 	stc
 11394 000033DD EBED                <1> 	jmp	short pfh_err_retn
 11395                              <1> 
 11396                              <1> copy_page:
 11397                              <1> 	; 22/09/2015
 11398                              <1> 	; 21/09/2015
 11399                              <1> 	; 19/09/2015
 11400                              <1> 	; 07/09/2015
 11401                              <1> 	; 31/08/2015
 11402                              <1> 	; 20/07/2015
 11403                              <1> 	; 05/05/2015
 11404                              <1> 	; 03/05/2015
 11405                              <1> 	; 18/04/2015
 11406                              <1> 	; 12/04/2015
 11407                              <1> 	; 30/10/2014
 11408                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
 11409                              <1> 	;
 11410                              <1> 	; INPUT -> 
 11411                              <1> 	;	EBX = Virtual (linear) address of source page
 11412                              <1> 	;	     (Page fault address)
 11413                              <1> 	; OUTPUT ->
 11414                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11415                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11416                              <1> 	;	EAX = 0 (CF = 1) 
 11417                              <1> 	;		if there is not a free page to be allocated
 11418                              <1> 	;	(page content of the source page will be copied
 11419                              <1> 	;	onto the target/new page) 	
 11420                              <1> 	;
 11421                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
 11422                              <1> 	;	
 11423 000033DF 56                  <1> 	push	esi
 11424 000033E0 57                  <1> 	push	edi
 11425                              <1> 	;push	ebx
 11426                              <1> 	;push	ecx
 11427 000033E1 31F6                <1> 	xor 	esi, esi
 11428 000033E3 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
 11429 000033E6 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
 11430 000033E8 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
 11431 000033EB 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
 11432 000033EE 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
 11433 000033F0 031D[D9740000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
 11434 000033F6 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
 11435 000033F8 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
 11436 000033FC 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
 11437 000033FE 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11438 00003404 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
 11439 00003408 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
 11440                              <1> 	; 07/09/2015
 11441 0000340A 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
 11442                              <1> 				     ; read only page as a child process?)	
 11443 0000340F 7509                <1> 	jnz	short cpp_0 ; yes
 11444 00003411 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
 11445 00003413 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
 11446 00003418 EB32                <1> 	jmp	short cpp_1
 11447                              <1> cpp_0:
 11448 0000341A 89FE                <1> 	mov	esi, edi
 11449 0000341C 0335[DD740000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
 11450 00003422 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
 11451 00003424 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11452 00003428 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
 11453 0000342A 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11454 00003430 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
 11455 00003434 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
 11456 00003436 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
 11457                              <1> 	; 21/09/2015
 11458 00003438 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
 11459 0000343A 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
 11460                              <1> 	;
 11461 0000343E F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
 11462 00003441 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
 11463                              <1> 	;
 11464 00003443 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
 11465 00003448 39C8                <1> 	cmp	eax, ecx   ; Same page?	
 11466 0000344A 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
 11467                              <1> 			    ; Convert child's page to writable page
 11468                              <1> cpp_1:
 11469 0000344C E8E6FBFFFF          <1> 	call	allocate_page
 11470 00003451 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
 11471 00003453 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
 11472 00003455 7405                <1> 	jz	short cpp_2
 11473                              <1> 		; Convert read only page to writable page 
 11474                              <1> 		;(for the parent of the current process)
 11475                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
 11476                              <1> 	; 22/09/2015
 11477 00003457 890E                <1> 	mov	[esi], ecx
 11478 00003459 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
 11479                              <1> 				 ; 1+2+4 = 7
 11480                              <1> cpp_2:
 11481 0000345C 89C7                <1> 	mov	edi, eax ; new page address of the child process
 11482                              <1> 	; 07/09/2015
 11483 0000345E 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
 11484 00003460 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 11485 00003465 F3A5                <1> 	rep	movsd ; 31/08/2015
 11486                              <1> cpp_3:		
 11487 00003467 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
 11488 00003469 8903                <1> 	mov	[ebx], eax ; Update PTE
 11489 0000346B 28C0                <1> 	sub	al, al ; clear attributes
 11490                              <1> cpp_4:
 11491                              <1> 	;pop	ecx
 11492                              <1> 	;pop	ebx
 11493 0000346D 5F                  <1> 	pop	edi
 11494 0000346E 5E                  <1> 	pop	esi
 11495 0000346F C3                  <1> 	retn
 11496                              <1> 
 11497                              <1> ;; 28/04/2015
 11498                              <1> ;; 24/10/2014
 11499                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
 11500                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
 11501                              <1> ;;
 11502                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
 11503                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
 11504                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
 11505                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
 11506                              <1> ;;
 11507                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
 11508                              <1> ;;
 11509                              <1> ;; Method:
 11510                              <1> ;;	Swap page queue is a list of allocated pages with physical
 11511                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
 11512                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
 11513                              <1> ;;	When a new page is being allocated, swap queue is updated
 11514                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
 11515                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
 11516                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
 11517                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
 11518                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
 11519                              <1> ;;	offset value becomes it's previous offset value - 4.
 11520                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
 11521                              <1> ;;	the queue/list is not shifted.
 11522                              <1> ;;	After the queue/list shift, newly allocated page is added
 11523                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
 11524                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
 11525                              <1> ;;	will not be added to the tail of swap page queue.  		 
 11526                              <1> ;;	
 11527                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
 11528                              <1> ;;	the first non-accessed, writable page in the list, 
 11529                              <1> ;;	from the head to the tail. The list is shifted to left 
 11530                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
 11531                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
 11532                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
 11533                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
 11534                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
 11535                              <1> ;;	procedure will be failed)...
 11536                              <1> ;;
 11537                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
 11538                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
 11539                              <1> ;;	(PTE) will be added to the tail of the queue after
 11540                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
 11541                              <1> ;;	the queue will be rotated and the PTE in the head will be
 11542                              <1> ;;	added to the tail after resetting 'accessed' bit. 
 11543                              <1> ;;
 11544                              <1> ;;
 11545                              <1> ;;	
 11546                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
 11547                              <1> ;;
 11548                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
 11549                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
 11550                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
 11551                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
 11552                              <1> ;;
 11553                              <1> ;; [swpd_next] = the first free block address in swapped page records
 11554                              <1> ;;    		 for next free block search by 'swap_out' procedure.
 11555                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
 11556                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
 11557                              <1> ;; 		 (entire swap space must be accessed by using
 11558                              <1> ;;		 31 bit offset address) 
 11559                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
 11560                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
 11561                              <1> ;;		  0 for file, or beginning sector of the swap partition
 11562                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
 11563                              <1> ;;
 11564                              <1> ;; 					
 11565                              <1> ;; Method:
 11566                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
 11567                              <1> ;;	procedure swaps out a page from memory to the swap disk 
 11568                              <1> ;;	(partition) or swap file to get a new free page at the memory.
 11569                              <1> ;;	Swapping out is performed by using swap page queue.
 11570                              <1> ;;
 11571                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
 11572                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
 11573                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
 11574                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
 11575                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
 11576                              <1> ;;	Absolute physical (logical) address of the swapped page is 
 11577                              <1> ;;	calculated by adding offset value to the swap partition's 
 11578                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
 11579                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
 11580                              <1> ;;	and offset value is equal to absolute (physical or logical)
 11581                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
 11582                              <1> ;;	is in a partitioned virtual hard disk.) 
 11583                              <1> ;;
 11584                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
 11585                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
 11586                              <1> ;;
 11587                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
 11588                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
 11589                              <1> ;;
 11590                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
 11591                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
 11592                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
 11593                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
 11594                              <1> ;;	it means relevant (respective) block is in use, and, 
 11595                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
 11596                              <1> ;;      swap disk/file block is free.
 11597                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
 11598                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
 11599                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
 11600                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
 11601                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
 11602                              <1> ;;	------------------------------------------------------------
 11603                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
 11604                              <1> ;;	------------------------------------------------------------
 11605                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
 11606                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
 11607                              <1> ;;
 11608                              <1> ;;	..............................................................
 11609                              <1> ;;
 11610                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
 11611                              <1> ;;	then it searches Swap Allocation Table if free count is not
 11612                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
 11613                              <1> ;;	position with value of 1 on the table is converted to swap
 11614                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
 11615                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
 11616                              <1> ;;	number of physical swap disk or virtual swap disk)
 11617                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
 11618                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
 11619                              <1> ;;	(memory page). That will be a direct disk write procedure.
 11620                              <1> ;;	(for preventing late memory allocation, significant waiting). 
 11621                              <1> ;;	If disk write procedure returns with error or free count of 
 11622                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
 11623                              <1> ;;	'insufficient memory error' (cf=1). 
 11624                              <1> ;;
 11625                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
 11626                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
 11627                              <1> ;;	in other words, 'swap_out' will not check the table for other
 11628                              <1> ;;	free blocks after a disk write error. It will return to 
 11629                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
 11630                              <1> ;;
 11631                              <1> ;;	After writing the page on to swap disk/file address/sector,
 11632                              <1> ;;	'swap_out' procesure returns with that swap (offset) sector
 11633                              <1> ;;	address (cf=0). 
 11634                              <1> ;;
 11635                              <1> ;;	..............................................................
 11636                              <1> ;;
 11637                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
 11638                              <1> ;;	file sectors at specified memory page. Then page allocation
 11639                              <1> ;;	procedure updates relevant page table entry with 'present' 
 11640                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
 11641                              <1> ;;	to do, except to terminate the process which is the owner of
 11642                              <1> ;;	the swapped page.
 11643                              <1> ;;
 11644                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
 11645                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
 11646                              <1> ;;	updates [swpd_first] pointer if it is required.
 11647                              <1> ;;
 11648                              <1> ;;	..............................................................	 
 11649                              <1> ;;
 11650                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
 11651                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
 11652                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
 11653                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
 11654                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
 11655                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
 11656                              <1> ;;
 11657                              <1> 
 11658                              <1> swap_in:
 11659                              <1> 	; 31/08/2015
 11660                              <1> 	; 20/07/2015
 11661                              <1> 	; 28/04/2015
 11662                              <1> 	; 18/04/2015
 11663                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 11664                              <1> 	;
 11665                              <1> 	; INPUT -> 
 11666                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
 11667                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
 11668                              <1> 	;	EAX = Offset Address for the swapped page on the
 11669                              <1> 	;	      swap disk or in the swap file.
 11670                              <1> 	;
 11671                              <1> 	; OUTPUT ->
 11672                              <1> 	;	EAX = 0 if loading at memory has been successful
 11673                              <1> 	;
 11674                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
 11675                              <1> 	;		  or sector not present or drive not ready
 11676                              <1> 	;	     EAX = Error code
 11677                              <1> 	;	     [u.error] = EAX 
 11678                              <1> 	;		       = The last error code for the process
 11679                              <1> 	;		         (will be reset after returning to user)	  
 11680                              <1> 	;
 11681                              <1> 	; Modified Registers -> EAX
 11682                              <1> 	;
 11683                              <1> 
 11684 00003470 833D[3A810000]00    <1>         cmp     dword [swp_drv], 0
 11685 00003477 7648                <1> 	jna	short swpin_dnp_err
 11686                              <1> 
 11687 00003479 3B05[3E810000]      <1> 	cmp	eax, [swpd_size]
 11688 0000347F 734C                <1> 	jnb	short swpin_snp_err
 11689                              <1> 
 11690 00003481 56                  <1> 	push	esi
 11691 00003482 53                  <1> 	push	ebx
 11692 00003483 51                  <1> 	push	ecx
 11693 00003484 8B35[3A810000]      <1> 	mov	esi, [swp_drv]	
 11694 0000348A B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 11695                              <1> 		; Note: Even if corresponding physical disk's sector 
 11696                              <1> 		; size different than 512 bytes, logical disk sector
 11697                              <1> 		; size is 512 bytes and disk reading procedure
 11698                              <1> 		; will be performed for reading 4096 bytes
 11699                              <1> 		; (2*2048, 8*512). 
 11700                              <1> 	; ESI = Logical disk description table address
 11701                              <1> 	; EBX = Memory page (buffer) address (physical!)
 11702                              <1> 	; EAX = Sector adress (offset address, logical sector number)
 11703                              <1> 	; ECX = Sector count ; 8 sectors
 11704 0000348F 50                  <1> 	push	eax
 11705 00003490 E833020000          <1> 	call	logical_disk_read
 11706 00003495 58                  <1> 	pop	eax
 11707 00003496 730C                <1> 	jnc	short swpin_read_ok
 11708                              <1> 	;
 11709 00003498 B804000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
 11710 0000349D A3[D5740000]        <1> 	mov	[u.error], eax
 11711 000034A2 EB19                <1> 	jmp	short swpin_retn
 11712                              <1> 	;
 11713                              <1> swpin_read_ok:
 11714                              <1> 	; EAX = Offset address (logical sector number)
 11715 000034A4 E891010000          <1> 	call	unlink_swap_block  ; Deallocate swap block	
 11716                              <1> 	;
 11717                              <1> 	; EBX = Memory page (buffer) address (physical!)
 11718                              <1> 	; 20/07/2015
 11719 000034A9 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
 11720 000034AB 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 11721 000034B0 8A1D[CF740000]      <1> 	mov	bl, [u.uno] ; current process number
 11722                              <1> 	; EBX = Virtual address & process number combination
 11723 000034B6 E89E000000          <1> 	call	swap_queue_shift
 11724 000034BB 29C0                <1> 	sub	eax, eax  ; 0 ; Error Code = 0  (no error)
 11725                              <1> 	;
 11726                              <1> swpin_retn:
 11727 000034BD 59                  <1> 	pop	ecx
 11728 000034BE 5B                  <1> 	pop	ebx
 11729 000034BF 5E                  <1> 	pop	esi
 11730 000034C0 C3                  <1> 	retn
 11731                              <1> 
 11732                              <1> swpin_dnp_err:
 11733 000034C1 B805000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
 11734                              <1> swpin_err_retn:
 11735 000034C6 A3[D5740000]        <1> 	mov	[u.error], eax
 11736 000034CB F9                  <1> 	stc
 11737 000034CC C3                  <1> 	retn
 11738                              <1> 
 11739                              <1> swpin_snp_err:
 11740 000034CD B806000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
 11741 000034D2 EBF2                <1> 	jmp	short swpin_err_retn
 11742                              <1> 
 11743                              <1> swap_out:
 11744                              <1> 	; 31/08/2015
 11745                              <1> 	; 05/05/2015
 11746                              <1> 	; 30/04/2015
 11747                              <1> 	; 28/04/2015
 11748                              <1> 	; 18/04/2015
 11749                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 11750                              <1> 	;
 11751                              <1> 	; INPUT -> 
 11752                              <1> 	;	none
 11753                              <1> 	;
 11754                              <1> 	; OUTPUT ->
 11755                              <1> 	;	EAX = Physical page address (which is swapped out
 11756                              <1> 	;	      for allocating a new page)
 11757                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
 11758                              <1> 	;		  or sector not present or drive not ready
 11759                              <1> 	;	     EAX = Error code
 11760                              <1> 	;	     [u.error] = EAX 
 11761                              <1> 	;		       = The last error code for the process
 11762                              <1> 	;		         (will be reset after returning to user)	  
 11763                              <1> 	;
 11764                              <1> 	; Modified Registers -> non (except EAX)
 11765                              <1> 	;
 11766 000034D4 66833D[38810000]01  <1> 	cmp 	word [swpq_count], 1
 11767 000034DC 7274                <1>         jc      short swpout_im_err ; 'insufficient memory'
 11768                              <1> 
 11769                              <1>         ;cmp     dword [swp_drv], 1
 11770                              <1> 	;jc	short swpout_dnp_err ; 'swap disk/file not present'
 11771                              <1> 
 11772 000034DE 833D[42810000]01    <1>         cmp     dword [swpd_free], 1
 11773 000034E5 7258                <1> 	jc	short swpout_nfspc_err ; 'no free space on swap disk'
 11774                              <1> 
 11775 000034E7 53                  <1> 	push	ebx
 11776                              <1> swpout_1:
 11777 000034E8 31DB                <1> 	xor	ebx, ebx
 11778 000034EA E86A000000          <1> 	call	swap_queue_shift
 11779 000034EF 21C0                <1> 	and	eax, eax	; entry count (before shifting)
 11780 000034F1 7457                <1> 	jz	short swpout_npts_err  ; There is no any PTE in
 11781                              <1> 				       ; the swap queue
 11782 000034F3 BB00E00800          <1> 	mov	ebx, swap_queue	       ; Addres of the head of 
 11783                              <1> 				       ; the swap queue		
 11784 000034F8 8B03                <1> 	mov	eax, [ebx]	       ; The PTE in the queue head	
 11785                              <1> 
 11786                              <1> 	;test	al, PTE_A_PRESENT      ; bit 0 = 1
 11787                              <1> 	;jz	short swpout_1	       ; non-present page already
 11788                              <1> 				       ; must not be in the queue
 11789                              <1> 
 11790                              <1> 	;test	al, PTE_A_WRITE	       ; bit 1 = 0
 11791                              <1> 	;jz	short swpout_1 	       ; read only page (must not be
 11792                              <1> 				       ; swapped out)
 11793                              <1> 	
 11794 000034FA A820                <1> 	test	al, PTE_A_ACCESS       ; bit 5 = 1 (Accessed)
 11795 000034FC 75EA                <1> 	jnz	short swpout_1 	       ; accessed page (must not be
 11796                              <1> 				       ; swapped out, at this stage)
 11797                              <1> 	;
 11798 000034FE 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11799                              <1> 	;
 11800 00003502 52                  <1> 	push	edx
 11801 00003503 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
 11802 00003505 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
 11803                              <1> 	;
 11804 00003507 E861010000          <1> 	call	link_swap_block
 11805 0000350C 7304                <1> 	jnc	short swpout_2	       ; It may not be needed here	
 11806 0000350E 5A                  <1> 	pop	edx		       ; because [swpd_free] value	
 11807 0000350F 5B                  <1> 	pop	ebx
 11808 00003510 EB2D                <1> 	jmp	short swpout_nfspc_err ; was checked at the beginging. 	
 11809                              <1> swpout_2:	
 11810 00003512 56                  <1> 	push	esi
 11811 00003513 51                  <1> 	push	ecx
 11812 00003514 50                  <1> 	push	eax ; sector address
 11813 00003515 8B35[3A810000]      <1> 	mov	esi, [swp_drv]	
 11814 0000351B B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 11815                              <1> 		; Note: Even if corresponding physical disk's sector 
 11816                              <1> 		; size different than 512 bytes, logical disk sector
 11817                              <1> 		; size is 512 bytes and disk writing procedure
 11818                              <1> 		; will be performed for writing 4096 bytes
 11819                              <1> 		; (2*2048, 8*512). 
 11820                              <1> 	; ESI = Logical disk description table address
 11821                              <1> 	; EBX = Buffer address
 11822                              <1> 	; EAX = Sector adress (offset address, logical sector number)
 11823                              <1> 	; ECX = Sector count ; 8 sectors
 11824 00003520 E8A4010000          <1> 	call	logical_disk_write
 11825 00003525 59                  <1> 	pop	ecx ; sector address	
 11826 00003526 730C                <1> 	jnc	short swpout_write_ok
 11827                              <1> 	;
 11828                              <1> 	;; call	unlink_swap_block ; this block must be left as 'in use'
 11829                              <1> swpout_dw_err:
 11830 00003528 B808000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
 11831 0000352D A3[D5740000]        <1> 	mov	[u.error], eax
 11832 00003532 EB06                <1> 	jmp	short swpout_retn
 11833                              <1> 	;
 11834                              <1> swpout_write_ok:
 11835                              <1> 	; EBX = Buffer (page) address
 11836                              <1> 	; EDX = Page Table entry address
 11837                              <1> 	; ECX = Swap disk sector (file block) address (31 bit)
 11838 00003534 D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
 11839 00003536 890A                <1> 	mov 	[edx], ecx 
 11840                              <1> 		; bit 0 = 0 (swapped page)
 11841 00003538 89D8                <1> 	mov	eax, ebx
 11842                              <1> swpout_retn:
 11843 0000353A 59                  <1> 	pop	ecx
 11844 0000353B 5E                  <1> 	pop	esi
 11845 0000353C 5A                  <1> 	pop	edx
 11846 0000353D 5B                  <1> 	pop	ebx
 11847 0000353E C3                  <1> 	retn
 11848                              <1> 
 11849                              <1> ; Note: Swap_queue will not be updated in 'swap_out' procedure
 11850                              <1> ;	after the page is swapped out. (the PTE at the queue head
 11851                              <1> ;	-with 'non-present' attribute- will be dropped from the
 11852                              <1> ;	the queue in next 'swap_out' or in next 'swap_queue_shift'.
 11853                              <1> 	
 11854                              <1> ;swpout_dnp_err:
 11855                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
 11856                              <1> ;	jmp	short swpout_err_retn
 11857                              <1> swpout_nfspc_err:
 11858 0000353F B807000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
 11859                              <1> swpout_err_retn:
 11860 00003544 A3[D5740000]        <1> 	mov	[u.error], eax
 11861                              <1> 	;stc
 11862 00003549 C3                  <1> 	retn
 11863                              <1> swpout_npts_err:
 11864 0000354A B809000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
 11865 0000354F 5B                  <1> 	pop	ebx
 11866 00003550 EBF2                <1> 	jmp	short swpout_err_retn
 11867                              <1> swpout_im_err:
 11868 00003552 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
 11869 00003557 EBEB                <1> 	jmp	short swpout_err_retn
 11870                              <1> 
 11871                              <1> swap_queue_shift:
 11872                              <1> 	; 20/07/2015
 11873                              <1> 	; 28/04/2015
 11874                              <1> 	; 18/04/2015
 11875                              <1> 	; 23/10/2014 (Retro UNIX 386 v1 - beginning)
 11876                              <1> 	;
 11877                              <1> 	; INPUT ->
 11878                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
 11879                              <1> 	;	      and process number combination (bit 0 to 11)
 11880                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
 11881                              <1> 	; OUTPUT ->
 11882                              <1> 	;	If EBX input > 0 
 11883                              <1> 	;	    the queue will be shifted 4 bytes (dword),
 11884                              <1> 	; 	    from the tail to the head, up to entry offset
 11885                              <1> 	; 	    which points to EBX input value or nothing
 11886                              <1> 	;	    to do if EBX value is not found in the queue.
 11887                              <1> 	;	    (The entry -with EBX value- will be removed
 11888                              <1> 	;	     from the queue if it is found.)	
 11889                              <1> 	;	If EBX input = 0
 11890                              <1> 	;	    the queue will be shifted 4 bytes (dword),
 11891                              <1> 	; 	    from the tail to the head, if the PTE address
 11892                              <1> 	;	    in head of the queue is marked as "accessed"
 11893                              <1> 	;	    or it is marked as "non present".
 11894                              <1> 	;	    (If "accessed" flag of the PTE -in the head-
 11895                              <1> 	; 	    is set -to 1-, it will be reset -to 0- and then, 
 11896                              <1> 	;	    the queue will be rotated -without dropping
 11897                              <1> 	; 	    the PTE from the queue-, for 4 bytes on head
 11898                              <1> 	; 	    to tail direction. The PTE in the head will be
 11899                              <1> 	;	    moved in the tail, other PTEs will be shifted on
 11900                              <1> 	;	    head direction.)	
 11901                              <1> 	;
 11902                              <1> 	;	EAX = [swpq_count] (before the shifting)
 11903                              <1> 	;	    (EAX = 0 -> next 'swap_out' stage 
 11904                              <1> 	; 	     is not applicable)	
 11905                              <1> 	;
 11906                              <1> 	; Modified Registers -> EAX
 11907                              <1> 	;
 11908 00003559 0FB705[38810000]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
 11909 00003560 6621C0              <1> 	and	ax, ax
 11910 00003563 7433                <1> 	jz	short swpqs_retn
 11911 00003565 57                  <1> 	push	edi
 11912 00003566 56                  <1> 	push	esi
 11913 00003567 53                  <1> 	push	ebx
 11914 00003568 51                  <1> 	push	ecx
 11915 00003569 50                  <1> 	push	eax
 11916 0000356A BE00E00800          <1> 	mov	esi, swap_queue
 11917 0000356F 89C1                <1> 	mov	ecx, eax
 11918 00003571 09DB                <1> 	or	ebx, ebx
 11919 00003573 7424                <1> 	jz	short swpqs_7
 11920                              <1> swpqs_1:
 11921 00003575 AD                  <1> 	lodsd
 11922 00003576 39D8                <1> 	cmp	eax, ebx
 11923 00003578 7404                <1> 	je	short swpqs_2
 11924 0000357A E2F9                <1> 	loop	swpqs_1
 11925 0000357C EB15                <1> 	jmp	short swpqs_6
 11926                              <1> swpqs_2:
 11927 0000357E 89F7                <1> 	mov	edi, esi
 11928 00003580 83EF04              <1> 	sub 	edi, 4
 11929                              <1> swpqs_3:
 11930 00003583 66FF0D[38810000]    <1> 	dec	word [swpq_count]
 11931 0000358A 7403                <1> 	jz	short swpqs_5
 11932                              <1> swpqs_4:
 11933 0000358C 49                  <1> 	dec 	ecx
 11934 0000358D F3A5                <1> 	rep	movsd	; shift up (to the head)
 11935                              <1> swpqs_5:
 11936 0000358F 31C0                <1> 	xor	eax, eax
 11937 00003591 8907                <1> 	mov	[edi], eax
 11938                              <1> swpqs_6:
 11939 00003593 58                  <1> 	pop	eax
 11940 00003594 59                  <1> 	pop	ecx
 11941 00003595 5B                  <1> 	pop	ebx
 11942 00003596 5E                  <1> 	pop	esi
 11943 00003597 5F                  <1> 	pop	edi
 11944                              <1> swpqs_retn:
 11945 00003598 C3                  <1> 	retn		
 11946                              <1> swpqs_7:
 11947 00003599 89F7                <1> 	mov	edi, esi ; head
 11948 0000359B AD                  <1> 	lodsd
 11949                              <1> 	; 20/07/2015
 11950 0000359C 89C3                <1> 	mov	ebx, eax
 11951 0000359E 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
 11952                              <1> 		      ; ebx = virtual address (at page boundary)	
 11953 000035A4 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
 11954                              <1> 		      ; ax = process number (1 to 4095)
 11955 000035A9 3A05[CF740000]      <1> 	cmp	al, [u.uno]
 11956                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
 11957 000035AF 7507                <1> 	jne	short swpqs_8
 11958 000035B1 A1[D9740000]        <1> 	mov	eax, [u.pgdir]
 11959 000035B6 EB16                <1> 	jmp	short swpqs_9
 11960                              <1> swpqs_8:
 11961                              <1> 	;shl	ax, 2
 11962 000035B8 C0E002              <1> 	shl	al, 2
 11963 000035BB 8B80[12720000]      <1> 	mov 	eax, [eax+p.upage-4]
 11964 000035C1 09C0                <1> 	or	eax, eax
 11965 000035C3 74BE                <1> 	jz	short swpqs_3 ; invalid upage
 11966 000035C5 83C061              <1> 	add	eax, u.pgdir - user
 11967                              <1> 			 ; u.pgdir value for the process
 11968                              <1> 			 ; is in [eax]
 11969 000035C8 8B00                <1> 	mov	eax, [eax]
 11970 000035CA 21C0                <1> 	and	eax, eax
 11971 000035CC 74B5                <1> 	jz	short swpqs_3 ; invalid page directory
 11972                              <1> swpqs_9:
 11973 000035CE 52                  <1> 	push	edx
 11974                              <1> 	; eax = page directory
 11975                              <1> 	; ebx = virtual address
 11976 000035CF E87EFBFFFF          <1> 	call	get_pte
 11977 000035D4 89D3                <1> 	mov	ebx, edx ; PTE address
 11978 000035D6 5A                  <1> 	pop	edx
 11979 000035D7 72AA                <1> 	jc	short swpqs_3 ; empty PDE
 11980                              <1> 	; EAX = PTE value
 11981 000035D9 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
 11982 000035DB 74A6                <1> 	jz	short swpqs_3 ; Drop non-present page
 11983                              <1> 			      ; from the queue (head)
 11984 000035DD A802                <1> 	test	al, PTE_A_WRITE	  ; bit 1 = 0
 11985 000035DF 74A2                <1> 	jz	short swpqs_3 ; Drop read only page
 11986                              <1> 			      ; from the queue (head) 	
 11987                              <1> 	;test	al, PTE_A_ACCESS  ; bit 5 = 1 (Accessed)
 11988                              <1> 	;jz	short swpqs_6 ; present
 11989                              <1> 			      ; non-accessed page
 11990 000035E1 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
 11991 000035E5 73AC                <1> 	jnc	short swpqs_6  ; non-accessed page
 11992 000035E7 8903                <1> 	mov	[ebx], eax     ; save changed attribute
 11993                              <1> 	;
 11994                              <1> 	; Rotation (head -> tail)
 11995 000035E9 49                  <1> 	dec	ecx     ; entry count -> last entry number		
 11996 000035EA 74A7                <1> 	jz	short swpqs_6
 11997                              <1> 		; esi = head + 4
 11998                              <1> 		; edi = head
 11999 000035EC 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
 12000 000035EE F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 12001 000035F0 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1] 		
 12002 000035F2 EB9F                <1> 	jmp	short swpqs_6
 12003                              <1> 
 12004                              <1> add_to_swap_queue:
 12005                              <1> ; temporary - 16/09/2015
 12006 000035F4 C3                  <1> retn
 12007                              <1> 	; 20/07/2015
 12008                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12009                              <1> 	;
 12010                              <1> 	; Adds new page to swap queue
 12011                              <1> 	; (page directories and page tables must not be added
 12012                              <1> 	; to swap queue)	
 12013                              <1> 	;
 12014                              <1> 	; INPUT ->
 12015                              <1> 	;	EBX = Virtual address (for current process, [u.uno])
 12016                              <1> 	;
 12017                              <1> 	; OUTPUT ->
 12018                              <1> 	;	EAX = [swpq_count]
 12019                              <1> 	;	      (after the PTE has been added)
 12020                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
 12021                              <1> 	;	      the pte could not be added.
 12022                              <1> 	;
 12023                              <1> 	; Modified Registers -> EAX
 12024                              <1> 	;
 12025 000035F5 53                  <1> 	push	ebx
 12026 000035F6 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 12027 000035FB 8A1D[CF740000]      <1> 	mov	bl, [u.uno] ; current process number
 12028 00003601 E853FFFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
 12029                              <1> 				 ; it is already in the queue
 12030                              <1> 		; Then add it to the tail of the queue
 12031 00003606 0FB705[38810000]    <1> 	movzx	eax, word [swpq_count]
 12032 0000360D 663D0004            <1> 	cmp	ax, 1024
 12033 00003611 7205                <1> 	jb	short atsq_1
 12034 00003613 6629C0              <1> 	sub	ax, ax
 12035 00003616 5B                  <1> 	pop	ebx
 12036 00003617 C3                  <1> 	retn
 12037                              <1> atsq_1:
 12038 00003618 56                  <1> 	push	esi
 12039 00003619 BE00E00800          <1> 	mov	esi, swap_queue
 12040 0000361E 6621C0              <1> 	and	ax, ax
 12041 00003621 740A                <1> 	jz	short atsq_2
 12042 00003623 66C1E002            <1> 	shl	ax, 2	; convert to offset
 12043 00003627 01C6                <1> 	add	esi, eax
 12044 00003629 66C1E802            <1> 	shr	ax, 2
 12045                              <1> atsq_2:
 12046 0000362D 6640                <1> 	inc	ax
 12047 0000362F 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
 12048 00003631 66A3[38810000]      <1> 	mov	[swpq_count], ax
 12049 00003637 5E                  <1> 	pop	esi
 12050 00003638 5B                  <1> 	pop	ebx
 12051 00003639 C3                  <1> 	retn
 12052                              <1> 
 12053                              <1> unlink_swap_block:
 12054                              <1> 	; 15/09/2015
 12055                              <1> 	; 30/04/2015
 12056                              <1> 	; 18/04/2015
 12057                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12058                              <1> 	;
 12059                              <1> 	; INPUT -> 
 12060                              <1> 	;	EAX = swap disk/file offset address
 12061                              <1> 	;	      (bit 1 to bit 31)
 12062                              <1> 	; OUTPUT ->
 12063                              <1> 	;	[swpd_free] is increased
 12064                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
 12065                              <1> 	;
 12066                              <1> 	; Modified Registers -> EAX
 12067                              <1> 	;
 12068 0000363A 53                  <1> 	push	ebx
 12069 0000363B 52                  <1> 	push	edx
 12070                              <1> 	;
 12071 0000363C C1E804              <1> 	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
 12072                              <1> 				     ; 3 bits right
 12073                              <1> 				     ; to get swap block/page number
 12074 0000363F 89C2                <1> 	mov	edx, eax
 12075                              <1> 	; 15/09/2015
 12076 00003641 C1EA03              <1> 	shr	edx, 3		     ; to get offset to S.A.T.
 12077                              <1> 				     ; (1 allocation bit = 1 page)
 12078                              <1> 				     ; (1 allocation bytes = 8 pages)
 12079 00003644 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 12080                              <1> 				     ; (to get 32 bit position)			
 12081                              <1> 	;
 12082 00003647 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
 12083 0000364C 01D3                <1> 	add	ebx, edx
 12084 0000364E 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 12085                              <1> 				     ; (allocation bit position)	 
 12086 00003651 3B05[46810000]      <1> 	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
 12087                              <1> 				     ; than the address in 'swpd_next' ?
 12088                              <1> 				     ; (next/first free block value)		
 12089 00003657 7305                <1> 	jnb	short uswpbl_1	     ; no	
 12090 00003659 A3[46810000]        <1> 	mov	[swpd_next], eax     ; yes	
 12091                              <1> uswpbl_1:
 12092 0000365E 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate block
 12093                              <1> 				     ; set relevant bit to 1.
 12094                              <1> 				     ; set CF to the previous bit value	
 12095 00003661 F5                  <1> 	cmc			     ; complement carry flag	
 12096 00003662 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
 12097                              <1> 				     ; if the block is already deallocated
 12098                              <1> 				     ; before.	
 12099 00003664 FF05[42810000]      <1>         inc     dword [swpd_free]
 12100                              <1> uswpbl_2:
 12101 0000366A 5A                  <1> 	pop	edx
 12102 0000366B 5B                  <1> 	pop	ebx
 12103 0000366C C3                  <1> 	retn
 12104                              <1> 
 12105                              <1> link_swap_block:
 12106                              <1> 	; 01/07/2015
 12107                              <1> 	; 18/04/2015
 12108                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12109                              <1> 	;
 12110                              <1> 	; INPUT -> none
 12111                              <1> 	;
 12112                              <1> 	; OUTPUT ->
 12113                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
 12114                              <1> 	;	      in sectors (corresponding 
 12115                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
 12116                              <1> 	;
 12117                              <1> 	;	CF = 1 and EAX = 0 
 12118                              <1> 	; 		   if there is not a free block to be allocated	
 12119                              <1> 	;
 12120                              <1> 	; Modified Registers -> none (except EAX)
 12121                              <1> 	;
 12122                              <1> 
 12123                              <1> 	;mov	eax, [swpd_free]
 12124                              <1> 	;and	eax, eax
 12125                              <1> 	;jz	short out_of_swpspc
 12126                              <1> 	;
 12127 0000366D 53                  <1> 	push	ebx
 12128 0000366E 51                  <1> 	push	ecx
 12129                              <1> 	;
 12130 0000366F BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
 12131 00003674 89D9                <1> 	mov	ecx, ebx
 12132 00003676 031D[46810000]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
 12133                              <1> 				 ; next_free_swap_block >> 5
 12134 0000367C 030D[4A810000]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
 12135                              <1> 				 ; (total_swap_blocks - 1) >> 5
 12136                              <1> lswbl_scan:
 12137 00003682 39CB                <1> 	cmp	ebx, ecx
 12138 00003684 770A                <1> 	ja	short lswbl_notfound
 12139                              <1> 	;
 12140 00003686 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 12141                              <1> 			   ; Clears ZF if a bit is found set (1) and 
 12142                              <1> 			   ; loads the destination with an index to
 12143                              <1> 			   ; first set bit. (0 -> 31) 
 12144                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 12145                              <1> 	; 01/07/2015
 12146 00003689 751C                <1> 	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
 12147                              <1> 			 ;
 12148                              <1> 			 ; NOTE:  a Swap Disk Allocation Table bit 
 12149                              <1> 			 ;	  with value of 1 means 
 12150                              <1> 			 ;	  the corresponding page is free 
 12151                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
 12152 0000368B 83C304              <1> 	add	ebx, 4
 12153                              <1> 			 ; We return back for searching next page block
 12154                              <1> 			 ; NOTE: [swpd_free] is not ZERO; so, 
 12155                              <1> 			 ;	 we always will find at least 1 free block here.
 12156 0000368E EBF2                <1> 	jmp    	short lswbl_scan
 12157                              <1> 	;
 12158                              <1> lswbl_notfound:	
 12159 00003690 81E900000D00        <1> 	sub	ecx, swap_alloc_table
 12160 00003696 890D[46810000]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
 12161                              <1> 				 ; (unlink_swap_block procedure will change it)
 12162 0000369C 31C0                <1> 	xor	eax, eax
 12163 0000369E A3[42810000]        <1> 	mov	[swpd_free], eax
 12164 000036A3 F9                  <1> 	stc
 12165                              <1> lswbl_ok:
 12166 000036A4 59                  <1> 	pop	ecx
 12167 000036A5 5B                  <1> 	pop	ebx
 12168 000036A6 C3                  <1> 	retn
 12169                              <1> 	;
 12170                              <1> ;out_of_swpspc:
 12171                              <1> ;	stc
 12172                              <1> ;	retn
 12173                              <1> 
 12174                              <1> lswbl_found:
 12175 000036A7 89D9                <1> 	mov	ecx, ebx
 12176 000036A9 81E900000D00        <1> 	sub	ecx, swap_alloc_table
 12177 000036AF 890D[46810000]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
 12178                              <1> 				 ; address/offset (to the next)
 12179 000036B5 FF0D[42810000]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
 12180                              <1> 	;
 12181 000036BB 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 12182                              <1> 				 ; is copied into the Carry Flag and then cleared
 12183                              <1> 				 ; in the destination.
 12184                              <1> 				 ;
 12185                              <1> 				 ; Reset the bit which is corresponding to the 
 12186                              <1> 				 ; (just) allocated block.
 12187 000036BE C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
 12188 000036C1 01C8                <1> 	add	eax, ecx	 ; = block number
 12189 000036C3 C1E003              <1> 	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
 12190                              <1> 				 ; 1 block =  8 sectors
 12191                              <1> 	;
 12192                              <1> 	; EAX = offset address of swap disk/file sector (beginning of the block)
 12193                              <1> 	;
 12194                              <1> 	; NOTE: The relevant page table entry will be updated
 12195                              <1> 	;       according to this EAX value...
 12196                              <1> 	;
 12197 000036C6 EBDC                <1> 	jmp	short lswbl_ok
 12198                              <1> 
 12199                              <1> logical_disk_read:
 12200                              <1> 	; 20/07/2015
 12201                              <1> 	; 09/03/2015 (temporary code here)
 12202                              <1> 	;
 12203                              <1> 	; INPUT ->
 12204                              <1> 	; 	ESI = Logical disk description table address
 12205                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12206                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12207                              <1> 	; 	ECX = Sector count
 12208                              <1> 	;
 12209                              <1> 	;
 12210 000036C8 C3                  <1> 	retn
 12211                              <1> 
 12212                              <1> logical_disk_write:
 12213                              <1> 	; 20/07/2015
 12214                              <1> 	; 09/03/2015 (temporary code here)
 12215                              <1> 	;
 12216                              <1> 	; INPUT ->
 12217                              <1> 	; 	ESI = Logical disk description table address
 12218                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12219                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12220                              <1> 	; 	ECX = Sector count
 12221                              <1> 	;
 12222 000036C9 C3                  <1> 	retn
 12223                              <1> 
 12224                              <1> get_physical_addr:
 12225                              <1> 	; 18/10/2015
 12226                              <1> 	; 29/07/2015
 12227                              <1> 	; 20/07/2015
 12228                              <1> 	; 04/06/2015
 12229                              <1> 	; 20/05/2015
 12230                              <1> 	; 28/04/2015
 12231                              <1> 	; 18/04/2015
 12232                              <1> 	; Get physical address
 12233                              <1> 	;     (allocates a new page for user if it is not present)
 12234                              <1> 	;	
 12235                              <1> 	; (This subroutine is needed for mapping user's virtual 
 12236                              <1> 	; (buffer) address to physical address (of the buffer).)
 12237                              <1> 	; ('sys write', 'sys read' system calls...)
 12238                              <1> 	;
 12239                              <1> 	; INPUT ->
 12240                              <1> 	;	EBX = virtual address
 12241                              <1> 	;	u.pgdir = page directory (physical) address
 12242                              <1> 	;
 12243                              <1> 	; OUTPUT ->
 12244                              <1> 	;	EAX = physical address 
 12245                              <1> 	;	EBX = linear address	
 12246                              <1> 	;	EDX = physical address of the page frame
 12247                              <1> 	;	      (with attribute bits)
 12248                              <1> 	;	ECX = byte count within the page frame
 12249                              <1> 	;
 12250                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
 12251                              <1> 	;
 12252 000036CA 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
 12253                              <1> 	;
 12254 000036D0 A1[D9740000]        <1> 	mov	eax, [u.pgdir]
 12255 000036D5 E878FAFFFF          <1> 	call	get_pte
 12256                              <1> 		; EDX = Page table entry address (if CF=0)
 12257                              <1> 	        ;       Page directory entry address (if CF=1)
 12258                              <1> 		;       (Bit 0 value is 0 if PT is not present)
 12259                              <1> 		; EAX = Page table entry value (page address)
 12260                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
 12261 000036DA 731C                <1> 	jnc	short gpa_1
 12262                              <1> 	;
 12263 000036DC E856F9FFFF          <1> 	call	allocate_page
 12264 000036E1 725B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
 12265                              <1> gpa_0:
 12266 000036E3 E8C9F9FFFF          <1> 	call 	clear_page
 12267                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 12268 000036E8 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
 12269                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
 12270                              <1> 			   ; (user, writable, present page)	
 12271 000036EA 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
 12272 000036EC A1[D9740000]        <1> 	mov	eax, [u.pgdir]	
 12273 000036F1 E85CFAFFFF          <1> 	call	get_pte
 12274 000036F6 7246                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12275                              <1> gpa_1:
 12276                              <1> 	; EAX = PTE value, EDX = PTE address
 12277 000036F8 A801                <1> 	test 	al, PTE_A_PRESENT
 12278 000036FA 751A                <1> 	jnz	short gpa_3
 12279 000036FC 09C0                <1> 	or	eax, eax
 12280 000036FE 7430                <1> 	jz	short gpa_4  ; Allocate a new page
 12281                              <1> 	; 20/07/2015
 12282 00003700 55                  <1> 	push	ebp
 12283 00003701 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
 12284                              <1> 	; reload swapped page
 12285 00003703 E83C000000          <1> 	call	reload_page ; 28/04/2015
 12286 00003708 5D                  <1> 	pop	ebp
 12287 00003709 7224                <1> 	jc	short gpa_retn
 12288                              <1> gpa_2:
 12289                              <1> 	; 20/07/2015
 12290                              <1> 	; 20/05/2015
 12291                              <1> 	; add this page to swap queue
 12292 0000370B 50                  <1> 	push	eax 
 12293                              <1> 	; EBX = virtual address
 12294 0000370C E8E3FEFFFF          <1> 	call 	add_to_swap_queue
 12295 00003711 58                  <1> 	pop	eax
 12296                              <1> 		; PTE address in EDX
 12297                              <1> 		; virtual address in EBX
 12298                              <1> 	; EAX = memory page address
 12299 00003712 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
 12300                              <1> 				  ; present flag, bit 0 = 1
 12301                              <1> 				  ; user flag, bit 2 = 1	
 12302                              <1> 				  ; writable flag, bit 1 = 1
 12303 00003714 8902                <1> 	mov	[edx], eax  ; Update PTE value
 12304                              <1> gpa_3:
 12305                              <1> 	; 18/10/2015
 12306 00003716 89D9                <1> 	mov	ecx, ebx
 12307 00003718 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
 12308 0000371E 89C2                <1> 	mov 	edx, eax
 12309 00003720 662500F0            <1> 	and	ax, PTE_A_CLEAR
 12310 00003724 01C8                <1> 	add	eax, ecx
 12311 00003726 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
 12312 00003728 81C100100000        <1> 	add	ecx, PAGE_SIZE
 12313 0000372E F8                  <1> 	clc
 12314                              <1> gpa_retn:
 12315 0000372F C3                  <1> 	retn	
 12316                              <1> gpa_4:	
 12317 00003730 E802F9FFFF          <1> 	call	allocate_page
 12318 00003735 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12319 00003737 E875F9FFFF          <1> 	call	clear_page
 12320 0000373C EBCD                <1> 	jmp	short gpa_2
 12321                              <1> 
 12322                              <1> gpa_im_err:	
 12323 0000373E B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12324                              <1> 				  ; Major error = 0 (No protection fault)	
 12325 00003743 C3                  <1> 	retn
 12326                              <1> 
 12327                              <1> reload_page:
 12328                              <1> 	; 20/07/2015
 12329                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
 12330                              <1> 	;
 12331                              <1> 	; Reload (Restore) swapped page at memory
 12332                              <1> 	;
 12333                              <1> 	; INPUT -> 
 12334                              <1> 	;	EBP = Virtual (linear) memory address
 12335                              <1> 	;	EAX = PTE value (swap disk sector address)
 12336                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
 12337                              <1> 	; OUTPUT ->
 12338                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
 12339                              <1> 	;
 12340                              <1> 	;	CF = 1 and EAX = error code
 12341                              <1> 	;
 12342                              <1> 	; Modified Registers -> none (except EAX)
 12343                              <1> 	;
 12344 00003744 D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
 12345 00003746 53                  <1> 	push	ebx      ;
 12346 00003747 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
 12347 00003749 E8E9F8FFFF          <1> 	call	allocate_page
 12348 0000374E 720C                <1> 	jc	short rlp_im_err
 12349 00003750 93                  <1> 	xchg 	eax, ebx	
 12350                              <1> 	; EBX = Physical memory (page) address
 12351                              <1> 	; EAX = Swap disk (offset) address
 12352                              <1> 	; EBP = Virtual (linear) memory address
 12353 00003751 E81AFDFFFF          <1> 	call	swap_in
 12354 00003756 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
 12355 00003758 89D8                <1> 	mov	eax, ebx	
 12356                              <1> rlp_retn:
 12357 0000375A 5B                  <1> 	pop	ebx
 12358 0000375B C3                  <1> 	retn
 12359                              <1> 	
 12360                              <1> rlp_im_err:	
 12361 0000375C B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12362                              <1> 				  ; Major error = 0 (No protection fault)	
 12363 00003761 EBF7                <1> 	jmp	short rlp_retn
 12364                              <1> 
 12365                              <1> rlp_swp_err:
 12366 00003763 B804000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
 12367 00003768 EBF0                <1> 	jmp	short rlp_retn
 12368                              <1> 
 12369                              <1> 
 12370                              <1> copy_page_dir:
 12371                              <1> 	; 19/09/2015
 12372                              <1> 	; temporary - 07/09/2015
 12373                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12374                              <1> 	;
 12375                              <1> 	; INPUT -> 
 12376                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 12377                              <1> 	;		    page directory.
 12378                              <1> 	; OUTPUT ->
 12379                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 12380                              <1> 	;	       page directory.
 12381                              <1> 	;	(New page directory with new page table entries.)
 12382                              <1> 	;	(New page tables with read only copies of the parent's
 12383                              <1> 	;	pages.)
 12384                              <1> 	;	EAX = 0 -> Error (CF = 1)
 12385                              <1> 	;
 12386                              <1> 	; Modified Registers -> none (except EAX)
 12387                              <1> 	;
 12388 0000376A E8C8F8FFFF          <1> 	call	allocate_page
 12389 0000376F 723E                <1> 	jc	short cpd_err
 12390                              <1> 	;
 12391 00003771 55                  <1> 	push	ebp ; 20/07/2015
 12392 00003772 56                  <1> 	push	esi
 12393 00003773 57                  <1> 	push	edi
 12394 00003774 53                  <1> 	push	ebx
 12395 00003775 51                  <1> 	push	ecx
 12396 00003776 8B35[D9740000]      <1> 	mov	esi, [u.pgdir]
 12397 0000377C 89C7                <1> 	mov	edi, eax
 12398 0000377E 50                  <1> 	push	eax ; save child's page directory address
 12399                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 12400                              <1> 	; (use same system space for all user page tables) 
 12401 0000377F A5                  <1> 	movsd
 12402 00003780 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 12403 00003785 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 12404                              <1> cpd_0:	
 12405 0000378A AD                  <1> 	lodsd
 12406                              <1> 	;or	eax, eax
 12407                              <1>         ;jnz     short cpd_1
 12408 0000378B A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 12409 0000378D 7508                <1> 	jnz	short cpd_1
 12410                              <1>  	; (virtual address at the end of the page table)	
 12411 0000378F 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 12412 00003795 EB0F                <1> 	jmp	short cpd_2
 12413                              <1> cpd_1:	
 12414 00003797 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 12415 0000379B 89C3                <1> 	mov	ebx, eax
 12416                              <1> 	; EBX = Parent's page table address
 12417 0000379D E81F000000          <1> 	call	copy_page_table
 12418 000037A2 720C                <1> 	jc	short cpd_p_err
 12419                              <1> 	; EAX = Child's page table address
 12420 000037A4 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 12421                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 12422                              <1> 			 ; (present, writable, user)
 12423                              <1> cpd_2:
 12424 000037A6 AB                  <1> 	stosd
 12425 000037A7 E2E1                <1> 	loop	cpd_0
 12426                              <1> 	;
 12427 000037A9 58                  <1> 	pop	eax  ; restore child's page directory address
 12428                              <1> cpd_3:
 12429 000037AA 59                  <1> 	pop	ecx
 12430 000037AB 5B                  <1> 	pop	ebx
 12431 000037AC 5F                  <1> 	pop	edi
 12432 000037AD 5E                  <1> 	pop	esi
 12433 000037AE 5D                  <1> 	pop	ebp
 12434                              <1> cpd_err:
 12435 000037AF C3                  <1> 	retn
 12436                              <1> cpd_p_err:
 12437                              <1> 	; release the allocated pages missing (recover free space)
 12438 000037B0 58                  <1> 	pop	eax  ; the new page directory address (physical)
 12439 000037B1 8B1D[D9740000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 12440 000037B7 E8B4F9FFFF          <1> 	call 	deallocate_page_dir
 12441 000037BC 29C0                <1> 	sub	eax, eax ; 0
 12442 000037BE F9                  <1> 	stc
 12443 000037BF EBE9                <1> 	jmp	short cpd_3	
 12444                              <1> 
 12445                              <1> copy_page_table:
 12446                              <1> 	; 19/09/2015
 12447                              <1> 	; temporary - 07/09/2015
 12448                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12449                              <1> 	;
 12450                              <1> 	; INPUT -> 
 12451                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 12452                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
 12453                              <1> 	; OUTPUT ->
 12454                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 12455                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 12456                              <1> 	;	CF = 1 -> error 
 12457                              <1> 	;
 12458                              <1> 	; Modified Registers -> EBP (except EAX)
 12459                              <1> 	;
 12460 000037C1 E871F8FFFF          <1> 	call	allocate_page
 12461 000037C6 725A                <1> 	jc	short cpt_err
 12462                              <1> 	;
 12463 000037C8 50                  <1> 	push	eax ; *
 12464                              <1> 	;push 	ebx
 12465 000037C9 56                  <1> 	push	esi
 12466 000037CA 57                  <1> 	push	edi
 12467 000037CB 52                  <1> 	push	edx
 12468 000037CC 51                  <1> 	push	ecx
 12469                              <1> 	;
 12470 000037CD 89DE                <1> 	mov	esi, ebx
 12471 000037CF 89C7                <1> 	mov	edi, eax
 12472 000037D1 89C2                <1> 	mov	edx, eax
 12473 000037D3 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 12474                              <1> cpt_0:
 12475 000037D9 AD                  <1> 	lodsd
 12476 000037DA A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 12477 000037DC 750B                <1> 	jnz	short cpt_1
 12478 000037DE 21C0                <1> 	and	eax, eax
 12479 000037E0 7430                <1> 	jz	short cpt_2
 12480                              <1> 	; ebp = virtual (linear) address of the memory page
 12481 000037E2 E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
 12482 000037E7 7234                <1> 	jc	short cpt_p_err
 12483                              <1> cpt_1:
 12484 000037E9 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 12485 000037ED 89C1                <1> 	mov	ecx, eax
 12486                              <1> 	; Allocate a new page for the child process
 12487 000037EF E843F8FFFF          <1> 	call	allocate_page
 12488 000037F4 7227                <1> 	jc	short cpt_p_err
 12489 000037F6 57                  <1> 	push	edi
 12490 000037F7 56                  <1> 	push	esi
 12491 000037F8 89CE                <1> 	mov	esi, ecx
 12492 000037FA 89C7                <1> 	mov	edi, eax
 12493 000037FC B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 12494 00003801 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 12495 00003803 5E                  <1> 	pop	esi
 12496 00003804 5F                  <1> 	pop	edi
 12497                              <1> 	; 
 12498 00003805 53                  <1> 	push	ebx
 12499 00003806 50                  <1> 	push	eax
 12500 00003807 89EB                <1> 	mov	ebx, ebp
 12501                              <1> 	; ebx = virtual address of the memory page
 12502 00003809 E8E6FDFFFF          <1> 	call	add_to_swap_queue
 12503 0000380E 58                  <1> 	pop	eax
 12504 0000380F 5B                  <1> 	pop	ebx
 12505                              <1> 	;
 12506                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 12507 00003810 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 12508                              <1> cpt_2:
 12509 00003812 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 12510                              <1> 	;
 12511 00003813 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 12512                              <1> 	;
 12513 00003819 39D7                <1> 	cmp	edi, edx
 12514 0000381B 72BC                <1> 	jb	short cpt_0
 12515                              <1> cpt_p_err:
 12516 0000381D 59                  <1> 	pop	ecx
 12517 0000381E 5A                  <1> 	pop	edx
 12518 0000381F 5F                  <1> 	pop	edi
 12519 00003820 5E                  <1> 	pop	esi
 12520                              <1> 	;pop	ebx
 12521 00003821 58                  <1> 	pop	eax ; *
 12522                              <1> cpt_err:
 12523 00003822 C3                  <1> 	retn
 12524                              <1> 
 12525                              <1> 
 12526                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
 12527                              <1> 
 12528                              <1> ;; Data:
 12529                              <1> 
 12530                              <1> ; 09/03/2015
 12531                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
 12532                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
 12533                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 12534                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 12535                              <1> ;swpd_next:  dd 0 ; next free page block
 12536                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
 12537                                  %include 'sysdefs.inc' ; 09/03/2015
 12538                              <1> ; Retro UNIX 386 v1 Kernel - SYSDEFS.INC
 12539                              <1> ; Last Modification: 14/11/2015
 12540                              <1> ;
 12541                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 12542                              <1> ; (Modified from 
 12543                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 12544                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 12545                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
 12546                              <1> ; ----------------------------------------------------------------------------
 12547                              <1> ;
 12548                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 12549                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 12550                              <1> ; <Bell Laboratories (17/3/1972)>
 12551                              <1> ; <Preliminary Release of UNIX Implementation Document>
 12552                              <1> ;
 12553                              <1> ; ****************************************************************************
 12554                              <1> 
 12555                              <1> nproc 	equ	16  ; number of processes
 12556                              <1> nfiles 	equ	50
 12557                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
 12558                              <1> nbuf	equ	4   ; 6 ;; 21/08/2015 - 'namei' buffer problem when nbuf > 4 	
 12559                              <1> 		; NOTE: If fd0 super block buffer addres is beyond of the 1st
 12560                              <1> 		; 32K, DMA r/w routine or someting else causes a jump to 
 12561                              <1> 		; kernel panic routine (in 'alloc' routine, in u5.s)
 12562                              <1> 		; because of invalid buffer content (r/w error). 
 12563                              <1> 		; When all buffers are set before the end of the 1st 32k,
 12564                              <1> 		; there is no problem!? (14/11/2015) 
 12565                              <1> 
 12566                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
 12567                              <1> ;core	equ 	0  	    ; 19/04/2013	
 12568                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
 12569                              <1> 	; (if total size of argument list and arguments is 128 bytes)
 12570                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
 12571                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
 12572                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
 12573                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
 12574                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
 12575                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
 12576                              <1> 	; '/core' dump file size = 32768 bytes
 12577                              <1>  
 12578                              <1> ; 08/03/2014 
 12579                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)		 	 
 12580                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
 12581                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
 12582                              <1> 
 12583                              <1> ; 30/08/2013
 12584                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
 12585                              <1> 
 12586                              <1> ; 05/02/2014
 12587                              <1> ; process status
 12588                              <1> ;SFREE 	equ 0
 12589                              <1> ;SRUN	equ 1
 12590                              <1> ;SWAIT	equ 2
 12591                              <1> ;SZOMB	equ 3
 12592                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
 12593                              <1> 
 12594                              <1> ; 09/03/2015
 12595                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
 12596                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
 12597                              <1> swap_alloc_table equ 0D0000h  ;  swap allocation table address ; temporary
 12598                              <1> 
 12599                              <1> ; 17/09/2015
 12600                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
 12601                              <1> 
 12602                              <1> ; 21/09/2015 (36) 
 12603                              <1> ; 01/07/2015 (35)
 12604                              <1> ; 14/07/2013 (0-34)
 12605                              <1> ; UNIX v1 system calls
 12606                              <1> _rele 	equ 0
 12607                              <1> _exit 	equ 1
 12608                              <1> _fork 	equ 2
 12609                              <1> _read 	equ 3
 12610                              <1> _write	equ 4
 12611                              <1> _open	equ 5
 12612                              <1> _close 	equ 6
 12613                              <1> _wait 	equ 7
 12614                              <1> _creat 	equ 8
 12615                              <1> _link 	equ 9
 12616                              <1> _unlink	equ 10
 12617                              <1> _exec	equ 11
 12618                              <1> _chdir	equ 12
 12619                              <1> _time 	equ 13
 12620                              <1> _mkdir 	equ 14
 12621                              <1> _chmod	equ 15
 12622                              <1> _chown	equ 16
 12623                              <1> _break	equ 17
 12624                              <1> _stat	equ 18
 12625                              <1> _seek	equ 19
 12626                              <1> _tell 	equ 20
 12627                              <1> _mount	equ 21
 12628                              <1> _umount	equ 22
 12629                              <1> _setuid	equ 23
 12630                              <1> _getuid	equ 24
 12631                              <1> _stime	equ 25
 12632                              <1> _quit	equ 26	
 12633                              <1> _intr	equ 27
 12634                              <1> _fstat	equ 28
 12635                              <1> _emt 	equ 29
 12636                              <1> _mdate 	equ 30
 12637                              <1> _stty 	equ 31
 12638                              <1> _gtty	equ 32
 12639                              <1> _ilgins	equ 33
 12640                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
 12641                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
 12642                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
 12643                              <1> 
 12644                              <1> %macro sys 1-4
 12645                              <1>     ; 13/04/2015
 12646                              <1>     ; Retro UNIX 386 v1 system call.		
 12647                              <1>     mov eax, %1
 12648                              <1>     %if %0 >= 2   
 12649                              <1>         mov ebx, %2
 12650                              <1>         %if %0 >= 3    
 12651                              <1>             mov ecx, %3
 12652                              <1>             %if %0 = 4
 12653                              <1>                mov edx, %4   
 12654                              <1>             %endif
 12655                              <1>         %endif
 12656                              <1>     %endif
 12657                              <1>     int 30h	   
 12658                              <1> %endmacro
 12659                              <1> 
 12660                              <1> ; 13/05/2015 - ERROR CODES
 12661                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
 12662                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
 12663                              <1> ; 14/05/2015
 12664                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
 12665                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
 12666                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
 12667                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
 12668                              <1> ; 16/05/2015		
 12669                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
 12670                              <1> ; 18/05/2015
 12671                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
 12672                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
 12673                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
 12674                              <1> ; 07/06/2015
 12675                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
 12676                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
 12677                              <1> ; 09/06/2015
 12678                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
 12679                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
 12680                              <1> ; 16/06/2015
 12681                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
 12682                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
 12683                              <1> ; 22/06/2015
 12684                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
 12685                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
 12686                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
 12687                              <1> ; 23/06/2015
 12688                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
 12689                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
 12690                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
 12691                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
 12692                              <1> ; 27/06/2015
 12693                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
 12694                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
 12695                              <1> ; 29/06/2015
 12696                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
 12697                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error	
 12698                              <1> 
 12699                              <1> ; 26/08/2015
 12700                              <1> ; 24/07/2015
 12701                              <1> ; 24/06/2015
 12702                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
 12703                              <1> ; 01/07/2015
 12704                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
 12705                              <1> ;	 					 		
 12706                                  %include 'u0.s'        ; 15/03/2015
 12707                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
 12708                              <1> ; Last Modification: 20/11/2015
 12709                              <1> ; ----------------------------------------------------------------------------
 12710                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 12711                              <1> ; (v0.1 - Beginning: 11/07/2012)
 12712                              <1> ;
 12713                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 12714                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 12715                              <1> ; <Bell Laboratories (17/3/1972)>
 12716                              <1> ; <Preliminary Release of UNIX Implementation Document>
 12717                              <1> ;
 12718                              <1> ; Retro UNIX 8086 v1 - U0.ASM (28/07/2014) //// UNIX v1 -> u0.s
 12719                              <1> ;
 12720                              <1> ; ****************************************************************************
 12721                              <1> 
 12722                              <1> sys_init:
 12723                              <1> 	; 18/10/2015
 12724                              <1> 	; 28/08/2015
 12725                              <1> 	; 24/08/2015
 12726                              <1> 	; 14/08/2015
 12727                              <1> 	; 24/07/2015 
 12728                              <1> 	; 02/07/2015
 12729                              <1> 	; 01/07/2015
 12730                              <1> 	; 23/06/2015
 12731                              <1> 	; 15/04/2015
 12732                              <1> 	; 13/04/2015
 12733                              <1> 	; 11/03/2015 (Retro UNIX 386 v1 - Beginning)
 12734                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 12735                              <1> 	;
 12736                              <1> 	;call	ldrv_init ; Logical drive description tables initialization
 12737                              <1> 	;
 12738                              <1> 	; 14/02/2014
 12739                              <1> 	; 14/07/2013
 12740 00003823 66B82900            <1> 	mov	ax, 41
 12741 00003827 66A3[70740000]      <1> 	mov	[rootdir], ax
 12742 0000382D 66A3[84740000]      <1> 	mov	[u.cdir], ax
 12743 00003833 2401                <1> 	and	al, 1 ; 15/04/2015
 12744 00003835 A2[CF740000]        <1> 	mov	[u.uno], al
 12745 0000383A 66A3[6E740000]      <1> 	mov	[mpid], ax
 12746 00003840 66A3[76710000]      <1> 	mov	[p.pid], ax
 12747 00003846 A2[06720000]        <1> 	mov	[p.stat], al ; SRUN, 05/02/2014
 12748                              <1> 	;
 12749 0000384B B004                <1> 	mov	al, time_count ; 30/08/2013
 12750 0000384D A2[C2740000]        <1> 	mov	[u.quant], al ; 14/07/2013
 12751                              <1> 	; 02/07/2015
 12752 00003852 A1[A8700000]        <1> 	mov	eax, [k_page_dir]
 12753                              <1> 	;sub	eax, eax
 12754 00003857 A3[D9740000]        <1> 	mov	[u.pgdir], eax ; reset
 12755                              <1> 	; 18/10/2015
 12756                              <1> 	;mov	[u.ppgdir], eax ; 0
 12757                              <1>         ;
 12758 0000385C E856030000          <1>  	call	epoch
 12759 00003861 A3[BC7E0000]        <1> 	mov	[s.time], eax ; 13/03/2015
 12760                              <1> 	; 17/07/2013
 12761 00003866 E8B0060000          <1> 	call 	bf_init ; buffer initialization 
 12762                              <1> 	; 23/06/2015
 12763 0000386B E8C7F7FFFF          <1> 	call	allocate_page
 12764                              <1> 	;;jc	error
 12765 00003870 0F829C000000        <1>         jc      panic   ; jc short panic (01/07/2015)
 12766 00003876 A3[D0740000]        <1> 	mov	[u.upage], eax ; user structure page	
 12767 0000387B A3[16720000]        <1> 	mov	[p.upage], eax
 12768                              <1> 	;
 12769 00003880 E82CF8FFFF          <1> 	call	clear_page
 12770                              <1> 	;
 12771                              <1> 	; 14/08/2015
 12772 00003885 FA                  <1> 	cli
 12773                              <1> 	; 14/03/2015
 12774                              <1> 	; 17/01/2014
 12775 00003886 E8DE010000          <1> 	call	sp_init ; serial port initialization
 12776                              <1> 	; 14/08/2015
 12777 0000388B FB                  <1> 	sti
 12778                              <1> 	;
 12779                              <1> 	; 30/06/2015
 12780                              <1> 	;mov	esi, kernel_init_ok_msg
 12781                              <1> 	;call 	print_msg
 12782                              <1> 	;
 12783 0000388C 30DB                <1> 	xor	bl, bl ; video page 0
 12784                              <1> vp_clr_nxt:  ; clear video pages (reset cursor positions)
 12785 0000388E E8052E0000          <1> 	call 	vp_clr  ; 17/07/2013
 12786 00003893 FEC3                <1> 	inc	bl
 12787 00003895 80FB08              <1> 	cmp	bl, 8
 12788 00003898 72F4                <1> 	jb	short vp_clr_nxt
 12789                              <1> 	;
 12790                              <1> 	; 24/07/2015
 12791                              <1> 	;push    KDATA
 12792                              <1>         ;push    esp
 12793                              <1> 	;mov	[tss.esp0], esp
 12794                              <1>         ;mov     word [tss.ss0], KDATA
 12795                              <1> 	;
 12796                              <1> 	; 24/08/2015
 12797                              <1> 	;; temporary (01/07/2015)
 12798 0000389A C605[C2740000]04    <1> 	mov	byte [u.quant], time_count ; 4 
 12799                              <1> 			       ; it is not needed here !
 12800                              <1> 	;;inc	byte [u.kcall] ; 'the caller is kernel' sign
 12801 000038A1 FE0D[77740000]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
 12802                              <1> 			      ; 0 = executing a system call
 12803                              <1> 	;;sys 	_msg, kernel_init_ok_msg, 255, 0
 12804                              <1> 	;
 12805                              <1> 	;;; 06/08/2015
 12806                              <1> 	;;;call	getch ; wait for a key stroke
 12807                              <1> 	;;mov 	ecx, 0FFFFFFFh	
 12808                              <1> ;;sys_init_msg_wait:
 12809                              <1> ;;	push 	ecx
 12810                              <1> ;;	mov	al, 1
 12811                              <1> ;;	mov 	ah, [ptty] ; active (current) video page
 12812                              <1> ;;	call	getc_n
 12813                              <1> ;;	pop	ecx
 12814                              <1> ;;	jnz	short sys_init_msg_ok
 12815                              <1> ;;	loop	sys_init_msg_wait
 12816                              <1> 	;
 12817                              <1> ;;sys_init_msg_ok:
 12818                              <1> 	; 28/08/2015 (initial settings for the 1st 'rswap')
 12819 000038A7 6A10                <1> 	push	KDATA ; ss
 12820 000038A9 54                  <1> 	push	esp
 12821 000038AA 9C                  <1> 	pushfd
 12822 000038AB 6A08                <1> 	push	KCODE ; cs
 12823 000038AD 68[E1380000]        <1> 	push	init_exec ; eip
 12824 000038B2 8925[78740000]      <1> 	mov	[u.sp], esp
 12825 000038B8 1E                  <1> 	push	ds
 12826 000038B9 06                  <1> 	push	es
 12827 000038BA 0FA0                <1> 	push	fs
 12828 000038BC 0FA8                <1> 	push	gs	
 12829 000038BE 60                  <1> 	pushad
 12830 000038BF 8925[7C740000]      <1> 	mov	[u.usp], esp
 12831 000038C5 E8561B0000          <1> 	call	wswap ; save current user (u) structure, user registers
 12832                              <1> 		      ; and interrupt return components (for IRET)
 12833 000038CA 61                  <1> 	popad
 12834 000038CB 6658                <1> 	pop	ax ; gs
 12835 000038CD 6658                <1> 	pop	ax ; fs
 12836 000038CF 6658                <1> 	pop	ax ; es
 12837 000038D1 6658                <1> 	pop	ax ; ds	
 12838 000038D3 58                  <1> 	pop	eax ; eip (init_exec)
 12839 000038D4 6658                <1> 	pop	ax ; cs (KCODE)
 12840 000038D6 58                  <1> 	pop	eax ; E-FLAGS
 12841 000038D7 58                  <1> 	pop	eax ; esp
 12842 000038D8 6658                <1> 	pop	ax ; ss (KDATA)
 12843                              <1> 	;
 12844 000038DA 31C0                <1> 	xor	eax, eax ; 0
 12845 000038DC A3[DD740000]        <1> 	mov	[u.ppgdir], eax ; reset (to zero) for '/etc/init'
 12846                              <1> 	;
 12847                              <1> 	; 02/07/2015
 12848                              <1> 	; [u.pgdir ] = [k_page_dir]
 12849                              <1> 	; [u.ppgdir] = 0 (page dir of the parent process)
 12850                              <1> 	;     (The caller is os kernel sign for 'sysexec')
 12851                              <1> init_exec:
 12852                              <1> 	; 13/03/2013
 12853                              <1> 	; 24/07/2013
 12854 000038E1 BB[08390000]        <1> 	mov	ebx, init_file
 12855 000038E6 B9[00390000]        <1> 	mov	ecx, init_argp
 12856                              <1> 	; EBX contains 'etc/init' asciiz file name address  
 12857                              <1> 	; ECX contains address of argument list pointer
 12858                              <1> 	;
 12859                              <1> 	;dec 	byte [sysflg] ; FFh = ready for system call
 12860                              <1> 			      ; 0 = executing a system call
 12861                              <1> 	sys	_exec  ; execute file
 12862                              <2> 
 12863                              <2> 
 12864 000038EB B80B000000          <2>  mov eax, %1
 12865                              <2>  %if %0 >= 2
 12866                              <2>  mov ebx, %2
 12867                              <2>  %if %0 >= 3
 12868                              <2>  mov ecx, %3
 12869                              <2>  %if %0 = 4
 12870                              <2>  mov edx, %4
 12871                              <2>  %endif
 12872                              <2>  %endif
 12873                              <2>  %endif
 12874 000038F0 CD30                <2>  int 30h
 12875 000038F2 731E                <1> 	jnc	short panic
 12876                              <1> 	;
 12877 000038F4 BE[586D0000]        <1> 	mov	esi, etc_init_err_msg
 12878 000038F9 E837000000          <1> 	call 	print_msg
 12879 000038FE EB1C                <1> 	jmp	short key_to_reboot
 12880                              <1> 
 12881                              <1> ;align 4
 12882                              <1> init_argp:
 12883 00003900 [08390000]00000000  <1> 	dd 	init_file, 0  ; 23/06/2015 (dw -> dd)
 12884                              <1> init_file:
 12885                              <1> 	; 24/08/2015
 12886 00003908 2F6574632F696E6974- <1> 	db 	'/etc/init', 0
 12887 00003911 00                  <1>
 12888                              <1> panic:
 12889                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 12890                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 12891 00003912 BE[3D6D0000]        <1> 	mov 	esi, panic_msg
 12892 00003917 E819000000          <1> 	call 	print_msg
 12893                              <1> key_to_reboot:
 12894                              <1> 	; 15/11/2015
 12895 0000391C E8B52B0000          <1> 	call 	getch 
 12896                              <1> 		; wait for a character from the current tty
 12897                              <1> 	;
 12898 00003921 B00A                <1> 	mov	al, 0Ah
 12899 00003923 8A1D[D6700000]      <1> 	mov	bl, [ptty] ; [active_page]
 12900 00003929 B407                <1> 	mov	ah, 07h ; Black background, 
 12901                              <1> 			; light gray forecolor
 12902 0000392B E8EDDBFFFF          <1> 	call 	write_tty
 12903 00003930 E96DD8FFFF          <1> 	jmp	cpu_reset 
 12904                              <1> 
 12905                              <1> print_msg:
 12906                              <1> 	; 01/07/2015
 12907                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 12908                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 12909                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
 12910                              <1> 	;
 12911                              <1> 	;
 12912 00003935 AC                  <1> 	lodsb
 12913                              <1> pmsg1:
 12914 00003936 56                  <1> 	push 	esi
 12915 00003937 0FB61D[D6700000]    <1> 	movzx	ebx, byte [ptty]
 12916 0000393E B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
 12917 00003940 E8D8DBFFFF          <1> 	call 	write_tty
 12918 00003945 5E                  <1> 	pop	esi
 12919 00003946 AC                  <1> 	lodsb
 12920 00003947 20C0                <1> 	and 	al, al
 12921 00003949 75EB                <1> 	jnz 	short pmsg1
 12922 0000394B C3                  <1> 	retn
 12923                              <1> 	
 12924                              <1> ctrlbrk:
 12925                              <1> 	; 12/11/2015
 12926                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 12927                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
 12928                              <1> 	;
 12929                              <1> 	; INT 1Bh (control+break) handler		
 12930                              <1> 	;
 12931                              <1>       	; Retro Unix 8086 v1 feature only!
 12932                              <1>       	;
 12933 0000394C 66833D[C4740000]00  <1> 	cmp 	word [u.intr], 0
 12934 00003954 7645                <1> 	jna 	short cbrk4
 12935                              <1> cbrk0:
 12936                              <1> 	; 12/11/2015
 12937                              <1> 	; 06/12/2013
 12938 00003956 66833D[C6740000]00  <1> 	cmp 	word [u.quit], 0
 12939 0000395E 743B                <1> 	jz	short cbrk4
 12940                              <1> 	;
 12941                              <1> 	; 20/09/2013	
 12942 00003960 6650                <1> 	push 	ax
 12943 00003962 A0[D6700000]        <1> 	mov	al, [ptty]
 12944                              <1> 	;
 12945                              <1> 	; 12/11/2015
 12946                              <1> 	;
 12947                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
 12948                              <1> 	; or ctrl+break from console (pseudo) tty
 12949                              <1> 	; (!redirection!)
 12950                              <1> 	;
 12951 00003967 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
 12952 00003969 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
 12953                              <1> 	;	
 12954                              <1> 	; Serial port interrupt handler sets [ptty]
 12955                              <1> 	; to the port's tty number (as temporary).
 12956                              <1> 	;
 12957                              <1> 	; If active process is using a stdin or 
 12958                              <1> 	; stdout redirection (by the shell),
 12959                              <1>         ; console tty keyboard must be available
 12960                              <1> 	; to terminate running process,
 12961                              <1> 	; in order to prevent a deadlock. 
 12962                              <1> 	;
 12963 0000396B 52                  <1> 	push	edx
 12964 0000396C 0FB615[CF740000]    <1> 	movzx	edx, byte [u.uno]
 12965 00003973 3A82[D5710000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
 12966 00003979 5A                  <1> 	pop	edx
 12967 0000397A 7412                <1> 	je	short cbrk2
 12968                              <1> cbrk1:
 12969 0000397C FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
 12970                              <1> 	; 06/12/2013
 12971 0000397E 3A05[B0740000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
 12972 00003984 7408                <1> 	je	short cbrk2	
 12973 00003986 3A05[B1740000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
 12974 0000398C 750B                <1> 	jne	short cbrk3	
 12975                              <1> cbrk2:
 12976                              <1> 	;; 06/12/2013
 12977                              <1> 	;mov	ax, [u.quit]
 12978                              <1> 	;and	ax, ax
 12979                              <1> 	;jz	short cbrk3
 12980                              <1> 	;
 12981 0000398E 6631C0              <1> 	xor	ax, ax ; 0
 12982 00003991 6648                <1> 	dec	ax
 12983                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
 12984 00003993 66A3[C6740000]      <1> 	mov	[u.quit], ax
 12985                              <1> cbrk3:
 12986 00003999 6658                <1> 	pop	ax
 12987                              <1> cbrk4:
 12988 0000399B C3                  <1> 	retn
 12989                              <1> 
 12990                              <1> com2_int:
 12991                              <1> 	; 07/11/2015 
 12992                              <1> 	; 24/10/2015
 12993                              <1> 	; 23/10/2015
 12994                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 12995                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 12996                              <1> 	; < serial port 2 interrupt handler >
 12997                              <1> 	;
 12998 0000399C 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 12999                              <1> 	;push	eax
 13000 0000399F 66B80900            <1> 	mov	ax, 9
 13001 000039A3 EB07                <1> 	jmp	short comm_int
 13002                              <1> com1_int:
 13003                              <1> 	; 07/11/2015
 13004                              <1> 	; 24/10/2015
 13005 000039A5 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13006                              <1> 	; 23/10/2015
 13007                              <1> 	;push	eax
 13008 000039A8 66B80800            <1> 	mov	ax, 8
 13009                              <1> comm_int:
 13010                              <1> 	; 20/11/2015
 13011                              <1> 	; 18/11/2015
 13012                              <1> 	; 17/11/2015
 13013                              <1> 	; 16/11/2015
 13014                              <1> 	; 09/11/2015
 13015                              <1> 	; 08/11/2015
 13016                              <1> 	; 07/11/2015
 13017                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
 13018                              <1> 	; 01/11/2015
 13019                              <1> 	; 26/10/2015
 13020                              <1> 	; 23/10/2015
 13021 000039AC 53                  <1> 	push	ebx
 13022 000039AD 56                  <1> 	push	esi
 13023 000039AE 57                  <1> 	push	edi
 13024 000039AF 1E                  <1> 	push 	ds
 13025 000039B0 06                  <1> 	push 	es
 13026                              <1> 	; 18/11/2015
 13027 000039B1 0F20DB              <1> 	mov	ebx, cr3
 13028 000039B4 53                  <1> 	push	ebx ; ****
 13029                              <1> 	;
 13030 000039B5 51                  <1> 	push	ecx ; ***
 13031 000039B6 52                  <1> 	push	edx ; **
 13032                              <1> 	;
 13033 000039B7 BB10000000          <1> 	mov	ebx, KDATA
 13034 000039BC 8EDB                <1> 	mov	ds, bx
 13035 000039BE 8EC3                <1> 	mov	es, bx
 13036                              <1> 	;
 13037 000039C0 8B0D[A8700000]      <1> 	mov	ecx, [k_page_dir]
 13038 000039C6 0F22D9              <1> 	mov	cr3, ecx
 13039                              <1> 	; 20/11/2015
 13040                              <1> 	; Interrupt identification register
 13041 000039C9 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
 13042                              <1> 	;
 13043 000039CD 3C08                <1> 	cmp 	al, 8 
 13044 000039CF 7702                <1> 	ja 	short com_i0
 13045                              <1> 	;
 13046                              <1> 	; 20/11/2015
 13047                              <1> 	; 17/11/2015
 13048                              <1> 	; 16/11/2015
 13049                              <1> 	; 15/11/2015
 13050                              <1> 	; 24/10/2015
 13051                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13052                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13053                              <1> 	; < serial port 1 interrupt handler >
 13054                              <1> 	;
 13055 000039D1 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
 13056                              <1> com_i0:
 13057                              <1> 	;push	eax ; *
 13058                              <1> 	; 07/11/2015
 13059 000039D3 A2[16710000]        <1> 	mov 	byte [ccomport], al
 13060                              <1> 	; 09/11/2015
 13061 000039D8 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
 13062                              <1> 	; 17/11/2015
 13063                              <1>  	; reset request for response status
 13064 000039DB 88A3[0C710000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
 13065                              <1> 	;
 13066                              <1> 	; 20/11/2015
 13067 000039E1 EC                  <1> 	in	al, dx		; read interrupt id. register
 13068 000039E2 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13069 000039E4 2404                <1> 	and	al, 4		; received data available?	
 13070 000039E6 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
 13071                              <1> 	;
 13072                              <1> 	; 20/11/2015
 13073 000039E8 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
 13074 000039EB EC                  <1> 	in	al, dx     	; read character
 13075                              <1> 	;JMP	$+2	   	; I/O DELAY
 13076                              <1> 	; 08/11/2015
 13077                              <1> 	; 07/11/2015
 13078 000039EC 89DE                <1> 	mov	esi, ebx 
 13079 000039EE 89DF                <1> 	mov	edi, ebx
 13080 000039F0 81C6[10710000]      <1> 	add 	esi, rchar - 8 ; points to last received char
 13081 000039F6 81C7[12710000]      <1> 	add	edi, schar - 8 ; points to last sent char
 13082 000039FC 8806                <1> 	mov	[esi], al ; received char (current char)
 13083                              <1> 	; query
 13084 000039FE 20C0                <1> 	and	al, al
 13085 00003A00 7527                <1> 	jnz	short com_i2
 13086                              <1>    	; response
 13087                              <1> 	; 17/11/2015
 13088                              <1> 	; set request for response status
 13089 00003A02 FE83[0C710000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
 13090                              <1> 	;
 13091 00003A08 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
 13092 00003A0C EC                  <1> 	in	al, dx	   	; read line status register 
 13093 00003A0D EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13094 00003A0F 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
 13095 00003A11 7445                <1> 	jz	short com_eoi 	; no
 13096 00003A13 B0FF                <1> 	mov 	al, 0FFh   	; response			
 13097 00003A15 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
 13098 00003A19 EE                  <1> 	out	dx, al	   	; send on serial port
 13099                              <1> 	; 17/11/2015
 13100 00003A1A 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
 13101 00003A1D 7502                <1> 	jne 	short com_i1    ; no
 13102 00003A1F 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
 13103                              <1> com_i1:
 13104                              <1> 	; 17/11/2015
 13105                              <1> 	; reset request for response status (again)
 13106 00003A21 FE8B[0C710000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
 13107 00003A27 EB2F                <1> 	jmp	short com_eoi
 13108                              <1> com_i2:	
 13109                              <1> 	; 08/11/2015
 13110 00003A29 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
 13111 00003A2B 7417                <1> 	je	short com_i3	; (check for response signal)
 13112                              <1> 	; 07/11/2015
 13113 00003A2D 3C04                <1> 	cmp	al, 04h	; EOT
 13114 00003A2F 751C                <1> 	jne	short com_i4	
 13115                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
 13116                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
 13117                              <1> 	; 08/11/2015
 13118                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
 13119 00003A31 861D[D6700000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
 13120 00003A37 E810FFFFFF          <1> 	call 	ctrlbrk
 13121 00003A3C 861D[D6700000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
 13122                              <1> 	;mov	al, 04h ; EOT
 13123                              <1> 	; 08/11/2015
 13124 00003A42 EB09                <1> 	jmp	short com_i4	
 13125                              <1> com_i3:
 13126                              <1> 	; 08/11/2015
 13127                              <1> 	; If 0FFh has been received just after a query
 13128                              <1> 	; (schar, ZERO), it is a response signal.
 13129                              <1> 	; 17/11/2015
 13130 00003A44 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
 13131 00003A47 7704                <1> 	ja	short com_i4 ; no
 13132                              <1> 	; reset query status (schar)
 13133 00003A49 8807                <1> 	mov	[edi], al ; 0FFh
 13134 00003A4B FEC0                <1> 	inc	al ; 0
 13135                              <1> com_i4:
 13136                              <1> 	; 27/07/2014
 13137                              <1> 	; 09/07/2014
 13138 00003A4D D0E3                <1> 	shl	bl, 1	
 13139 00003A4F 81C3[D8700000]      <1> 	add	ebx, ttychr
 13140                              <1> 	; 23/07/2014 (always overwrite)
 13141                              <1> 	;;cmp	word [ebx], 0
 13142                              <1> 	;;ja	short com_eoi
 13143                              <1> 	;
 13144 00003A55 668903              <1> 	mov	[ebx], ax   ; Save ascii code
 13145                              <1> 			    ; scan code = 0
 13146                              <1> com_eoi:
 13147                              <1> 	;mov	al, 20h
 13148                              <1> 	;out	20h, al	   ; end of interrupt
 13149                              <1> 	;
 13150                              <1> 	; 07/11/2015
 13151                              <1>       	;pop	eax ; *
 13152 00003A58 A0[16710000]        <1> 	mov	al, byte [ccomport] ; current COM port
 13153                              <1> 	 ; al = tty number (8 or 9)
 13154 00003A5D E8991A0000          <1>         call	wakeup
 13155                              <1> com_iret:
 13156                              <1> 	; 23/10/2015
 13157 00003A62 5A                  <1> 	pop	edx ; **
 13158 00003A63 59                  <1> 	pop	ecx ; ***
 13159                              <1> 	; 18/11/2015
 13160                              <1> 	;pop	eax ; ****
 13161                              <1> 	;mov	cr3, eax
 13162                              <1> 	;jmp	iiret
 13163 00003A64 E94BD0FFFF          <1> 	jmp	iiretp
 13164                              <1> 
 13165                              <1> ;iiretp: ; 01/09/2015
 13166                              <1> ;	; 28/08/2015
 13167                              <1> ;	pop	eax ; (*) page directory
 13168                              <1> ;	mov	cr3, eax
 13169                              <1> ;iiret:
 13170                              <1> ;	; 22/08/2014
 13171                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
 13172                              <1> ;	out	20h, al	; 8259 PORT
 13173                              <1> ;	;
 13174                              <1> ;	pop	es
 13175                              <1> ;	pop	ds
 13176                              <1> ;	pop	edi
 13177                              <1> ;	pop	esi
 13178                              <1> ;	pop	ebx ; 29/08/2014
 13179                              <1> ;	pop 	eax
 13180                              <1> ;	iretd
 13181                              <1> 
 13182                              <1> sp_init:
 13183                              <1> 	; 07/11/2015
 13184                              <1> 	; 29/10/2015
 13185                              <1> 	; 26/10/2015
 13186                              <1> 	; 23/10/2015
 13187                              <1> 	; 29/06/2015
 13188                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
 13189                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
 13190                              <1> 	; Initialization of Serial Port Communication Parameters
 13191                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13192                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13193                              <1> 	;
 13194                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13195                              <1> 	;
 13196                              <1> 	; INPUT:  (29/06/2015)
 13197                              <1> 	;	AL = 0 for COM1
 13198                              <1> 	;	     1 for COM2
 13199                              <1> 	;	AH = Communication parameters	
 13200                              <1> 	;
 13201                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13202                              <1> 	;	Bit	4	3	2	1	0
 13203                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13204                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13205                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13206                              <1> 	;		11 = even
 13207                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13208                              <1> 	;		Retro UNIX 386 v1 feature only !
 13209                              <1> 	;	Bit	7    6    5  | Baud rate
 13210                              <1> 	;		------------------------
 13211                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13212                              <1> 	;		0    0    1  | 9600 (12)
 13213                              <1> 	;		0    1    0  | 19200 (6) 
 13214                              <1> 	;		0    1	  1  | 38400 (3) 
 13215                              <1> 	;		1    0	  0  | 14400 (8)
 13216                              <1> 	;		1    0	  1  | 28800 (4)
 13217                              <1> 	;		1    1    0  | 57600 (2)
 13218                              <1> 	;		1    1    1  | 115200 (1) 	
 13219                              <1> 	
 13220                              <1> 	; References:	
 13221                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
 13222                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
 13223                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
 13224                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
 13225                              <1> 	;
 13226                              <1> 	; Set communication parameters for COM1 (= 03h)	
 13227                              <1> 	;
 13228 00003A69 BB[12710000]        <1> 	mov	ebx, com1p		; COM1 parameters  
 13229 00003A6E 66BAF803            <1> 	mov	dx, 3F8h		; COM1
 13230                              <1> 	 ; 29/10/2015
 13231 00003A72 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13232 00003A76 E86F000000          <1> 	call	sp_i3	; call A4	
 13233 00003A7B A880                <1> 	test	al, 80h
 13234 00003A7D 7410                <1> 	jz	short sp_i0 ; OK..
 13235                              <1> 		; Error !
 13236                              <1> 	;mov	dx, 3F8h
 13237 00003A7F 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
 13238 00003A82 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13239 00003A86 E85F000000          <1> 	call	sp_i3	; call A4	
 13240 00003A8B A880                <1> 	test	al, 80h
 13241 00003A8D 7508                <1> 	jnz	short sp_i1
 13242                              <1> sp_i0:
 13243                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
 13244                              <1>         ; (INT 14h initialization code disables interrupts.)
 13245                              <1> 	;
 13246 00003A8F C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13247 00003A92 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
 13248                              <1> sp_i1:
 13249 00003A97 43                  <1> 	inc	ebx
 13250 00003A98 66BAF802            <1> 	mov	dx, 2F8h		; COM2
 13251                              <1> 	 ; 29/10/2015
 13252 00003A9C 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13253 00003AA0 E845000000          <1> 	call	sp_i3	; call A4	
 13254 00003AA5 A880                <1> 	test	al, 80h
 13255 00003AA7 7410                <1> 	jz	short sp_i2 ; OK..
 13256                              <1> 		; Error !
 13257                              <1> 	;mov	dx, 2F8h
 13258 00003AA9 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
 13259 00003AAC 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13260 00003AB0 E835000000          <1> 	call	sp_i3	; call A4	
 13261 00003AB5 A880                <1> 	test	al, 80h
 13262 00003AB7 7530                <1> 	jnz	short sp_i7
 13263                              <1> sp_i2:
 13264 00003AB9 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13265                              <1> sp_i6:
 13266                              <1> 	;; COM2 - enabling IRQ 3
 13267                              <1> 	; 07/11/2015
 13268                              <1> 	; 26/10/2015
 13269 00003ABC 9C                  <1> 	pushf
 13270 00003ABD FA                  <1> 	cli
 13271                              <1> 	;
 13272 00003ABE 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
 13273 00003AC2 EC                  <1> 	in	al, dx 	   		; read register
 13274 00003AC3 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13275 00003AC5 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13276 00003AC7 EE                  <1> 	out	dx, al     		; write back to register
 13277 00003AC8 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13278 00003ACA 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
 13279 00003ACE EC                  <1> 	in	al, dx     		; read register
 13280 00003ACF EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13281                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13282 00003AD1 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13283 00003AD3 EE                  <1> 	out	dx, al 	   		; write back to register
 13284 00003AD4 EB00                <1> 	JMP	$+2        		; I/O DELAY
 13285 00003AD6 E421                <1> 	in	al, 21h    		; read interrupt mask register
 13286 00003AD8 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13287 00003ADA 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
 13288 00003ADC E621                <1> 	out	21h, al    		; write back to register
 13289                              <1> 	;
 13290                              <1> 	; 23/10/2015
 13291 00003ADE B8[9C390000]        <1> 	mov 	eax, com2_int
 13292 00003AE3 A3[7B3F0000]        <1> 	mov	[com2_irq3], eax
 13293                              <1> 	; 26/10/2015
 13294 00003AE8 9D                  <1> 	popf	
 13295                              <1> sp_i7:
 13296 00003AE9 C3                  <1> 	retn
 13297                              <1> 
 13298                              <1> sp_i3:
 13299                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
 13300                              <1> 	; 28/10/2015
 13301 00003AEA FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
 13302 00003AEC B000                <1> 	mov	al, 0
 13303 00003AEE EE                  <1> 	out	dx, al			; disable serial port interrupt
 13304 00003AEF EB00                <1> 	JMP	$+2			; I/O DELAY
 13305 00003AF1 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
 13306 00003AF4 B080                <1> 	mov	al, 80h			
 13307 00003AF6 EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
 13308                              <1> 	;-----	SET BAUD RATE DIVISOR
 13309                              <1> 	; 26/10/2015
 13310 00003AF7 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
 13311                              <1> 					; of the divisor value
 13312 00003AFA 88C8                <1> 	mov	al, cl	; 1
 13313 00003AFC EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
 13314                              <1> 					; 2 = 57600 baud
 13315                              <1> 					; 3 = 38400 baud
 13316                              <1> 					; 6 = 19200 baud
 13317                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
 13318 00003AFD EB00                <1> 	JMP	$+2			; I/O DELAY
 13319 00003AFF 28C0                <1> 	sub	al, al
 13320 00003B01 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
 13321                              <1> 					; of the divisor value
 13322 00003B03 EE                  <1> 	out	dx, al ; 0
 13323 00003B04 EB00                <1> 	JMP	$+2			; I/O DELAY
 13324                              <1> 	;	
 13325 00003B06 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
 13326                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
 13327 00003B08 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
 13328 00003B0B EE                  <1> 	out	dx, al			
 13329 00003B0C EB00                <1> 	JMP	$+2			; I/O DELAY
 13330                              <1> 	; 29/10/2015
 13331 00003B0E FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
 13332 00003B10 30C0                <1> 	xor	al, al			; 0
 13333 00003B12 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
 13334 00003B13 EB00                <1> 	JMP	$+2	
 13335                              <1> sp_i4:
 13336                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
 13337                              <1> 	; 29/06/2015 (line status after modem status)
 13338 00003B15 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
 13339                              <1> sp_i4s:
 13340 00003B18 EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
 13341 00003B19 EB00                <1> 	JMP	$+2			; I/O DELAY
 13342 00003B1B 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
 13343 00003B1D FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
 13344                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
 13345 00003B1F EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
 13346                              <1> 	; AL = Line status, AH = Modem status
 13347 00003B20 C3                  <1> 	retn
 13348                              <1> 
 13349                              <1> sp_status:
 13350                              <1> 	; 29/06/2015
 13351                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
 13352                              <1> 	; Get serial port status
 13353 00003B21 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
 13354 00003B25 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
 13355                              <1> 					; dx = 2FEh for COM2
 13356 00003B27 EBEF                <1> 	jmp	short sp_i4s
 13357                              <1> 
 13358                              <1> sp_setp: ; Set serial port communication parameters
 13359                              <1> 	; 07/11/2015
 13360                              <1> 	; 29/10/2015
 13361                              <1> 	; 29/06/2015
 13362                              <1> 	; Retro UNIX 386 v1 feature only !	
 13363                              <1> 	;
 13364                              <1> 	; INPUT:
 13365                              <1> 	;	AL = 0 for COM1
 13366                              <1> 	;	     1 for COM2
 13367                              <1> 	;	AH = Communication parameters (*)
 13368                              <1> 	; OUTPUT:
 13369                              <1> 	;	CL = Line status
 13370                              <1> 	;	CH = Modem status
 13371                              <1> 	;   If cf = 1 -> Error code in [u.error]
 13372                              <1> 	;		 'invalid parameter !' 
 13373                              <1> 	;		 	 or
 13374                              <1> 	;		 'device not ready !' error
 13375                              <1> 	;	
 13376                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13377                              <1> 	;	Bit	4	3	2	1	0
 13378                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13379                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13380                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13381                              <1> 	;		11 = even
 13382                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13383                              <1> 	;		Retro UNIX 386 v1 feature only !
 13384                              <1> 	;	Bit	7    6    5  | Baud rate
 13385                              <1> 	;		------------------------
 13386                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13387                              <1> 	;		0    0    1  | 9600 (12)
 13388                              <1> 	;		0    1    0  | 19200 (6) 
 13389                              <1> 	;		0    1	  1  | 38400 (3) 
 13390                              <1> 	;		1    0	  0  | 14400 (8)
 13391                              <1> 	;		1    0	  1  | 28800 (4)
 13392                              <1> 	;		1    1    0  | 57600 (2)
 13393                              <1> 	;		1    1    1  | 115200 (1) 
 13394                              <1> 	;
 13395                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13396                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13397                              <1> 	;
 13398                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13399                              <1> 	;
 13400 00003B29 66BAF803            <1> 	mov	dx, 3F8h
 13401 00003B2D BB[12710000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
 13402 00003B32 3C01                <1> 	cmp	al, 1
 13403 00003B34 776B                <1> 	ja 	short sp_invp_err
 13404 00003B36 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
 13405 00003B38 FECE                <1> 	dec	dh ; 2F8h
 13406 00003B3A 43                  <1> 	inc	ebx ; COM2 control byte offset
 13407                              <1> sp_setp1:
 13408                              <1> 	; 29/10/2015
 13409 00003B3B 8823                <1> 	mov	[ebx], ah
 13410 00003B3D 0FB6CC              <1> 	movzx 	ecx, ah
 13411 00003B40 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
 13412 00003B43 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
 13413 00003B46 8A81[B03B0000]      <1> 	mov	al, [ecx+b_div_tbl]
 13414 00003B4C 6689C1              <1> 	mov	cx, ax
 13415 00003B4F E896FFFFFF          <1> 	call	sp_i3
 13416 00003B54 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
 13417 00003B57 A880                <1> 	test	al, 80h
 13418 00003B59 740F                <1> 	jz	short sp_setp2
 13419 00003B5B C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
 13420                              <1> stp_dnr_err:
 13421 00003B5E C705[D5740000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
 13422 00003B66 0000                <1>
 13423                              <1> 	; CL = Line status, CH = Modem status
 13424 00003B68 F9                  <1> 	stc
 13425 00003B69 C3                  <1> 	retn
 13426                              <1> sp_setp2:
 13427 00003B6A 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
 13428 00003B6D 0F8649FFFFFF        <1>         jna     sp_i6 
 13429                              <1> 		      ; COM1 (3F?h)
 13430                              <1> sp_i5: 
 13431                              <1> 	; 07/11/2015
 13432                              <1> 	; 26/10/2015
 13433                              <1> 	; 29/06/2015
 13434                              <1> 	;
 13435                              <1> 	;; COM1 - enabling IRQ 4
 13436 00003B73 9C                  <1> 	pushf
 13437 00003B74 FA                  <1> 	cli
 13438 00003B75 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
 13439 00003B79 EC                  <1> 	in	al, dx 	   		; read register
 13440 00003B7A EB00                <1> 	JMP	$+2			; I/O DELAY
 13441 00003B7C 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13442 00003B7E EE                  <1> 	out	dx, al     		; write back to register
 13443 00003B7F EB00                <1> 	JMP	$+2			; I/O DELAY
 13444 00003B81 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
 13445 00003B85 EC                  <1> 	in	al, dx     		; read register
 13446 00003B86 EB00                <1> 	JMP	$+2			; I/O DELAY
 13447                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13448 00003B88 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13449 00003B8A EE                  <1> 	out	dx, al 	   		; write back to register
 13450 00003B8B EB00                <1> 	JMP	$+2        		; I/O DELAY
 13451 00003B8D E421                <1> 	in	al, 21h    		; read interrupt mask register
 13452 00003B8F EB00                <1> 	JMP	$+2			; I/O DELAY
 13453 00003B91 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
 13454 00003B93 E621                <1> 	out	21h, al    		; write back to register
 13455                              <1> 	;
 13456                              <1> 	; 23/10/2015
 13457 00003B95 B8[A5390000]        <1> 	mov 	eax, com1_int
 13458 00003B9A A3[773F0000]        <1> 	mov	[com1_irq4], eax
 13459                              <1> 	; 26/10/2015
 13460 00003B9F 9D                  <1> 	popf
 13461 00003BA0 C3                  <1> 	retn
 13462                              <1> 
 13463                              <1> sp_invp_err:
 13464 00003BA1 C705[D5740000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 13465 00003BA9 0000                <1>
 13466 00003BAB 31C9                <1> 	xor	ecx, ecx
 13467 00003BAD 49                  <1> 	dec	ecx ; 0FFFFh
 13468 00003BAE F9                  <1> 	stc
 13469 00003BAF C3                  <1> 	retn
 13470                              <1> 
 13471                              <1> ; 29/10/2015
 13472                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
 13473 00003BB0 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
 13474                              <1> 
 13475                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (01/09/2014) 
 13476                              <1> epoch:
 13477                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13478                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1 - UNIX.ASM)
 13479                              <1> 	; 'epoch' procedure prototype: 
 13480                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13481                              <1> 	; 14/11/2012
 13482                              <1> 	; unixboot.asm (boot file configuration)
 13483                              <1> 	; version of "epoch" procedure in "unixproc.asm"
 13484                              <1> 	; 21/7/2012
 13485                              <1> 	; 15/7/2012
 13486                              <1> 	; 14/7/2012		
 13487                              <1> 	; Erdogan Tan - RETRO UNIX v0.1
 13488                              <1> 	; compute current date and time as UNIX Epoch/Time
 13489                              <1> 	; UNIX Epoch: seconds since 1/1/1970 00:00:00
 13490                              <1> 	;
 13491                              <1>         ;  ((Modified registers: EAX, EDX, ECX, EBX))  
 13492                              <1> 	;
 13493 00003BB7 E81D010000          <1> 	call 	get_rtc_time		; Return Current Time
 13494 00003BBC 86E9                <1>         xchg 	ch,cl
 13495 00003BBE 66890D[B26D0000]    <1>         mov 	[hour], cx
 13496 00003BC5 86F2                <1>         xchg 	dh,dl
 13497 00003BC7 668915[B66D0000]    <1>         mov 	[second], dx
 13498                              <1> 	;
 13499 00003BCE E837010000          <1>         call 	get_rtc_date		; Return Current Date
 13500 00003BD3 86E9                <1>         xchg 	ch,cl
 13501 00003BD5 66890D[AC6D0000]    <1>         mov 	[year], cx
 13502 00003BDC 86F2                <1>         xchg 	dh,dl
 13503 00003BDE 668915[AE6D0000]    <1>         mov 	[month], dx
 13504                              <1> 	;
 13505 00003BE5 66B93030            <1> 	mov 	cx, 3030h
 13506                              <1> 	;
 13507 00003BE9 A0[B26D0000]        <1> 	mov 	al, [hour] ; Hour
 13508                              <1>         	; AL <= BCD number)
 13509 00003BEE D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13510                              <1> 					; AH = AL / 10h
 13511                              <1> 					; AL = AL MOD 10h
 13512 00003BF0 D50A                <1>         aad 	; AX= AH*10+AL
 13513 00003BF2 A2[B26D0000]        <1> 	mov 	[hour], al
 13514 00003BF7 A0[B36D0000]        <1> 	mov 	al, [hour+1] ; Minute
 13515                              <1>         	; AL <= BCD number)
 13516 00003BFC D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13517                              <1> 					; AH = AL / 10h
 13518                              <1> 					; AL = AL MOD 10h
 13519 00003BFE D50A                <1>         aad 	; AX= AH*10+AL
 13520 00003C00 A2[B46D0000]        <1> 	mov 	[minute], al
 13521 00003C05 A0[B66D0000]        <1> 	mov 	al, [second] ; Second
 13522                              <1>         	; AL <= BCD number)
 13523 00003C0A D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13524                              <1> 					; AH = AL / 10h
 13525                              <1> 					; AL = AL MOD 10h
 13526 00003C0C D50A                <1>         aad 	; AX= AH*10+AL
 13527 00003C0E A2[B66D0000]        <1> 	mov 	[second], al
 13528 00003C13 66A1[AC6D0000]      <1> 	mov 	ax, [year] ; Year (century)
 13529 00003C19 6650                <1>         push 	ax
 13530                              <1> 	   	; AL <= BCD number)
 13531 00003C1B D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13532                              <1> 					; AH = AL / 10h
 13533                              <1> 					; AL = AL MOD 10h
 13534 00003C1D D50A                <1>         aad 	; AX= AH*10+AL
 13535 00003C1F B464                <1> 	mov 	ah, 100
 13536 00003C21 F6E4                <1> 	mul 	ah
 13537 00003C23 66A3[AC6D0000]      <1> 	mov 	[year], ax
 13538 00003C29 6658                <1> 	pop	ax
 13539 00003C2B 88E0                <1> 	mov	al, ah
 13540                              <1>         	; AL <= BCD number)
 13541 00003C2D D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13542                              <1> 					; AH = AL / 10h
 13543                              <1> 					; AL = AL MOD 10h
 13544 00003C2F D50A                <1>         aad 	; AX= AH*10+AL
 13545 00003C31 660105[AC6D0000]    <1> 	add 	[year], ax
 13546 00003C38 A0[AE6D0000]        <1> 	mov 	al, [month] ; Month
 13547                              <1>            	; AL <= BCD number)
 13548 00003C3D D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13549                              <1> 					; AH = AL / 10h
 13550                              <1> 					; AL = AL MOD 10h
 13551 00003C3F D50A                <1>         aad 	; AX= AH*10+AL
 13552 00003C41 A2[AE6D0000]        <1> 	mov 	[month], al	
 13553 00003C46 A0[AF6D0000]        <1>         mov     al, [month+1]      	; Day
 13554                              <1>            	; AL <= BCD number)
 13555 00003C4B D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13556                              <1> 					; AH = AL / 10h
 13557                              <1> 					; AL = AL MOD 10h
 13558 00003C4D D50A                <1>         aad 	; AX= AH*10+AL
 13559 00003C4F A2[B06D0000]        <1>         mov     [day], al
 13560                              <1> 	
 13561                              <1> convert_to_epoch:
 13562                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit modification)
 13563                              <1> 	; 09/04/2013 (retro UNIX 8086 v1)
 13564                              <1> 	;
 13565                              <1> 	; ((Modified registers: EAX, EDX, EBX)) 
 13566                              <1> 	;
 13567                              <1> 	; Derived from DALLAS Semiconductor
 13568                              <1> 	; Application Note 31 (DS1602/DS1603)
 13569                              <1> 	; 6 May 1998
 13570 00003C54 29C0                <1> 	sub 	eax, eax
 13571 00003C56 66A1[AC6D0000]      <1> 	mov 	ax, [year]
 13572 00003C5C 662DB207            <1> 	sub 	ax, 1970
 13573 00003C60 BA6D010000          <1> 	mov 	edx, 365
 13574 00003C65 F7E2                <1> 	mul 	edx
 13575 00003C67 31DB                <1> 	xor 	ebx, ebx
 13576 00003C69 8A1D[AE6D0000]      <1> 	mov 	bl, [month]
 13577 00003C6F FECB                <1> 	dec 	bl
 13578 00003C71 D0E3                <1> 	shl 	bl, 1
 13579                              <1> 	;sub	edx, edx
 13580 00003C73 668B93[B86D0000]    <1> 	mov 	dx, [EBX+DMonth]
 13581 00003C7A 8A1D[B06D0000]      <1>         mov     bl, [day]
 13582 00003C80 FECB                <1> 	dec 	bl
 13583 00003C82 01D0                <1> 	add 	eax, edx
 13584 00003C84 01D8                <1> 	add 	eax, ebx
 13585                              <1> 			; EAX = days since 1/1/1970
 13586 00003C86 668B15[AC6D0000]    <1> 	mov 	dx, [year]
 13587 00003C8D 6681EAB107          <1> 	sub 	dx, 1969
 13588 00003C92 66D1EA              <1> 	shr 	dx, 1
 13589 00003C95 66D1EA              <1> 	shr 	dx, 1		
 13590                              <1> 		; (year-1969)/4
 13591 00003C98 01D0                <1> 	add 	eax, edx
 13592                              <1> 			; + leap days since 1/1/1970
 13593 00003C9A 803D[AE6D0000]02    <1> 	cmp 	byte [month], 2	; if past february
 13594 00003CA1 7610                <1> 	jna 	short cte1
 13595 00003CA3 668B15[AC6D0000]    <1> 	mov 	dx, [year]
 13596 00003CAA 6683E203            <1> 	and 	dx, 3 ; year mod 4
 13597 00003CAE 7503                <1> 	jnz 	short cte1		
 13598                              <1> 			; and if leap year
 13599 00003CB0 83C001              <1> 	add 	eax, 1 	; add this year's leap day (february 29)
 13600                              <1> cte1: 			; compute seconds since 1/1/1970
 13601 00003CB3 BA18000000          <1> 	mov 	edx, 24
 13602 00003CB8 F7E2                <1> 	mul	edx
 13603 00003CBA 8A15[B26D0000]      <1> 	mov 	dl, [hour]
 13604 00003CC0 01D0                <1> 	add 	eax, edx
 13605                              <1> 		; EAX = hours since 1/1/1970 00:00:00
 13606                              <1> 	;mov	ebx, 60
 13607 00003CC2 B33C                <1> 	mov	bl, 60
 13608 00003CC4 F7E3                <1> 	mul	ebx
 13609 00003CC6 8A15[B46D0000]      <1> 	mov 	dl, [minute]
 13610 00003CCC 01D0                <1> 	add 	eax, edx
 13611                              <1> 		; EAX = minutes since 1/1/1970 00:00:00
 13612                              <1> 	;mov 	ebx, 60
 13613 00003CCE F7E3                <1> 	mul	ebx
 13614 00003CD0 8A15[B66D0000]      <1> 	mov 	dl, [second]
 13615 00003CD6 01D0                <1> 	add 	eax, edx
 13616                              <1>  		; EAX -> seconds since 1/1/1970 00:00:00
 13617 00003CD8 C3                  <1> 	retn
 13618                              <1> 
 13619                              <1> get_rtc_time:
 13620                              <1> 	; 15/03/2015
 13621                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13622                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13623                              <1> 	; INT 1Ah
 13624                              <1> 	; (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,	:
 13625                              <1> 	;       (CH) = HOURS IN BCD (00-23)			:
 13626                              <1> 	;       (CL) = MINUTES IN BCD (00-59)			:
 13627                              <1> 	;       (DH) = SECONDS IN BCD (00-59)			:
 13628                              <1> 	;       (DL) = DAYLIGHT SAVINGS ENABLE (00-01).		:
 13629                              <1> 	;								
 13630                              <1> RTC_20: 				; GET RTC TIME
 13631 00003CD9 FA                  <1> 	cli
 13632 00003CDA E870CFFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13633 00003CDF 7227                <1> 	JC	short RTC_29		; EXIT IF ERROR (CY= 1)
 13634                              <1> 
 13635 00003CE1 B000                <1> 	MOV	AL,CMOS_SECONDS 	; SET ADDRESS OF SECONDS
 13636 00003CE3 E84FCFFFFF          <1> 	CALL	CMOS_READ		; GET SECONDS
 13637 00003CE8 88C6                <1> 	MOV	DH,AL			; SAVE
 13638 00003CEA B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
 13639 00003CEC E846CFFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 13640 00003CF1 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
 13641 00003CF3 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
 13642 00003CF5 B002                <1> 	MOV	AL,CMOS_MINUTES 	; SET ADDRESS OF MINUTES
 13643 00003CF7 E83BCFFFFF          <1> 	CALL	CMOS_READ		; GET MINUTES
 13644 00003CFC 88C1                <1> 	MOV	CL,AL			; SAVE
 13645 00003CFE B004                <1> 	MOV	AL,CMOS_HOURS		; SET ADDRESS OF HOURS
 13646 00003D00 E832CFFFFF          <1> 	CALL	CMOS_READ		; GET HOURS
 13647 00003D05 88C5                <1> 	MOV	CH,AL			; SAVE
 13648 00003D07 F8                  <1> 	CLC				; SET CY= 0
 13649                              <1> RTC_29:
 13650 00003D08 FB                  <1> 	sti
 13651 00003D09 C3                  <1> 	RETn				; RETURN WITH RESULT IN CARRY FLAG
 13652                              <1> 
 13653                              <1> get_rtc_date:
 13654                              <1> 	; 15/03/2015
 13655                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13656                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13657                              <1> 	; INT 1Ah
 13658                              <1> 	; (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,:
 13659                              <1> 	;      (CH) = CENTURY IN BCD (19 OR 20) 		       :
 13660                              <1> 	;      (CL) = YEAR IN BCD (00-99)			       :
 13661                              <1> 	;      (DH) = MONTH IN BCD (01-12)			       :
 13662                              <1> 	;      (DL) = DAY IN BCD (01-31).		
 13663                              <1> 	;
 13664                              <1> RTC_40: 				; GET RTC DATE
 13665 00003D0A FA                  <1> 	cli
 13666 00003D0B E83FCFFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13667 00003D10 7225                <1> 	JC	short RTC_49		; EXIT IF ERROR (CY= 1)
 13668                              <1> 
 13669 00003D12 B007                <1> 	MOV	AL,CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
 13670 00003D14 E81ECFFFFF          <1> 	CALL	CMOS_READ		; READ DAY OF MONTH
 13671 00003D19 88C2                <1> 	MOV	DL,AL			; SAVE
 13672 00003D1B B008                <1> 	MOV	AL,CMOS_MONTH		; ADDRESS MONTH
 13673 00003D1D E815CFFFFF          <1> 	CALL	CMOS_READ		; READ MONTH
 13674 00003D22 88C6                <1> 	MOV	DH,AL			; SAVE
 13675 00003D24 B009                <1> 	MOV	AL,CMOS_YEAR		; ADDRESS YEAR
 13676 00003D26 E80CCFFFFF          <1> 	CALL	CMOS_READ		; READ YEAR
 13677 00003D2B 88C1                <1> 	MOV	CL,AL			; SAVE
 13678 00003D2D B032                <1> 	MOV	AL,CMOS_CENTURY 	; ADDRESS CENTURY LOCATION
 13679 00003D2F E803CFFFFF          <1> 	CALL	CMOS_READ		; GET CENTURY BYTE
 13680 00003D34 88C5                <1> 	MOV	CH,AL			; SAVE
 13681 00003D36 F8                  <1> 	CLC				; SET CY=0
 13682                              <1> RTC_49:
 13683 00003D37 FB                  <1> 	sti
 13684 00003D38 C3                  <1> 	RETn				; RETURN WITH RESULTS IN CARRY FLAG
 13685                              <1> 
 13686                              <1> set_date_time:
 13687                              <1> convert_from_epoch:
 13688                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13689                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 13690                              <1> 	; 'convert_from_epoch' procedure prototype: 
 13691                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13692                              <1> 	;
 13693                              <1> 	; ((Modified registers: EAX, EDX, ECX, EBX))	
 13694                              <1> 	;
 13695                              <1> 	; Derived from DALLAS Semiconductor
 13696                              <1> 	; Application Note 31 (DS1602/DS1603)
 13697                              <1> 	; 6 May 1998
 13698                              <1> 	;
 13699                              <1> 	; INPUT:
 13700                              <1> 	; EAX = Unix (Epoch) Time
 13701                              <1> 	;
 13702 00003D39 31D2                <1> 	xor 	edx, edx
 13703 00003D3B B93C000000          <1> 	mov 	ecx, 60
 13704 00003D40 F7F1                <1> 	div	ecx
 13705                              <1> 	;mov 	[imin], eax   ; whole minutes
 13706                              <1> 			  ; since 1/1/1970
 13707 00003D42 668915[B66D0000]    <1> 	mov 	[second], dx  ; leftover seconds
 13708 00003D49 29D2                <1> 	sub 	edx, edx
 13709 00003D4B F7F1                <1> 	div	ecx
 13710                              <1> 	;mov 	[ihrs], eax   ; whole hours
 13711                              <1> 	;		      ; since 1/1/1970
 13712 00003D4D 668915[B46D0000]    <1> 	mov 	[minute], dx  ; leftover minutes
 13713 00003D54 31D2                <1> 	xor	edx, edx
 13714                              <1> 	;mov 	cx, 24
 13715 00003D56 B118                <1> 	mov 	cl, 24
 13716 00003D58 F7F1                <1> 	div	ecx
 13717                              <1> 	;mov 	[iday], ax   ; whole days
 13718                              <1> 			     ; since 1/1/1970
 13719 00003D5A 668915[B26D0000]    <1> 	mov 	[hour], dx   ; leftover hours
 13720 00003D61 05DB020000          <1> 	add 	eax, 365+366 ; whole day since
 13721                              <1> 			     ; 1/1/1968 	
 13722                              <1> 	;mov 	[iday], ax
 13723 00003D66 50                  <1> 	push 	eax
 13724 00003D67 29D2                <1> 	sub	edx, edx
 13725 00003D69 B9B5050000          <1> 	mov 	ecx, (4*365)+1 ; 4 years = 1461 days
 13726 00003D6E F7F1                <1> 	div	ecx
 13727 00003D70 59                  <1> 	pop 	ecx
 13728                              <1> 	;mov 	[lday], ax   ; count of quadyrs (4 years)
 13729 00003D71 6652                <1> 	push 	dx
 13730                              <1> 	;mov 	[qday], dx   ; days since quadyr began
 13731 00003D73 6683FA3C            <1> 	cmp 	dx, 31 + 29  ; if past feb 29 then
 13732 00003D77 F5                  <1> 	cmc		     ; add this quadyr's leap day
 13733 00003D78 83D000              <1> 	adc 	eax, 0	     ; to # of qadyrs (leap days)
 13734                              <1> 	;mov 	[lday], ax   ; since 1968			  
 13735                              <1> 	;mov 	cx, [iday]
 13736 00003D7B 91                  <1> 	xchg 	ecx, eax     ; ECX = lday, EAX = iday		  
 13737 00003D7C 29C8                <1> 	sub 	eax, ecx     ; iday - lday
 13738 00003D7E B96D010000          <1> 	mov 	ecx, 365
 13739 00003D83 31D2                <1> 	xor	edx, edx
 13740                              <1> 	; EAX = iday-lday, EDX = 0
 13741 00003D85 F7F1                <1> 	div	ecx
 13742                              <1> 	;mov 	[iyrs], ax   ; whole years since 1968
 13743                              <1> 	;jday = iday - (iyrs*365) - lday
 13744                              <1> 	;mov [jday], dx      ; days since 1/1 of current year
 13745                              <1> 	;add	eax, 1968
 13746 00003D87 6605B007            <1> 	add 	ax, 1968     ; compute year
 13747 00003D8B 66A3[AC6D0000]      <1> 	mov 	[year], ax
 13748 00003D91 6689D1              <1> 	mov 	cx, dx
 13749                              <1> 	;mov 	dx, [qday]
 13750 00003D94 665A                <1> 	pop 	dx
 13751 00003D96 6681FA6D01          <1> 	cmp 	dx, 365	     ; if qday <= 365 and qday >= 60	
 13752 00003D9B 7709                <1> 	ja 	short cfe1   ; jday = jday +1
 13753 00003D9D 6683FA3C            <1> 	cmp 	dx, 60       ; if past 2/29 and leap year then
 13754 00003DA1 F5                  <1>         cmc		     ; add a leap day to the # of whole
 13755 00003DA2 6683D100            <1> 	adc 	cx, 0        ; days since 1/1 of current year
 13756                              <1> cfe1:			
 13757                              <1> 	;mov 	[jday], cx
 13758 00003DA6 66BB0C00            <1> 	mov 	bx, 12       ; estimate month
 13759 00003DAA 66BA6E01            <1> 	mov 	dx, 366      ; mday, max. days since 1/1 is 365
 13760 00003DAE 6683E003            <1> 	and 	ax, 11b      ; year mod 4 (and dx, 3) 
 13761                              <1> cfe2:	; Month calculation  ; 0 to 11  (11 to 0)	
 13762 00003DB2 6639D1              <1> 	cmp 	cx, dx       ; mday = # of days passed from 1/1
 13763 00003DB5 731D                <1> 	jnb 	short cfe3
 13764 00003DB7 664B                <1> 	dec 	bx           ; month = month - 1
 13765 00003DB9 66D1E3              <1> 	shl 	bx, 1 
 13766 00003DBC 668B93[B86D0000]    <1> 	mov 	dx, [EBX+DMonth] ; # elapsed days at 1st of month
 13767 00003DC3 66D1EB              <1> 	shr 	bx, 1        ; bx = month - 1 (0 to 11)
 13768 00003DC6 6683FB01            <1> 	cmp	bx, 1        ; if month > 2 and year mod 4  = 0	
 13769 00003DCA 76E6                <1> 	jna 	short cfe2   ; then mday = mday + 1
 13770 00003DCC 08C0                <1> 	or 	al, al       ; if past 2/29 and leap year then
 13771 00003DCE 75E2                <1> 	jnz 	short cfe2   ; add leap day (to mday)
 13772 00003DD0 6642                <1> 	inc 	dx           ; mday = mday + 1
 13773 00003DD2 EBDE                <1> 	jmp 	short cfe2
 13774                              <1> cfe3:
 13775 00003DD4 6643                <1> 	inc 	bx	     ; -> bx = month, 1 to 12
 13776 00003DD6 66891D[AE6D0000]    <1> 	mov 	[month], bx
 13777 00003DDD 6629D1              <1> 	sub 	cx, dx	     ; day = jday - mday + 1	
 13778 00003DE0 6641                <1> 	inc 	cx 			  
 13779 00003DE2 66890D[B06D0000]    <1> 	mov 	[day], cx
 13780                              <1> 	
 13781                              <1> 	; eax, ebx, ecx, edx is changed at return
 13782                              <1> 	; output ->
 13783                              <1> 	; [year], [month], [day], [hour], [minute], [second]
 13784                              <1> 	
 13785                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13786                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 13787                              <1> set_date:
 13788 00003DE9 A0[AD6D0000]        <1>         mov     al, [year+1]
 13789 00003DEE D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13790 00003DF0 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13791                              <1> 			     ; AL = AH * 10h + AL
 13792 00003DF2 88C5                <1> 	mov 	ch, al ; century (BCD)
 13793 00003DF4 A0[AC6D0000]        <1> 	mov 	al, [year]
 13794 00003DF9 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13795 00003DFB D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13796                              <1> 			     ; AL = AH * 10h + AL
 13797 00003DFD 88C1                <1> 	mov 	cl, al ; year (BCD)
 13798 00003DFF A0[AE6D0000]        <1>         mov 	al, [month]
 13799 00003E04 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13800 00003E06 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13801                              <1> 			     ; AL = AH * 10h + AL
 13802 00003E08 88C6                <1> 	mov 	dh, al ; month (BCD)
 13803 00003E0A A0[B06D0000]        <1> 	mov 	al, [day]
 13804 00003E0F D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13805 00003E11 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13806                              <1> 			     ; AL = AH * 10h + AL
 13807 00003E13 88C6                <1> 	mov 	dh, al ; day (BCD)
 13808                              <1> 	; Set real-time clock date
 13809 00003E15 E879000000          <1> 	call	set_rtc_date
 13810                              <1> set_time:
 13811                              <1>         ; Read real-time clock time 
 13812                              <1> 	; (get day light saving time bit status)
 13813 00003E1A FA                  <1>  	cli
 13814 00003E1B E82FCEFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13815                              <1> 	; cf = 1 -> al = 0
 13816 00003E20 7207                <1>         jc      short stime1
 13817 00003E22 B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
 13818 00003E24 E80ECEFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 13819                              <1> stime1:
 13820 00003E29 FB                  <1> 	sti
 13821 00003E2A 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
 13822 00003E2C 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
 13823                              <1> 	; DL = 1 or 0 (day light saving time)
 13824                              <1> 	;	
 13825 00003E2E A0[B26D0000]        <1> 	mov 	al, [hour]
 13826 00003E33 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13827 00003E35 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13828                              <1> 			     ; AL = AH * 10h + AL
 13829 00003E37 88C5                <1> 	mov 	ch, al ; hour (BCD)
 13830 00003E39 A0[B46D0000]        <1>         mov     al, [minute]
 13831 00003E3E D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13832 00003E40 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13833                              <1> 			     ; AL = AH * 10h + AL
 13834 00003E42 88C1                <1> 	mov 	cl, al       ; minute (BCD)
 13835 00003E44 A0[B66D0000]        <1>         mov     al, [second]
 13836 00003E49 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13837 00003E4B D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13838                              <1> 			     ; AL = AH * 10h + AL
 13839 00003E4D 88C6                <1> 	mov 	dh, al	     ; second (BCD)
 13840                              <1> 	; Set real-time clock time
 13841                              <1>  	; call	set_rtc_time
 13842                              <1> set_rtc_time:
 13843                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 13844                              <1> 	; 15/03/2015
 13845                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13846                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13847                              <1> 	; INT 1Ah
 13848                              <1> 	; (AH) = 03H  SET THE REAL TIME CLOCK USING,			:
 13849                              <1> 	;      (CH) = HOURS IN BCD (00-23)			       	:
 13850                              <1> 	;      (CL) = MINUTES IN BCD (00-59)			       	:
 13851                              <1> 	;      (DH) = SECONDS IN BCD (00-59)			       	:
 13852                              <1> 	;      (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.    :
 13853                              <1> 	;								:
 13854                              <1> 	;  NOTE: (DL)= 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED. :
 13855                              <1> 	;        (DL)= 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN  :
 13856                              <1> 	;         APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN :
 13857                              <1> 	;         OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.	  :
 13858                              <1> 	;
 13859                              <1> RTC_30: 				; SET RTC TIME
 13860 00003E4F FA                  <1> 	cli
 13861 00003E50 E8FACDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13862 00003E55 7305                <1> 	JNC	short RTC_35		; GO AROUND IF CLOCK OPERATING
 13863 00003E57 E886000000          <1> 	CALL	RTC_STA 		; ELSE TRY INITIALIZING CLOCK
 13864                              <1> RTC_35:
 13865 00003E5C 88F4                <1> 	MOV	AH,DH			; GET TIME BYTE - SECONDS
 13866 00003E5E B000                <1> 	MOV	AL,CMOS_SECONDS 	; ADDRESS SECONDS
 13867 00003E60 E89E000000          <1> 	CALL	CMOS_WRITE		; UPDATE SECONDS
 13868 00003E65 88CC                <1> 	MOV	AH,CL			; GET TIME BYTE - MINUTES
 13869 00003E67 B002                <1> 	MOV	AL,CMOS_MINUTES 	; ADDRESS MINUTES
 13870 00003E69 E895000000          <1> 	CALL	CMOS_WRITE		; UPDATE MINUTES
 13871 00003E6E 88EC                <1> 	MOV	AH,CH			; GET TIME BYTE - HOURS
 13872 00003E70 B004                <1> 	MOV	AL,CMOS_HOURS		; ADDRESS HOURS
 13873 00003E72 E88C000000          <1> 	CALL	CMOS_WRITE		; UPDATE ADDRESS
 13874                              <1> 	;MOV	AX,X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 13875 00003E77 66B80B0B            <1> 	MOV	AX,257*CMOS_REG_B 	; 
 13876 00003E7B E8B7CDFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT TIME
 13877 00003E80 2462                <1> 	AND	AL,01100010B		; MASK FOR VALID BIT POSITIONS
 13878 00003E82 0C02                <1> 	OR	AL,00000010B		; TURN ON 24 HOUR MODE
 13879 00003E84 80E201              <1> 	AND	DL,00000001B		; USE ONLY THE DSE BIT
 13880 00003E87 08D0                <1> 	OR	AL,DL			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
 13881 00003E89 86E0                <1> 	XCHG	AH,AL			; PLACE IN WORK REGISTER AND GET ADDRESS
 13882 00003E8B E873000000          <1> 	CALL	CMOS_WRITE		; SET NEW ALARM BITS
 13883 00003E90 F8                  <1> 	CLC				; SET CY= 0
 13884 00003E91 FB                  <1> 	sti
 13885 00003E92 C3                  <1> 	RETn				; RETURN WITH CY= 0
 13886                              <1> 
 13887                              <1> set_rtc_date:
 13888                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 13889                              <1> 	; 15/03/2015
 13890                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13891                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13892                              <1> 	; INT 1Ah
 13893                              <1> 	; (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING, :
 13894                              <1> 	;     (CH) = CENTURY IN BCD (19 OR 20)			   :
 13895                              <1> 	;     (CL) = YEAR IN BCD (00-99)			   :
 13896                              <1> 	;     (DH) = MONTH IN BCD (01-12)			   :
 13897                              <1> 	;     (DL) = DAY IN BCD (01-31).
 13898                              <1> 	;
 13899                              <1> RTC_50: 				; SET RTC DATE
 13900 00003E93 FA                  <1> 	cli
 13901 00003E94 E8B6CDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13902 00003E99 7305                <1> 	JNC	short RTC_55		; GO AROUND IF NO ERROR
 13903 00003E9B E842000000          <1> 	CALL	RTC_STA 		; ELSE INITIALIZE CLOCK
 13904                              <1> RTC_55:
 13905 00003EA0 66B80600            <1> 	MOV	AX,CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
 13906 00003EA4 E85A000000          <1> 	CALL	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
 13907 00003EA9 88D4                <1> 	MOV	AH,DL			; GET DAY OF MONTH BYTE
 13908 00003EAB B007                <1> 	MOV	AL,CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
 13909 00003EAD E851000000          <1> 	CALL	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
 13910 00003EB2 88F4                <1> 	MOV	AH,DH			; GET MONTH
 13911 00003EB4 B008                <1> 	MOV	AL,CMOS_MONTH		; ADDRESS MONTH BYTE
 13912 00003EB6 E848000000          <1> 	CALL	CMOS_WRITE		; WRITE MONTH REGISTER
 13913 00003EBB 88CC                <1> 	MOV	AH,CL			; GET YEAR BYTE
 13914 00003EBD B009                <1> 	MOV	AL,CMOS_YEAR		; ADDRESS YEAR REGISTER
 13915 00003EBF E83F000000          <1> 	CALL	CMOS_WRITE		; WRITE YEAR REGISTER
 13916 00003EC4 88EC                <1> 	MOV	AH,CH			; GET CENTURY BYTE
 13917 00003EC6 B032                <1> 	MOV	AL,CMOS_CENTURY 	; ADDRESS CENTURY BYTE
 13918 00003EC8 E836000000          <1> 	CALL	CMOS_WRITE		; WRITE CENTURY LOCATION
 13919                              <1> 	;MOV	AX,X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 13920 00003ECD 66B80B0B            <1> 	MOV	AX,257*CMOS_REG_B 	; 
 13921 00003ED1 E861CDFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT SETTINGS
 13922 00003ED6 247F                <1> 	AND	AL,07FH 		; CLEAR 'SET BIT'
 13923 00003ED8 86E0                <1> 	XCHG	AH,AL			; MOVE TO WORK REGISTER
 13924 00003EDA E824000000          <1> 	CALL	CMOS_WRITE		; AND START CLOCK UPDATING
 13925 00003EDF F8                  <1> 	CLC				; SET CY= 0
 13926 00003EE0 FB                  <1> 	sti
 13927 00003EE1 C3                  <1> 	RETn				; RETURN CY=0
 13928                              <1> 
 13929                              <1> 	; 15/03/2015
 13930                              <1> RTC_STA:				; INITIALIZE REAL TIME CLOCK
 13931 00003EE2 B426                <1> 	mov	ah, 26h
 13932 00003EE4 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK
 13933 00003EE6 E818000000          <1> 	CALL	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
 13934 00003EEB B482                <1> 	mov	ah, 82h
 13935 00003EED B00B                <1> 	mov 	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION
 13936 00003EEF E80F000000          <1> 	CALL	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
 13937 00003EF4 B00C                <1> 	MOV	AL,CMOS_REG_C		; ADDRESS REGISTER C
 13938 00003EF6 E83CCDFFFF          <1> 	CALL	CMOS_READ		; READ REGISTER C TO INITIALIZE
 13939 00003EFB B00D                <1> 	MOV	AL,CMOS_REG_D		; ADDRESS REGISTER D
 13940 00003EFD E835CDFFFF          <1> 	CALL	CMOS_READ		; READ REGISTER D TO INITIALIZE
 13941 00003F02 C3                  <1> 	RETn
 13942                              <1> 
 13943                              <1> 	; 15/03/2015
 13944                              <1> 	; IBM PC/XT Model 286 BIOS source code ----- 10/06/85 (test4.asm)
 13945                              <1> CMOS_WRITE:			; WRITE (AH) TO LOCATION (AL)
 13946 00003F03 9C                  <1> 	pushf			; SAVE INTERRUPT ENABLE STATUS AND FLAGS
 13947                              <1> 	;push	ax		; SAVE WORK REGISTER VALUES
 13948 00003F04 D0C0                <1> 	rol	al, 1		; MOVE NMI BIT TO LOW POSITION
 13949 00003F06 F9                  <1> 	stc			; FORCE NMI BIT ON IN CARRY FLAG
 13950 00003F07 D0D8                <1> 	rcr	al, 1		; HIGH BIT ON TO DISABLE NMI - OLD IN CY
 13951 00003F09 FA                  <1> 	cli			; DISABLE INTERRUPTS
 13952 00003F0A E670                <1> 	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
 13953 00003F0C 88E0                <1> 	mov	al, ah		; GET THE DATA BYTE TO WRITE
 13954 00003F0E E671                <1> 	out	CMOS_DATA, al	; PLACE IN REQUESTED CMOS LOCATION
 13955 00003F10 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
 13956 00003F12 D0D8                <1> 	rcr	al, 1		; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
 13957 00003F14 E670                <1> 	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
 13958 00003F16 90                  <1> 	nop			; I/O DELAY
 13959 00003F17 E471                <1> 	in	al, CMOS_DATA	; OPEN STANDBY LATCH
 13960                              <1> 	;pop	ax		; RESTORE WORK REGISTERS
 13961 00003F19 9D                  <1> 	popf	
 13962 00003F1A C3                  <1> 	RETn
 13963                              <1> 
 13964                              <1> bf_init:
 13965                              <1> 	; 14/08/2015
 13966                              <1> 	; 02/07/2015
 13967                              <1> 	; 01/07/2015
 13968                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 13969                              <1> 	; Buffer (pointer) initialization !
 13970                              <1> 	; 
 13971                              <1> 	; 17/07/2013 - 24/07/2013
 13972                              <1> 	; Retro UNIX 8086 v1 (U9.ASM)
 13973                              <1> 	; (Retro UNIX 8086 v1 feature only !)
 13974                              <1> 	;
 13975 00003F1B BF[4A740000]        <1> 	mov	edi, bufp 
 13976 00003F20 B8[287D0000]        <1> 	mov	eax, buffer + (nbuf*520) 
 13977 00003F25 29D2                <1> 	sub	edx, edx
 13978 00003F27 FECA                <1> 	dec	dl
 13979 00003F29 31C9                <1> 	xor	ecx, ecx
 13980 00003F2B 49                  <1> 	dec	ecx
 13981                              <1> bi0:
 13982 00003F2C 2D08020000          <1> 	sub	eax, 520 ; 8 header + 512 data
 13983 00003F31 AB                  <1> 	stosd
 13984 00003F32 89C6                <1> 	mov	esi, eax
 13985 00003F34 8916                <1> 	mov	[esi], edx ; 000000FFh
 13986                              <1> 			    ; Not a valid device sign
 13987 00003F36 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 13988                              <1> 		      ; Not a valid block number sign 	 	
 13989 00003F39 3D[08750000]        <1> 	cmp	eax, buffer
 13990 00003F3E 77EC                <1> 	ja	short bi0
 13991 00003F40 B8[287D0000]        <1> 	mov	eax, sb0
 13992 00003F45 AB                  <1> 	stosd
 13993 00003F46 B8[307F0000]        <1> 	mov	eax, sb1
 13994 00003F4B AB                  <1> 	stosd
 13995 00003F4C 89C6                <1> 	mov	esi, eax ; offset sb1
 13996 00003F4E 8916                <1> 	mov	[esi], edx ; 000000FFh
 13997                              <1> 			    ; Not a valid device sign
 13998 00003F50 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 13999                              <1> 		      ; Not a valid block number sign 	 
 14000                              <1> 	; 14/08/2015
 14001                              <1> 	;call 	rdev_init
 14002                              <1> 	;retn
 14003                              <1> 
 14004                              <1> rdev_init: ; root device, super block buffer initialization
 14005                              <1> 	; 14/08/2015
 14006                              <1> 	; Retro UNIX 386 v1 feature only !
 14007                              <1> 	;
 14008                              <1> 	; NOTE: Disk partitions (file systems), logical
 14009                              <1> 	; drive initialization, partition's start sector etc.
 14010                              <1> 	; will be coded here, later in 'ldrv_init'	
 14011                              <1> 
 14012 00003F53 0FB605[D46D0000]    <1> 	movzx	eax, byte [boot_drv]
 14013                              <1> rdi_0:
 14014 00003F5A 3C80                <1> 	cmp	al, 80h
 14015 00003F5C 7202                <1> 	jb	short rdi_1
 14016 00003F5E 2C7E                <1> 	sub	al, 7Eh ; 80h = 2 (hd0), 81h = 3 (hd1)
 14017                              <1> rdi_1:
 14018 00003F60 A2[68740000]        <1> 	mov	[rdev], al
 14019 00003F65 BB[287D0000]        <1>         mov	ebx, sb0 ; super block buffer
 14020 00003F6A 8903                <1> 	mov 	[ebx], eax
 14021 00003F6C B001                <1> 	mov	al, 1 ; eax = 1
 14022 00003F6E 894304              <1> 	mov	[ebx+4], eax ; super block address on disk
 14023 00003F71 E838240000          <1> 	call 	diskio
 14024 00003F76 C3                  <1> 	retn
 14025                              <1> 
 14026                              <1> ; 23/10/2015
 14027                              <1> com1_irq4:
 14028 00003F77 [7F3F0000]          <1> 	dd dummy_retn
 14029                              <1> com2_irq3:
 14030 00003F7B [7F3F0000]          <1> 	dd dummy_retn
 14031                              <1> 
 14032                              <1> dummy_retn:
 14033 00003F7F C3                  <1> 	retn
 14034                                  %include 'u1.s'        ; 10/05/2015
 14035                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS1.INC
 14036                              <1> ; Last Modification: 27/12/2015
 14037                              <1> ; ----------------------------------------------------------------------------
 14038                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 14039                              <1> ; (v0.1 - Beginning: 11/07/2012)
 14040                              <1> ;
 14041                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 14042                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 14043                              <1> ; <Bell Laboratories (17/3/1972)>
 14044                              <1> ; <Preliminary Release of UNIX Implementation Document>
 14045                              <1> ;
 14046                              <1> ; Retro UNIX 8086 v1 - U1.ASM (12/07/2014) //// UNIX v1 -> u1.s
 14047                              <1> ;
 14048                              <1> ; ****************************************************************************
 14049                              <1> 
 14050                              <1> unkni: ; / used for all system calls
 14051                              <1> sysent: ; < enter to system call >
 14052                              <1> 	 ;19/10/2015
 14053                              <1> 	; 21/09/2015
 14054                              <1> 	; 01/07/2015
 14055                              <1> 	; 19/05/2015
 14056                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14057                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 14058                              <1> 	;
 14059                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
 14060                              <1> 	; The trap type is determined and an indirect jump is made to 
 14061                              <1> 	; the appropriate system call handler. If there is a trap inside
 14062                              <1> 	; the system a jump to panic is made. All user registers are saved 
 14063                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
 14064                              <1> 	; instructor is decoded to get the the system code part (see
 14065                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
 14066                              <1> 	; the indirect jump address is calculated. If a bad system call is
 14067                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
 14068                              <1> 	; is called. If the call is legitimate control passes to the
 14069                              <1> 	; appropriate system routine.
 14070                              <1> 	;
 14071                              <1> 	; Calling sequence:
 14072                              <1> 	;	Through a trap caused by any sys call outside the system.
 14073                              <1> 	; Arguments:
 14074                              <1> 	;	Arguments of particular system call.	
 14075                              <1> 	; ...............................................................
 14076                              <1> 	;	
 14077                              <1> 	; Retro UNIX 8086 v1 modification: 
 14078                              <1> 	;       System call number is in EAX register.
 14079                              <1> 	;
 14080                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14081                              <1> 	;	registers depending of function details.
 14082                              <1>   	;
 14083                              <1> 	; 16/04/2015
 14084 00003F80 368925[78740000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
 14085                              <1> 	; save user registers
 14086 00003F87 1E                  <1> 	push	ds
 14087 00003F88 06                  <1> 	push	es
 14088 00003F89 0FA0                <1> 	push	fs
 14089 00003F8B 0FA8                <1> 	push	gs
 14090 00003F8D 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
 14091                              <1> 	;
 14092                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
 14093                              <1> 	; 	(ESPACE is size of space in kernel stack 
 14094                              <1> 	;	for saving/restoring user registers.)
 14095                              <1> 	;
 14096 00003F8E 50                  <1> 	push	eax ; 01/07/2015
 14097 00003F8F 66B81000            <1> 	mov     ax, KDATA
 14098 00003F93 8ED8                <1>         mov     ds, ax
 14099 00003F95 8EC0                <1>         mov     es, ax
 14100 00003F97 8EE0                <1>         mov     fs, ax
 14101 00003F99 8EE8                <1>         mov     gs, ax
 14102 00003F9B A1[A8700000]        <1> 	mov	eax, [k_page_dir]
 14103 00003FA0 0F22D8              <1> 	mov	cr3, eax
 14104 00003FA3 58                  <1> 	pop	eax ; 01/07/2015
 14105                              <1> 	; 19/10/2015
 14106 00003FA4 FC                  <1> 	cld
 14107                              <1> 	;
 14108 00003FA5 FE05[77740000]      <1> 	inc	byte [sysflg]
 14109                              <1> 		; incb sysflg / indicate a system routine is in progress
 14110 00003FAB FB                  <1>         sti 	; 18/01/2014
 14111 00003FAC 0F8560F9FFFF        <1> 	jnz     panic ; 24/05/2013
 14112                              <1> 		; beq 1f
 14113                              <1> 		; jmp panic ; / called if trap inside system
 14114                              <1> ;1:
 14115                              <1> 	; 16/04/2015
 14116 00003FB2 A3[80740000]        <1> 	mov	[u.r0], eax
 14117 00003FB7 8925[7C740000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
 14118                              <1> 	;
 14119                              <1> 		; mov $s.syst+2,clockp
 14120                              <1> 		; mov r0,-(sp) / save user registers 
 14121                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
 14122                              <1> 			   ; / in u.r0
 14123                              <1> 		; mov r1,-(sp)
 14124                              <1> 		; mov r2,-(sp)
 14125                              <1> 		; mov r3,-(sp)
 14126                              <1> 		; mov r4,-(sp)
 14127                              <1> 		; mov r5,-(sp)
 14128                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
 14129                              <1> 		             ; / arithmetic unit
 14130                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
 14131                              <1> 		             ; / extended arithmetic unit
 14132                              <1> 		; mov sc,-(sp) / "step count" register for the extended
 14133                              <1> 		             ; / arithmetic unit
 14134                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
 14135                              <1> 		; mov 18.(sp),r0 / store pc in r0
 14136                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
 14137                              <1> 		; sub $sys,r0 / get xxx code
 14138 00003FBD C1E002              <1> 	shl	eax, 2
 14139                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
 14140 00003FC0 3D94000000          <1> 	cmp	eax, end_of_syscalls - syscalls
 14141                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
 14142                              <1> 	;jnb	short badsys
 14143                              <1> 		; bhis badsys / yes, bad system call
 14144 00003FC5 F5                  <1> 	cmc
 14145 00003FC6 9C                  <1> 	pushf	
 14146 00003FC7 50                  <1> 	push	eax
 14147 00003FC8 8B2D[78740000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
 14148 00003FCE B0FE                <1> 	mov	al, 0FEh ; 11111110b
 14149 00003FD0 1400                <1> 	adc	al, 0 ; al = al + cf
 14150 00003FD2 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
 14151                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
 14152                              <1> 				 ; / and clear carry bit
 14153 00003FD5 5D                  <1> 	pop	ebp ; eax
 14154 00003FD6 9D                  <1> 	popf
 14155 00003FD7 0F8248010000        <1>         jc      badsys
 14156 00003FDD A1[80740000]        <1> 	mov	eax, [u.r0]
 14157                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
 14158 00003FE2 FFA5[E83F0000]      <1> 	jmp	dword [ebp+syscalls]
 14159                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
 14160                              <1> 		            ; / to proper system routine.
 14161                              <1> syscalls: ; 1:
 14162                              <1> 	; 21/09/2015
 14163                              <1> 	; 01/07/2015
 14164                              <1> 	; 16/04/2015 (32 bit address modification) 
 14165 00003FE8 [EF400000]          <1> 	dd sysrele	; / 0
 14166 00003FEC [95410000]          <1> 	dd sysexit 	; / 1
 14167 00003FF0 [BA420000]          <1> 	dd sysfork 	; / 2
 14168 00003FF4 [CD430000]          <1> 	dd sysread 	; / 3
 14169 00003FF8 [E8430000]          <1> 	dd syswrite 	; / 4
 14170 00003FFC [52440000]          <1> 	dd sysopen 	; / 5
 14171 00004000 [8C450000]          <1> 	dd sysclose 	; / 6
 14172 00004004 [3C420000]          <1> 	dd syswait 	; / 7
 14173 00004008 [02450000]          <1> 	dd syscreat 	; / 8
 14174 0000400C [B3480000]          <1> 	dd syslink 	; / 9
 14175 00004010 [75490000]          <1> 	dd sysunlink 	; / 10
 14176 00004014 [484A0000]          <1> 	dd sysexec 	; / 11
 14177 00004018 [AF500000]          <1> 	dd syschdir 	; / 12
 14178 0000401C [93510000]          <1> 	dd systime 	; / 13
 14179 00004020 [43450000]          <1> 	dd sysmkdir 	; / 14
 14180 00004024 [01510000]          <1> 	dd syschmod 	; / 15
 14181 00004028 [63510000]          <1> 	dd syschown 	; / 16
 14182 0000402C [C6510000]          <1> 	dd sysbreak 	; / 17
 14183 00004030 [204E0000]          <1> 	dd sysstat 	; / 18
 14184 00004034 [8B520000]          <1> 	dd sysseek 	; / 19
 14185 00004038 [9D520000]          <1> 	dd systell 	; / 20
 14186 0000403C [9A5D0000]          <1> 	dd sysmount 	; / 21
 14187 00004040 [4C5E0000]          <1> 	dd sysumount 	; / 22
 14188 00004044 [1B530000]          <1> 	dd syssetuid 	; / 23
 14189 00004048 [4C530000]          <1> 	dd sysgetuid 	; / 24
 14190 0000404C [A2510000]          <1> 	dd sysstime 	; / 25
 14191 00004050 [0F530000]          <1> 	dd sysquit 	; / 26
 14192 00004054 [03530000]          <1> 	dd sysintr 	; / 27
 14193 00004058 [FC4D0000]          <1> 	dd sysfstat 	; / 28
 14194 0000405C [A8450000]          <1> 	dd sysemt 	; / 29
 14195 00004060 [D6450000]          <1> 	dd sysmdate 	; / 30
 14196 00004064 [21460000]          <1> 	dd sysstty 	; / 31
 14197 00004068 [A0470000]          <1> 	dd sysgtty 	; / 32
 14198 0000406C [D1450000]          <1> 	dd sysilgins 	; / 33
 14199 00004070 [81660000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
 14200                              <1> 			     ; 11/06/2014
 14201 00004074 [B0660000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
 14202                              <1> 			     ; 01/07/2015
 14203 00004078 [87670000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
 14204                              <1> 			     ; 21/09/2015 - get last error number
 14205                              <1> end_of_syscalls:
 14206                              <1> 
 14207                              <1> error:
 14208                              <1> 	; 17/09/2015
 14209                              <1> 	; 03/09/2015
 14210                              <1> 	; 01/09/2015
 14211                              <1> 	; 09/06/2015
 14212                              <1> 	; 13/05/2015
 14213                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14214                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 14215                              <1> 	;
 14216                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
 14217                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
 14218                              <1> 	;
 14219                              <1> 	; INPUTS -> none
 14220                              <1> 	; OUTPUTS ->
 14221                              <1> 	;	processor status - carry (c) bit is set (means error)
 14222                              <1> 	;
 14223                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
 14224                              <1> 	; 	      Because, jumps to error procedure
 14225                              <1> 	;	      disrupts push-pop nesting balance)
 14226                              <1> 	;
 14227 0000407C 8B2D[78740000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
 14228 00004082 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
 14229                              <1> 				 ; (system call will return with cf = 1)
 14230                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
 14231                              <1> 		               ; / users stack
 14232                              <1> 	; 17/09/2015
 14233 00004086 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
 14234                              <1> 				 ; for saving/restoring user registers	
 14235                              <1> 	;cmp	ebp, [u.usp]
 14236                              <1> 	;je	short err0	
 14237 00004089 892D[7C740000]      <1> 	mov	[u.usp], ebp
 14238                              <1> ;err0:
 14239                              <1> 	; 01/09/2015
 14240 0000408F 8B25[7C740000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
 14241                              <1> 				    ; 10/04/2013
 14242                              <1> 				    ; (If an I/O error occurs during disk I/O,
 14243                              <1> 				    ; related procedures will jump to 'error'
 14244                              <1> 				    ; procedure directly without returning to 
 14245                              <1> 				    ; the caller procedure. So, stack pointer
 14246                              <1>                                     ; must be restored here.)
 14247                              <1> 	; 13/05/2015
 14248                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
 14249                              <1> 	;	'get last error' system call later. 	
 14250                              <1> 
 14251                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
 14252 00004095 C605[E7740000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
 14253                              <1> 
 14254                              <1> sysret: ; < return from system call>
 14255                              <1> 	; 10/09/2015
 14256                              <1> 	; 29/07/2015
 14257                              <1> 	; 25/06/2015
 14258                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14259                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 14260                              <1> 	;
 14261                              <1> 	; 'sysret' first checks to see if process is about to be 
 14262                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
 14263                              <1> 	; If not, following happens:	 
 14264                              <1> 	; 	1) The user's stack pointer is restored.
 14265                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
 14266                              <1> 	;	   i-node has been modified. If it has, it is written out
 14267                              <1> 	;	   via 'ppoke'.
 14268                              <1> 	;	3) If the super block has been modified, it is written out
 14269                              <1> 	;	   via 'ppoke'.				
 14270                              <1> 	;	4) If the dismountable file system's super block has been
 14271                              <1> 	;	   modified, it is written out to the specified device
 14272                              <1> 	;	   via 'ppoke'.
 14273                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
 14274                              <1> 	;	   during his execution. If so, 'tswap' is called to give
 14275                              <1> 	;	   another user a chance to run.
 14276                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
 14277                              <1> 	;	    (See 'sysrele' for conclusion.)		
 14278                              <1> 	;
 14279                              <1> 	; Calling sequence:
 14280                              <1> 	;	jump table or 'br sysret'
 14281                              <1> 	; Arguments: 
 14282                              <1> 	;	-	
 14283                              <1> 	; ...............................................................
 14284                              <1> 	;	
 14285                              <1> 	; ((AX=r1 for 'iget' input))
 14286                              <1> 	;	
 14287 0000409C 6631C0              <1> 	xor	ax, ax ; 04/05/2013
 14288                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
 14289 0000409F FEC0                <1> 	inc	al ; 04/05/2013
 14290 000040A1 3805[CE740000]      <1> 	cmp	[u.bsys], al ; 1
 14291                              <1> 		; tstb u.bsys / is a process about to be terminated because
 14292 000040A7 0F83E8000000        <1>         jnb     sysexit ; 04/05/2013
 14293                              <1> 		; bne sysexit / of an error? yes, go to sysexit
 14294                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
 14295                              <1> 		; mov u.sp,sp / no point stack to users stack
 14296 000040AD FEC8                <1> 	dec 	al ; mov ax, 0
 14297                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
 14298 000040AF E874160000          <1> 	call	iget
 14299                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
 14300                              <1> 		            ; / it is written out
 14301 000040B4 6631C0              <1> 	xor 	ax, ax ; 0
 14302 000040B7 3805[75740000]      <1> 	cmp	[smod], al ; 0
 14303                              <1> 		; tstb	smod / has the super block been modified
 14304 000040BD 7614                <1> 	jna	short sysret1
 14305                              <1> 		; beq	1f / no, 1f
 14306 000040BF A2[75740000]        <1> 	mov	[smod], al ; 0
 14307                              <1> 		; clrb smod / yes, clear smod
 14308 000040C4 BB[287D0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
 14309 000040C9 66810B0002          <1>    	or	word [ebx], 200h ;;
 14310                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
 14311                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
 14312                              <1> 		      	      ; / output
 14313                              <1> 	; AX = 0
 14314 000040CE E8C0210000          <1> 	call 	poke ; 07/08/2013
 14315                              <1> 	; call	ppoke
 14316                              <1> 	; AX = 0
 14317                              <1> 		; jsr r0,ppoke / write out modified super block to disk
 14318                              <1> sysret1: ;1:
 14319 000040D3 3805[76740000]      <1> 	cmp	[mmod], al ; 0
 14320                              <1> 		; tstb	mmod / has the super block for the dismountable file
 14321                              <1> 		           ; / system
 14322 000040D9 7614                <1> 	jna	short sysrel0
 14323                              <1> 		; beq 1f / been modified?  no, 1f
 14324 000040DB A2[76740000]        <1> 	mov	[mmod], al ; 0	
 14325                              <1> 		; clrb	mmod / yes, clear mmod
 14326                              <1>         ;mov    ax, [mntd]
 14327                              <1>         ;;mov   al, [mdev] ; 26/04/2013
 14328 000040E0 BB[307F0000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
 14329                              <1>         ;;mov	[ebx], al
 14330                              <1> 	;mov    [sb1], al
 14331                              <1> 		; movb	mntd,sb1 / set the I/O queue
 14332 000040E5 66810B0002          <1> 	or	word [ebx], 200h
 14333                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
 14334                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
 14335 000040EA E8A4210000          <1> 	call	poke ; 07/08/2013
 14336                              <1> 	;call	ppoke 
 14337                              <1> 		; jsr r0,ppoke / write it out to its device
 14338                              <1>         ;xor    al, al ; 26/04/2013       
 14339                              <1> ;1:
 14340                              <1> 		; tstb uquant / is the time quantum 0?
 14341                              <1> 		; bne 1f / no, don't swap it out
 14342                              <1> 
 14343                              <1> sysrele: ; < release >
 14344                              <1> 	; 14/10/2015
 14345                              <1> 	; 01/09/2015
 14346                              <1> 	; 24/07/2015
 14347                              <1> 	; 14/05/2015
 14348                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14349                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
 14350                              <1> 	;
 14351                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
 14352                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
 14353                              <1> 	; turns off the system flag. It then checked to see if there is
 14354                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
 14355                              <1> 	; the output gets flashed (see isintr) and interrupt action is
 14356                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
 14357                              <1> 	; the user, a rti is made.
 14358                              <1> 	;
 14359                              <1> 	; Calling sequence:
 14360                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
 14361                              <1> 	; Arguments:
 14362                              <1> 	;	-	
 14363                              <1> 	; ...............................................................
 14364                              <1> 	;	
 14365                              <1> 	; 23/02/2014 (swapret)
 14366                              <1> 	; 22/09/2013
 14367                              <1> sysrel0: ;1:
 14368 000040EF 803D[C2740000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
 14369                              <1> 		; tstb uquant / is the time quantum 0?
 14370 000040F6 7705                <1>         ja      short swapret
 14371                              <1> 		; bne 1f / no, don't swap it out
 14372                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
 14373 000040F8 E8A1120000          <1> 	call	tswap
 14374                              <1> 		; jsr r0,tswap / yes, swap it out
 14375                              <1> ;
 14376                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
 14377                              <1> swapret: ;1:
 14378                              <1> 	; 10/09/2015
 14379                              <1> 	; 01/09/2015
 14380                              <1> 	; 14/05/2015
 14381                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
 14382                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
 14383                              <1> 	; cli
 14384                              <1> 	; 24/07/2015
 14385                              <1> 	;
 14386                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
 14387                              <1> 	;; mov	esp, [u.usp]
 14388                              <1> 
 14389                              <1> 	; 22/09/2013
 14390 000040FD E886140000          <1> 	call	isintr
 14391                              <1> 	; 20/10/2013
 14392 00004102 7405                <1> 	jz	short sysrel1
 14393 00004104 E875000000          <1> 	call	intract
 14394                              <1> 		; jsr r0,isintr / is there an interrupt from the user
 14395                              <1> 		;     br intract / yes, output gets flushed, take interrupt
 14396                              <1> 		               ; / action
 14397                              <1> sysrel1:
 14398 00004109 FA                  <1> 	cli ; 14/10/2015
 14399 0000410A FE0D[77740000]      <1> 	dec	byte [sysflg]
 14400                              <1> 		; decb sysflg / turn system flag off
 14401 00004110 A1[D9740000]        <1> 	mov     eax, [u.pgdir]
 14402 00004115 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
 14403                              <1> 			  ; (others are different than kernel page tables) 
 14404                              <1> 	; 10/09/2015
 14405 00004118 61                  <1> 	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
 14406                              <1> 		; mov (sp)+,sc / restore user registers
 14407                              <1> 		; mov (sp)+,mq
 14408                              <1> 		; mov (sp)+,ac
 14409                              <1> 		; mov (sp)+,r5
 14410                              <1> 		; mov (sp)+,r4
 14411                              <1> 		; mov (sp)+,r3
 14412                              <1> 		; mov (sp)+,r2
 14413                              <1> 	;
 14414 00004119 A1[80740000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
 14415 0000411E 0FA9                <1> 	pop	gs
 14416 00004120 0FA1                <1> 	pop	fs
 14417 00004122 07                  <1> 	pop	es
 14418 00004123 1F                  <1> 	pop	ds
 14419 00004124 CF                  <1> 	iretd	
 14420                              <1> 		; rti / no, return from interrupt
 14421                              <1> 
 14422                              <1> badsys:
 14423                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14424                              <1> 	; (Major Modification: 'core' dumping procedure in
 14425                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
 14426                              <1> 	;	has been changed to print 'Invalid System Call !'
 14427                              <1> 	;	message on the user's console tty.)
 14428                              <1> 	; (EIP, EAX values will be shown on screen with error message)
 14429                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
 14430                              <1> 	; (EAX = Function number)  
 14431                              <1> 	;
 14432 00004125 FE05[CE740000]      <1> 	inc	byte [u.bsys]
 14433                              <1> 	;
 14434 0000412B 8B1D[78740000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
 14435 00004131 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
 14436 00004133 E8E7D7FFFF          <1> 	call	dwordtohex
 14437 00004138 8915[A06D0000]      <1> 	mov	[bsys_msg_eip], edx
 14438 0000413E A3[A46D0000]        <1> 	mov	[bsys_msg_eip+4], eax
 14439 00004143 A1[80740000]        <1> 	mov	eax, [u.r0]
 14440 00004148 E8D2D7FFFF          <1> 	call	dwordtohex
 14441 0000414D 8915[906D0000]      <1> 	mov	[bsys_msg_eax], edx
 14442 00004153 A3[946D0000]        <1> 	mov	[bsys_msg_eax+4], eax
 14443 00004158 31C0                <1> 	xor	eax, eax
 14444 0000415A C705[A0740000]-     <1>         mov     dword [u.base], badsys_msg ; "Invalid System call !"
 14445 00004160 [716D0000]          <1>
 14446 00004164 8B1D[90740000]      <1> 	mov	ebx, [u.fofp]
 14447 0000416A 8903                <1> 	mov	[ebx], eax
 14448                              <1> 	;mov	eax, 1 ; inode number of console tty (for user)	
 14449 0000416C 40                  <1> 	inc	eax
 14450 0000416D C705[A4740000]3B00- <1> 	mov	dword [u.count], BSYS_M_SIZE
 14451 00004175 0000                <1>
 14452                              <1> 		; writei
 14453                              <1> 		; INPUTS ->
 14454                              <1> 		;    r1 - inode number
 14455                              <1> 		;    u.count - byte count to be written
 14456                              <1> 		;    u.base - points to user buffer
 14457                              <1> 		;    u.fofp - points to word with current file offset
 14458                              <1> 		; OUTPUTS ->
 14459                              <1> 		;    u.count - cleared
 14460                              <1> 		;    u.nread - accumulates total bytes passed back	
 14461                              <1> 		;
 14462                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
 14463 00004177 E882190000          <1> 	call	writei
 14464                              <1> 	;mov	eax, 1
 14465 0000417C EB17                <1> 	jmp	sysexit
 14466                              <1> 
 14467                              <1> 		; incb u.bsys / turn on the user's bad-system flag
 14468                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
 14469                              <1> 		; jsr r0,namei / get the i-number for the core image file
 14470                              <1> 		; br 1f / error
 14471                              <1> 		; neg r1 / negate the i-number to open the core image file
 14472                              <1> 		       ; / for writing
 14473                              <1> 		; jsr r0,iopen / open the core image file
 14474                              <1> 		; jsr r0,itrunc / free all associated blocks
 14475                              <1> 		; br 2f
 14476                              <1> ;1:
 14477                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
 14478                              <1> 		; jsr r0,maknod / make an i-node
 14479                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
 14480                              <1> ;2:
 14481                              <1> 		; mov $core,u.base / move address core to u.base
 14482                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
 14483                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
 14484                              <1> 		; clr u.off / clear user offset
 14485                              <1> 		; jsr r0,writei / write out the core image to the user
 14486                              <1> 		; mov $user,u.base / pt. u.base to user
 14487                              <1> 		; mov $64.,u.count / u.count = 64
 14488                              <1> 		; jsr r0,writei / write out all the user parameters
 14489                              <1> 		; neg r1 / make i-number positive
 14490                              <1> 		; jsr r0,iclose / close the core image file
 14491                              <1> 		; br sysexit /
 14492                              <1> ;3:
 14493                              <1> 		; <core\0\0>
 14494                              <1> 
 14495                              <1> intract: ; / interrupt action
 14496                              <1> 	; 14/10/2015
 14497                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14498                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
 14499                              <1> 	;
 14500                              <1> 	; Retro UNIX 8086 v1 modification !
 14501                              <1> 	; (Process/task switching and quit routine by using
 14502                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 14503                              <1> 	;
 14504                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
 14505                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
 14506                              <1> 	;		'intract' will jump to 'sysexit'.
 14507                              <1> 	;	    Intract will return to the caller 
 14508                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
 14509                              <1> 	; 14/10/2015
 14510 0000417E FB                  <1> 	sti
 14511                              <1> 	; 07/12/2013	
 14512 0000417F 66FF05[C6740000]    <1> 	inc 	word [u.quit]
 14513 00004186 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
 14514 00004188 66FF0D[C6740000]    <1> 	dec	word [u.quit]
 14515                              <1> 	; 16/04/2015
 14516 0000418F C3                  <1> 	retn
 14517                              <1> intrct0:	
 14518 00004190 58                  <1> 	pop	eax ; call intract -> retn
 14519                              <1> 	;
 14520 00004191 31C0                <1> 	xor 	eax, eax
 14521 00004193 FEC0                <1> 	inc	al  ; mov ax, 1
 14522                              <1> ;;;
 14523                              <1> 	; UNIX v1 original 'intract' routine... 
 14524                              <1> 	; / interrupt action
 14525                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
 14526                              <1> 		; bne 1f / no, 1f
 14527                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
 14528                              <1> 	; 1: / now in user area
 14529                              <1> 		; mov r1,-(sp) / save r1
 14530                              <1> 		; mov u.ttyp,r1 
 14531                              <1> 			; / pointer to tty buffer in control-to r1
 14532                              <1> 		; cmpb 6(r1),$177
 14533                              <1> 			; / is the interrupt char equal to "del"
 14534                              <1> 		; beq 1f / yes, 1f
 14535                              <1> 		; clrb 6(r1) 
 14536                              <1> 		        ; / no, clear the byte 
 14537                              <1> 			; / (must be a quit character)
 14538                              <1> 		; mov (sp)+,r1 / restore r1
 14539                              <1> 		; clr u.quit / clear quit flag
 14540                              <1> 		; bis $20,2(sp) 
 14541                              <1> 		    	; / set trace for quit (sets t bit of 
 14542                              <1> 			; / ps-trace trap)
 14543                              <1> 		; rti   ;  / return from interrupt
 14544                              <1> 	; 1: / interrupt char = del
 14545                              <1> 		; clrb 6(r1) / clear the interrupt byte 
 14546                              <1> 			   ; / in the buffer
 14547                              <1> 		; mov (sp)+,r1 / restore r1
 14548                              <1> 		; cmp u.intr,$core / should control be 
 14549                              <1> 				; / transferred to loc core?
 14550                              <1> 		; blo 1f
 14551                              <1> 		; jmp *u.intr / user to do rti yes, 
 14552                              <1> 				; / transfer to loc core
 14553                              <1> 	; 1:
 14554                              <1> 		; sys 1 / exit
 14555                              <1> 
 14556                              <1> sysexit: ; <terminate process>
 14557                              <1> 	; 01/09/2015
 14558                              <1> 	; 31/08/2015
 14559                              <1> 	; 14/05/2015
 14560                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14561                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 14562                              <1> 	;
 14563                              <1> 	; 'sysexit' terminates a process. First each file that
 14564                              <1> 	; the process has opened is closed by 'flose'. The process
 14565                              <1> 	; status is then set to unused. The 'p.pid' table is then
 14566                              <1> 	; searched to find children of the dying process. If any of
 14567                              <1> 	; children are zombies (died by not waited for), they are
 14568                              <1> 	; set free. The 'p.pid' table is then searched to find the
 14569                              <1> 	; dying process's parent. When the parent is found, it is
 14570                              <1> 	; checked to see if it is free or it is a zombie. If it is
 14571                              <1> 	; one of these, the dying process just dies. If it is waiting
 14572                              <1> 	; for a child process to die, it notified that it doesn't 
 14573                              <1> 	; have to wait anymore by setting it's status from 2 to 1
 14574                              <1> 	; (waiting to active). It is awakened and put on runq by
 14575                              <1> 	; 'putlu'. The dying process enters a zombie state in which
 14576                              <1> 	; it will never be run again but stays around until a 'wait'
 14577                              <1> 	; is completed by it's parent process. If the parent is not
 14578                              <1> 	; found, process just dies. This means 'swap' is called with
 14579                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
 14580                              <1> 	; to write out the process and 'rswap' reads the new process
 14581                              <1> 	; over the one that dies..i.e., the dying process is 
 14582                              <1> 	; overwritten and destroyed.	
 14583                              <1>  	;
 14584                              <1> 	; Calling sequence:
 14585                              <1> 	;	sysexit or conditional branch.
 14586                              <1> 	; Arguments:
 14587                              <1> 	;	-	
 14588                              <1> 	; ...............................................................
 14589                              <1> 	;	
 14590                              <1> 	; Retro UNIX 8086 v1 modification: 
 14591                              <1> 	;       System call number (=1) is in EAX register.
 14592                              <1> 	;
 14593                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14594                              <1> 	;       registers depending of function details.
 14595                              <1> 	;
 14596                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
 14597                              <1> 	;
 14598                              <1> ; / terminate process
 14599                              <1> 	; AX = 1
 14600 00004195 6648                <1> 	dec 	ax ; 0
 14601 00004197 66A3[C4740000]      <1> 	mov	[u.intr], ax ; 0
 14602                              <1> 		; clr u.intr / clear interrupt control word
 14603                              <1> 		; clr r1 / clear r1
 14604                              <1> 	; AX = 0
 14605                              <1> sysexit_1: ; 1:
 14606                              <1> 	; AX = File descriptor
 14607                              <1> 		; / r1 has file descriptor (index to u.fp list)
 14608                              <1> 		; / Search the whole list
 14609 0000419D E8140D0000          <1> 	call	fclose
 14610                              <1> 		; jsr r0,fclose / close all files the process opened
 14611                              <1> 	;; ignore error return
 14612                              <1> 		; br .+2 / ignore error return
 14613                              <1> 	;inc	ax
 14614 000041A2 FEC0                <1> 	inc	al
 14615                              <1> 		; inc r1 / increment file descriptor
 14616                              <1> 	;cmp	ax, 10
 14617 000041A4 3C0A                <1> 	cmp	al, 10
 14618                              <1> 		; cmp r1,$10. / end of u.fp list?
 14619 000041A6 72F5                <1> 	jb	short sysexit_1
 14620                              <1> 		; blt 1b / no, go back
 14621 000041A8 0FB61D[CF740000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 14622                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
 14623 000041AF 88A3[05720000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 14624                              <1> 		; clrb p.stat-1(r1) / free the process
 14625                              <1> 	;shl	bx, 1
 14626 000041B5 D0E3                <1> 	shl	bl, 1
 14627                              <1> 		; asl r1 / use r1 for index into the below tables
 14628 000041B7 668B8B[74710000]    <1> 	mov	cx, [ebx+p.pid-2]
 14629                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
 14630 000041BE 668B93[94710000]    <1> 	mov	dx, [ebx+p.ppid-2]
 14631                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
 14632                              <1> 	; xor 	bx, bx ; 0
 14633 000041C5 30DB                <1> 	xor	bl, bl ; 0
 14634                              <1> 		; clr r2
 14635 000041C7 31F6                <1> 	xor	esi, esi ; 0
 14636                              <1> 		; clr r5 / initialize reg
 14637                              <1> sysexit_2: ; 1:
 14638                              <1> 	        ; / find children of this dying process, 
 14639                              <1> 		; / if they are zombies, free them
 14640                              <1> 	;add	bx, 2
 14641 000041C9 80C302              <1> 	add	bl, 2
 14642                              <1> 		; add $2,r2 / search parent process table 
 14643                              <1> 		          ; / for dying process's name
 14644 000041CC 66398B[94710000]    <1> 	cmp	[ebx+p.ppid-2], cx
 14645                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
 14646 000041D3 7513                <1> 	jne	short sysexit_4
 14647                              <1> 		; bne 3f / no
 14648                              <1> 	;shr	bx, 1
 14649 000041D5 D0EB                <1> 	shr	bl, 1
 14650                              <1> 		; asr r2 / yes, it is a parent
 14651 000041D7 80BB[05720000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
 14652                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
 14653                              <1> 				     ; / dying process a zombie
 14654 000041DE 7506                <1> 	jne	short sysexit_3 
 14655                              <1> 		; bne 2f / no
 14656 000041E0 88A3[05720000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 14657                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
 14658                              <1> sysexit_3: ; 2:
 14659                              <1> 	;shr	bx, 1
 14660 000041E6 D0E3                <1> 	shl	bl, 1
 14661                              <1> 		; asl r2
 14662                              <1> sysexit_4: ; 3:
 14663                              <1> 		; / search the process name table 
 14664                              <1> 		; / for the dying process's parent
 14665 000041E8 663993[74710000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
 14666                              <1> 		; cmp p.pid-2(r2),r4 / found it?
 14667 000041EF 7502                <1> 	jne	short sysexit_5
 14668                              <1> 		; bne 3f / no
 14669 000041F1 89DE                <1> 	mov	esi, ebx
 14670                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
 14671                              <1> 		          ; / process # x2) in r5
 14672                              <1> sysexit_5: ; 3:
 14673                              <1> 	;cmp	bx, nproc + nproc
 14674 000041F3 80FB20              <1> 	cmp	bl, nproc + nproc
 14675                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
 14676 000041F6 72D1                <1> 	jb	short sysexit_2
 14677                              <1> 		; blt 1b / no, go back
 14678                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
 14679 000041F8 21F6                <1> 	and	esi, esi ; r5=r1
 14680 000041FA 7431                <1> 	jz	short sysexit_6
 14681                              <1> 		; beq 2f / no parent has been found. 
 14682                              <1> 		       ; / The process just dies
 14683 000041FC 66D1EE              <1> 	shr	si, 1
 14684                              <1> 		; asr r1 / set up index to p.stat
 14685 000041FF 8A86[05720000]      <1> 	mov	al, [esi+p.stat-1]
 14686                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
 14687 00004205 20C0                <1> 	and	al, al
 14688 00004207 7424                <1> 	jz	short sysexit_6
 14689                              <1> 		; beq 2f / if its been freed, 2f
 14690 00004209 3C03                <1> 	cmp	al, 3
 14691                              <1> 		; cmp r2,$3 / is parent a zombie?
 14692 0000420B 7420                <1> 	je	short sysexit_6
 14693                              <1> 		; beq 2f / yes, 2f
 14694                              <1> 	; BH = 0
 14695 0000420D 8A1D[CF740000]      <1> 	mov	bl, [u.uno]
 14696                              <1> 		; movb u.uno,r3 / move dying process's number to r3
 14697 00004213 C683[05720000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
 14698                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
 14699                              <1> 	; 05/02/2014
 14700 0000421A 3C01                <1> 	cmp	al, 1 ; SRUN
 14701 0000421C 740F                <1> 	je	short sysexit_6
 14702                              <1> 	;cmp	al, 2
 14703                              <1> 		; cmp r2,$2 / is the parent waiting for 
 14704                              <1> 			  ; / this child to die
 14705                              <1> 	;jne	short sysexit_6	
 14706                              <1> 		; bne 2f / yes, notify parent not to wait any more
 14707                              <1> 	; 05/02/2014
 14708                              <1> 	; p.stat = 2 --> waiting
 14709                              <1> 	; p.stat = 4 --> sleeping
 14710 0000421E C686[05720000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
 14711                              <1> 	;dec	byte [esi+p.stat-1]
 14712                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
 14713 00004225 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
 14714                              <1> 	; 
 14715                              <1> 	;mov	ebx, runq + 4
 14716                              <1> 		; mov $runq+4,r2 / on the runq
 14717 00004228 E849120000          <1> 	call	putlu
 14718                              <1> 		; jsr r0, putlu
 14719                              <1> sysexit_6: ; 2:
 14720                              <1> 	; 31/08/2015
 14721                              <1> 		; / the process dies
 14722 0000422D C605[CF740000]00    <1> 	mov	byte [u.uno], 0
 14723                              <1> 		; clrb u.uno / put zero as the process number, 
 14724                              <1> 	           ; / so "swap" will
 14725 00004234 E86F110000          <1> 	call	swap
 14726                              <1> 		; jsr r0,swap / overwrite process with another process
 14727                              <1> hlt_sys:
 14728                              <1> 	;sti ; 18/01/2014
 14729                              <1> hlts0:
 14730 00004239 F4                  <1> 	hlt
 14731 0000423A EBFD                <1> 	jmp	short hlts0
 14732                              <1> 		; 0 / and thereby kill it; halt?
 14733                              <1> 
 14734                              <1> 
 14735                              <1> syswait: ; < wait for a processs to die >
 14736                              <1> 	; 17/09/2015
 14737                              <1> 	; 02/09/2015
 14738                              <1> 	; 01/09/2015
 14739                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14740                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
 14741                              <1> 	;
 14742                              <1> 	; 'syswait' waits for a process die. 
 14743                              <1> 	; It works in following way:
 14744                              <1> 	;    1) From the parent process number, the parent's 
 14745                              <1> 	; 	process name is found. The p.ppid table of parent
 14746                              <1> 	;	names is then searched for this process name.
 14747                              <1> 	;	If a match occurs, r2 contains child's process
 14748                              <1> 	;	number. The child status is checked to see if it is
 14749                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
 14750                              <1> 	;	If it is, the child process is freed and it's name
 14751                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
 14752                              <1> 	;	If the child is not a zombie, nothing happens and
 14753                              <1> 	;	the search goes on through the p.ppid table until
 14754                              <1> 	;	all processes are checked or a zombie is found.
 14755                              <1> 	;    2) If no zombies are found, a check is made to see if
 14756                              <1> 	;	there are any children at all. If there are none,
 14757                              <1> 	;	an error return is made. If there are, the parent's
 14758                              <1> 	;	status is set to 2 (waiting for child to die),
 14759                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
 14760                              <1> 	;	is made to wait on the next process.
 14761                              <1> 	;
 14762                              <1> 	; Calling sequence:
 14763                              <1> 	;	?
 14764                              <1> 	; Arguments:
 14765                              <1> 	;	-
 14766                              <1> 	; Inputs: - 
 14767                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
 14768                              <1> 	; ...............................................................
 14769                              <1> 	;				
 14770                              <1> 	
 14771                              <1> ; / wait for a process to die
 14772                              <1> 
 14773                              <1> syswait_0:
 14774 0000423C 0FB61D[CF740000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 14775                              <1> 		; movb u.uno,r1 / put parents process number in r1
 14776 00004243 D0E3                <1> 	shl	bl, 1
 14777                              <1> 	;shl	bx, 1
 14778                              <1> 		; asl r1 / x2 to get index into p.pid table
 14779 00004245 668B83[74710000]    <1> 	mov	ax, [ebx+p.pid-2]
 14780                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
 14781 0000424C 31F6                <1> 	xor	esi, esi
 14782                              <1> 		; clr r2
 14783 0000424E 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
 14784                              <1> 	;xor 	cl, cl
 14785                              <1> 		; clr r3 / initialize reg 3
 14786                              <1> syswait_1: ; 1:
 14787 00004250 6683C602            <1> 	add	si, 2
 14788                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
 14789                              <1> 			  ; / search table of parent processes 
 14790                              <1> 			  ; / for this process name
 14791 00004254 663B86[94710000]    <1> 	cmp	ax, [esi+p.ppid-2]
 14792                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
 14793                              <1> 			            ; / process number
 14794 0000425B 7535                <1> 	jne	short syswait_3
 14795                              <1> 		;bne 3f / branch if no match of parent process name
 14796                              <1> 	;inc	cx
 14797 0000425D FEC1                <1> 	inc	cl
 14798                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
 14799 0000425F 66D1EE              <1> 	shr	si, 1
 14800                              <1> 		; asr r2 / r2/2 to get index to p.stat table
 14801                              <1> 	; The possible states ('p.stat' values) of a process are:
 14802                              <1> 	;	0 = free or unused
 14803                              <1> 	;	1 = active
 14804                              <1> 	;	2 = waiting for a child process to die
 14805                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
 14806 00004262 80BE[05720000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
 14807                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
 14808 00004269 7524                <1> 	jne	short syswait_2
 14809                              <1> 		; bne 2f / no, skip it
 14810 0000426B 88BE[05720000]      <1> 	mov	[esi+p.stat-1], bh ; 0
 14811                              <1> 		; clrb p.stat-1(r2) / yes, free it
 14812 00004271 66D1E6              <1> 	shl	si, 1
 14813                              <1> 		; asl r2 / r2x2 to get index into p.pid table
 14814 00004274 0FB786[74710000]    <1> 	movzx	eax, word [esi+p.pid-2]
 14815 0000427B A3[80740000]        <1> 	mov	[u.r0], eax
 14816                              <1> 		; mov p.pid-2(r2),*u.r0 
 14817                              <1> 			      ; / put childs process name in (u.r0)
 14818                              <1> 	;
 14819                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
 14820                              <1> 	;
 14821                              <1> 	; Parent process ID -p.ppid- field (of the child process)
 14822                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
 14823                              <1> 	; system call loop from the application/program if it calls
 14824                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
 14825                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
 14826                              <1> 	;
 14827                              <1> 	; Note: syswait will return with error if there is not a
 14828                              <1> 	;       zombie or running process to wait.	
 14829                              <1> 	;
 14830 00004280 6629C0              <1> 	sub	ax, ax
 14831 00004283 668986[94710000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
 14832 0000428A E910FEFFFF          <1> 	jmp	sysret0 ; ax = 0
 14833                              <1> 	;
 14834                              <1> 	;jmp	sysret
 14835                              <1> 		; br sysret1 / return cause child is dead
 14836                              <1> syswait_2: ; 2:
 14837 0000428F 66D1E6              <1> 	shl	si, 1
 14838                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
 14839                              <1> syswait_3: ; 3:
 14840 00004292 6683FE20            <1> 	cmp	si, nproc+nproc
 14841                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
 14842 00004296 72B8                <1> 	jb	short syswait_1
 14843                              <1> 		; blt 1b / no, continue search
 14844                              <1> 	;and	cx, cx
 14845 00004298 20C9                <1> 	and	cl, cl
 14846                              <1> 		; tst r3 / one gets here if there are no children 
 14847                              <1> 		       ; / or children that are still active
 14848                              <1> 	; 30/10/2013
 14849 0000429A 750B                <1> 	jnz	short syswait_4
 14850                              <1> 	;jz	error
 14851                              <1> 		; beq error1 / there are no children, error
 14852 0000429C 890D[80740000]      <1> 	mov	[u.r0], ecx ; 0
 14853 000042A2 E9D5FDFFFF          <1> 	jmp	error
 14854                              <1> syswait_4:
 14855 000042A7 8A1D[CF740000]      <1> 	mov	bl, [u.uno]
 14856                              <1> 		; movb u.uno,r1 / there are children so put 
 14857                              <1> 			      ; / parent process number in r1
 14858 000042AD FE83[05720000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
 14859                              <1> 		; incb p.stat-1(r1) / it is waiting for 
 14860                              <1> 				  ; / other children to die
 14861                              <1> 	; 04/11/2013
 14862 000042B3 E8F0100000          <1> 	call	swap
 14863                              <1> 		; jsr r0,swap / swap it out, because it's waiting
 14864 000042B8 EB82                <1> 	jmp	syswait_0
 14865                              <1> 		; br syswait / wait on next process
 14866                              <1> 
 14867                              <1> sysfork: ; < create a new process >
 14868                              <1> 	; 18/09/2015
 14869                              <1> 	; 04/09/2015
 14870                              <1> 	; 02/09/2015
 14871                              <1> 	; 01/09/2015
 14872                              <1> 	; 28/08/2015
 14873                              <1> 	; 14/05/2015
 14874                              <1> 	; 10/05/2015
 14875                              <1> 	; 09/05/2015
 14876                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
 14877                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 14878                              <1> 	;
 14879                              <1> 	; 'sysfork' creates a new process. This process is referred
 14880                              <1> 	; to as the child process. This new process core image is
 14881                              <1> 	; a copy of that of the caller of 'sysfork'. The only
 14882                              <1> 	; distinction is the return location and the fact that (u.r0)
 14883                              <1> 	; in the old process (parent) contains the process id (p.pid)
 14884                              <1> 	; of the new process (child). This id is used by 'syswait'.
 14885                              <1> 	; 'sysfork' works in the following manner: 	
 14886                              <1> 	;    1) The process status table (p.stat) is searched to find
 14887                              <1> 	;	a process number that is unused. If none are found
 14888                              <1> 	;	an error occurs.
 14889                              <1> 	;    2) when one is found, it becomes the child process number
 14890                              <1> 	;	and it's status (p.stat) is set to active.
 14891                              <1> 	;    3) If the parent had a control tty, the interrupt 
 14892                              <1> 	;	character in that tty buffer is cleared.
 14893                              <1> 	;    4) The child process is put on the lowest priority run 
 14894                              <1> 	;	queue via 'putlu'.
 14895                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
 14896                              <1> 	;	it is a unique number) and is put in the child's unique
 14897                              <1> 	;	identifier; process id (p.pid).
 14898                              <1> 	;    6) The process name of the parent is then obtained and
 14899                              <1> 	;	placed in the unique identifier of the parent process
 14900                              <1> 	;	name is then put in 'u.r0'.	
 14901                              <1> 	;    7) The child process is then written out on disk by
 14902                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
 14903                              <1> 	;	and the child is born. (The child process is written 
 14904                              <1> 	;	out on disk/drum with 'u.uno' being the child process
 14905                              <1> 	;	number.)
 14906                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
 14907                              <1> 	;    9) The child process name is put in 'u.r0'.
 14908                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
 14909                              <1> 	;	create the return address for the parent process.
 14910                              <1> 	;   11) The 'u.fp' list as then searched to see what files
 14911                              <1> 	;	the parent has opened. For each file the parent has
 14912                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
 14913                              <1> 	;	to indicate that the child process also has opened
 14914                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
 14915                              <1> 	;
 14916                              <1> 	; Calling sequence:
 14917                              <1> 	;	from shell ?
 14918                              <1> 	; Arguments:
 14919                              <1> 	;	-
 14920                              <1> 	; Inputs: -
 14921                              <1> 	; Outputs: *u.r0 - child process name
 14922                              <1> 	; ...............................................................
 14923                              <1> 	;	
 14924                              <1> 	; Retro UNIX 8086 v1 modification: 
 14925                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
 14926                              <1> 	;	= process id of child a parent process returns
 14927                              <1> 	;	= process id of parent when a child process returns
 14928                              <1> 	;
 14929                              <1> 	;       In original UNIX v1, sysfork is called and returns as
 14930                              <1> 	;	in following manner: (with an example: c library, fork)
 14931                              <1> 	;	
 14932                              <1> 	;	1:
 14933                              <1> 	;		sys	fork
 14934                              <1> 	;			br 1f  / child process returns here
 14935                              <1> 	;		bes	2f     / parent process returns here
 14936                              <1> 	;		/ pid of new process in r0
 14937                              <1> 	;		rts	pc
 14938                              <1> 	;	2: / parent process condionally branches here
 14939                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
 14940                              <1> 	;		rts	pc
 14941                              <1> 	;
 14942                              <1> 	;	1: / child process brances here
 14943                              <1> 	;		clr	r0   / pid = 0 in child process
 14944                              <1> 	;		rts	pc
 14945                              <1> 	;
 14946                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
 14947                              <1> 	;		// pid = fork();
 14948                              <1> 	;		//
 14949                              <1> 	;		// pid == 0 in child process; 
 14950                              <1> 	;		// pid == -1 means error return
 14951                              <1> 	;		// in child, 
 14952                              <1> 	;		//	parents id is in par_uid if needed
 14953                              <1> 	;		
 14954                              <1> 	;		_fork:
 14955                              <1> 	;			mov	$.fork,eax
 14956                              <1> 	;			int	$0x30
 14957                              <1> 	;			jmp	1f
 14958                              <1> 	;			jnc	2f
 14959                              <1> 	;			jmp	cerror
 14960                              <1> 	;		1:
 14961                              <1> 	;			mov	eax,_par_uid
 14962                              <1> 	;			xor	eax,eax
 14963                              <1> 	;		2:
 14964                              <1> 	;			ret
 14965                              <1> 	;
 14966                              <1> 	;	In Retro UNIX 8086 v1,
 14967                              <1> 	;	'sysfork' returns in following manner:
 14968                              <1> 	;	
 14969                              <1> 	;		mov	ax, sys_fork
 14970                              <1> 	;		mov	bx, offset @f ; routine for child
 14971                              <1> 	;		int	20h
 14972                              <1> 	;		jc	error
 14973                              <1> 	;		
 14974                              <1> 	;	; Routine for parent process here (just after 'jc')
 14975                              <1> 	;		mov	word ptr [pid_of_child], ax
 14976                              <1> 	;		jmp	next_routine_for_parent	
 14977                              <1> 	;
 14978                              <1> 	;	@@: ; routine for child process here				
 14979                              <1> 	;		....	
 14980                              <1> 	;	NOTE: 'sysfork' returns to specified offset
 14981                              <1> 	;	       for child process by using BX input.
 14982                              <1> 	;	      (at first, parent process will return then 
 14983                              <1> 	;	      child process will return -after swapped in-
 14984                              <1> 	;	      'syswait' is needed in parent process
 14985                              <1> 	;	      if return from child process will be waited for.)
 14986                              <1> 	;	  				
 14987                              <1> 	
 14988                              <1> ; / create a new process
 14989                              <1> 	; EBX = return address for child process 
 14990                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
 14991 000042BA 31F6                <1> 	xor 	esi, esi
 14992                              <1> 		; clr r1
 14993                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
 14994 000042BC 46                  <1> 	inc	esi
 14995                              <1> 		; inc r1
 14996 000042BD 80BE[05720000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
 14997                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
 14998 000042C4 760B                <1> 	jna	short sysfork_2	
 14999                              <1> 		; beq 1f / it's unused so branch
 15000 000042C6 6683FE10            <1> 	cmp	si, nproc
 15001                              <1> 		; cmp r1,$nproc / all processes checked
 15002 000042CA 72F0                <1> 	jb	short sysfork_1
 15003                              <1> 		; blt 1b / no, branch back
 15004                              <1> 	;
 15005                              <1> 	; Retro UNIX 8086 v1. modification:
 15006                              <1> 	;	Parent process returns from 'sysfork' to address 
 15007                              <1> 	;	which is just after 'sysfork' system call in parent
 15008                              <1> 	;	process. Child process returns to address which is put
 15009                              <1> 	;	in BX register by parent process for 'sysfork'. 
 15010                              <1> 	;
 15011                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
 15012                              <1> 		             ; / to old process return
 15013                              <1> 		; br error1 / no room for a new process
 15014 000042CC E9ABFDFFFF          <1> 	jmp	error
 15015                              <1> sysfork_2: ; 1:
 15016 000042D1 E861EDFFFF          <1> 	call	allocate_page
 15017 000042D6 0F82A0FDFFFF        <1> 	jc	error
 15018 000042DC 50                  <1> 	push	eax   ; UPAGE (user structure page) address
 15019                              <1> 	; Retro UNIX 386 v1 modification!
 15020 000042DD E85EEFFFFF          <1> 	call	duplicate_page_dir
 15021                              <1> 		; EAX = New page directory 
 15022 000042E2 730B                <1> 	jnc	short sysfork_3
 15023 000042E4 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15024 000042E5 E825EFFFFF          <1> 	call 	deallocate_page
 15025 000042EA E98DFDFFFF          <1> 	jmp	error
 15026                              <1> sysfork_3:
 15027                              <1> 	; Retro UNIX 386 v1 modification !
 15028 000042EF 56                  <1> 	push	esi
 15029 000042F0 E82B110000          <1> 	call	wswap ; save current user (u) structure, user registers
 15030                              <1> 		      ; and interrupt return components (for IRET)
 15031 000042F5 8705[D9740000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
 15032 000042FB A3[DD740000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
 15033 00004300 5E                  <1> 	pop	esi
 15034 00004301 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15035                              <1> 		; [u.usp] = esp
 15036 00004302 89F7                <1> 	mov	edi, esi
 15037 00004304 66C1E702            <1> 	shl	di, 2
 15038 00004308 8987[12720000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
 15039 0000430E A3[D0740000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
 15040                              <1> 	; 28/08/2015
 15041 00004313 0FB605[CF740000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
 15042                              <1> 		; movb u.uno,-(sp) / save parent process number
 15043 0000431A 89C7                <1> 	mov	edi, eax
 15044 0000431C 50                  <1>         push	eax ; ** 
 15045 0000431D 8A87[D5710000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
 15046                              <1> 	; 18/09/2015
 15047                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
 15048                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
 15049 00004323 668986[D5710000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
 15050                              <1> 				   ; ah - reset child's wait channel	
 15051 0000432A 89F0                <1> 	mov	eax, esi
 15052 0000432C A2[CF740000]        <1> 	mov	[u.uno], al ; child process number
 15053                              <1> 		;movb r1,u.uno / set child process number to r1
 15054 00004331 FE86[05720000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
 15055                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
 15056                              <1> 				; / process to active status
 15057                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
 15058                              <1> 			      ; / control tty buffer in r2
 15059                              <1>                 ; beq 2f / branch, if no such tty assigned
 15060                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
 15061                              <1> 	; 2:
 15062 00004337 53                  <1> 	push	ebx  ; * return address for the child process
 15063                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15064                              <1> 	; (Retro UNIX 8086 v1 modification!)
 15065                              <1> 		; mov $runq+4,r2
 15066 00004338 E839110000          <1> 	call	putlu 
 15067                              <1>  		; jsr r0,putlu / put child process on lowest priority 
 15068                              <1> 			   ; / run queue
 15069 0000433D 66D1E6              <1> 	shl	si, 1
 15070                              <1> 		; asl r1 / multiply r1 by 2 to get index 
 15071                              <1> 		       ; / into p.pid table
 15072 00004340 66FF05[6E740000]    <1> 	inc	word [mpid]
 15073                              <1> 		; inc mpid / increment m.pid; get a new process name
 15074 00004347 66A1[6E740000]      <1> 	mov	ax, [mpid]
 15075 0000434D 668986[74710000]    <1> 	mov	[esi+p.pid-2], ax
 15076                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
 15077                              <1> 				    ; / in child process' name slot
 15078 00004354 5A                  <1> 	pop	edx  ; * return address for the child process
 15079                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15080 00004355 5B                  <1>   	pop	ebx  ; **
 15081                              <1> 	;mov	ebx, [esp] ; ** parent process number
 15082                              <1> 		; movb (sp),r2 / put parent process number in r2
 15083 00004356 66D1E3              <1> 	shl 	bx, 1
 15084                              <1> 		;asl r2 / multiply by 2 to get index into below tables
 15085                              <1> 	;movzx eax, word [ebx+p.pid-2]
 15086 00004359 668B83[74710000]    <1> 	mov	ax, [ebx+p.pid-2]
 15087                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
 15088                              <1> 				   ; / process
 15089 00004360 668986[94710000]    <1> 	mov	[esi+p.ppid-2], ax
 15090                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
 15091                              <1> 			  ; / in parent process slot for child
 15092 00004367 A3[80740000]        <1> 	mov	[u.r0], eax	
 15093                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
 15094                              <1> 			     ; / at location where r0 was saved
 15095 0000436C 8B2D[78740000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
 15096 00004372 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
 15097                              <1> 			   ; * return address for the child process
 15098                              <1> 		; mov $sysret1,-(sp) /
 15099                              <1> 		; mov sp,u.usp / contents of sp at the time when 
 15100                              <1> 			      ; / user is swapped out
 15101                              <1> 		; mov $sstack,sp / point sp to swapping stack space
 15102                              <1> 	; 04/09/2015 - 01/09/2015
 15103                              <1> 	; [u.usp] = esp
 15104 00004375 68[9C400000]        <1> 	push	sysret ; ***
 15105 0000437A 8925[7C740000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
 15106                              <1> 			     ; (for child process)	
 15107 00004380 31C0                <1> 	xor 	eax, eax
 15108 00004382 66A3[B0740000]      <1> 	mov 	[u.ttyp], ax ; 0
 15109                              <1> 	;
 15110 00004388 E893100000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
 15111                              <1> 		;jsr r0,wswap / put child process out on drum
 15112                              <1> 		;jsr r0,unpack / unpack user stack
 15113                              <1> 		;mov u.usp,sp / restore user stack pointer
 15114                              <1> 		; tst (sp)+ / bump stack pointer
 15115                              <1> 	; Retro UNIX 386 v1 modification !
 15116 0000438D 58                  <1> 	pop	eax ; ***
 15117 0000438E 66D1E3              <1> 	shl	bx, 1
 15118 00004391 8B83[12720000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
 15119 00004397 E8AD100000          <1> 	call	rswap ; restore parent process 'u' structure, 
 15120                              <1> 		      ; registers and return address (for IRET)
 15121                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
 15122 0000439C 0FB705[6E740000]    <1>         movzx   eax, word [mpid]
 15123 000043A3 A3[80740000]        <1> 	mov	[u.r0], eax
 15124                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
 15125                              <1> 			       ; / where r0 was saved
 15126                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
 15127                              <1> 			          ; / process return
 15128                              <1> 	;xor	ebx, ebx
 15129 000043A8 31F6                <1> 	xor     esi, esi
 15130                              <1> 		;clr r1
 15131                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
 15132                              <1> 	      ; / opened by the parent process
 15133                              <1> 	; 01/09/2015
 15134                              <1> 	;xor	bh, bh
 15135                              <1> 	;mov 	bl, [esi+u.fp]
 15136 000043AA 8A86[86740000]      <1> 	mov 	al, [esi+u.fp]
 15137                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
 15138                              <1>         ;or      bl, bl
 15139 000043B0 08C0                <1> 	or	al, al
 15140 000043B2 740D                <1> 	jz	short sysfork_5	
 15141                              <1> 		; beq 2f / file has not been opened by parent, 
 15142                              <1> 		       ; / so branch
 15143 000043B4 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
 15144 000043B6 F6E4                <1> 	mul	ah
 15145                              <1> 	;movzx	ebx, ax
 15146 000043B8 6689C3              <1> 	mov	bx, ax
 15147                              <1> 	;shl     bx, 3
 15148                              <1> 		; asl r2 / multiply by 8
 15149                              <1>        		; asl r2 / to get index into fsp table
 15150                              <1>        		; asl r2
 15151 000043BB FE83[54720000]      <1>   	inc     byte [ebx+fsp-2]
 15152                              <1> 		; incb fsp-2(r2) / increment number of processes
 15153                              <1> 			     ; / using file, because child will now be
 15154                              <1> 			     ; / using this file
 15155                              <1> sysfork_5: ; 2:
 15156 000043C1 46                  <1>         inc     esi
 15157                              <1> 		; inc r1 / get next open file
 15158 000043C2 6683FE0A            <1>         cmp     si, 10
 15159                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
 15160                              <1> 			  ; / can be opened
 15161 000043C6 72E2                <1> 	jb	short sysfork_4	
 15162                              <1> 		; blt 1b / check next entry
 15163 000043C8 E9CFFCFFFF          <1> 	jmp	sysret
 15164                              <1> 		; br sysret1
 15165                              <1> 
 15166                              <1> sysread: ; < read from file >
 15167                              <1> 	; 13/05/2015
 15168                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15169                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15170                              <1> 	;
 15171                              <1> 	; 'sysread' is given a buffer to read into and the number of
 15172                              <1> 	; characters to be read. If finds the file from the file
 15173                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
 15174                              <1> 	; is returned from a successful open call (sysopen).
 15175                              <1> 	; The i-number of file is obtained via 'rw1' and the data
 15176                              <1> 	; is read into core via 'readi'.
 15177                              <1> 	;
 15178                              <1> 	; Calling sequence:
 15179                              <1> 	;	sysread; buffer; nchars
 15180                              <1> 	; Arguments:
 15181                              <1> 	;	buffer - location of contiguous bytes where 
 15182                              <1> 	;		 input will be placed.
 15183                              <1> 	;	nchars - number of bytes or characters to be read.
 15184                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15185                              <1> 	; Outputs: *u.r0 - number of bytes read.	
 15186                              <1> 	; ...............................................................
 15187                              <1> 	;				
 15188                              <1> 	; Retro UNIX 8086 v1 modification: 
 15189                              <1> 	;       'sysread' system call has three arguments; so,
 15190                              <1> 	;	* 1st argument, file descriptor is in BX register
 15191                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15192                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15193                              <1> 	;
 15194                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15195                              <1> 	;	to the user with number of bytes read. 
 15196                              <1> 	;
 15197 000043CD E83D000000          <1> 	call	rw1
 15198 000043D2 0F82A4FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
 15199                              <1> 		; jsr r0,rw1 / get i-number of file to be read into r1
 15200 000043D8 F6C480              <1> 	test	ah, 80h
 15201                              <1> 		; tst r1 / negative i-number?
 15202 000043DB 0F859BFCFFFF        <1> 	jnz	error
 15203                              <1> 		; ble error1 / yes, error 1 to read
 15204                              <1> 			   ; / it should be positive
 15205 000043E1 E822150000          <1> 	call	readi
 15206                              <1> 		; jsr r0,readi / read data into core
 15207 000043E6 EB18                <1> 	jmp	short rw0
 15208                              <1> 		; br 1f
 15209                              <1> syswrite: ; < write to file >
 15210                              <1> 	; 13/05/2015
 15211                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15212                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15213                              <1> 	;
 15214                              <1> 	; 'syswrite' is given a buffer to write onto an output file
 15215                              <1> 	; and the number of characters to write. If finds the file
 15216                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
 15217                              <1> 	; descriptor is returned from a successful open or create call
 15218                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
 15219                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
 15220                              <1> 	;
 15221                              <1> 	; Calling sequence:
 15222                              <1> 	;	syswrite; buffer; nchars
 15223                              <1> 	; Arguments:
 15224                              <1> 	;	buffer - location of contiguous bytes to be writtten.
 15225                              <1> 	;	nchars - number of characters to be written.
 15226                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15227                              <1> 	; Outputs: *u.r0 - number of bytes written.	
 15228                              <1> 	; ...............................................................
 15229                              <1> 	;				
 15230                              <1> 	; Retro UNIX 8086 v1 modification: 
 15231                              <1> 	;       'syswrite' system call has three arguments; so,
 15232                              <1> 	;	* 1st argument, file descriptor is in BX register
 15233                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15234                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15235                              <1> 	;
 15236                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15237                              <1> 	;	to the user with number of bytes written. 
 15238                              <1> 	;
 15239 000043E8 E822000000          <1> 	call	rw1
 15240 000043ED 0F8289FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
 15241                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
 15242 000043F3 F6C480              <1>         test	ah, 80h
 15243                              <1> 		; tst r1 / positive i-number ?
 15244 000043F6 744E                <1>         jz	short rw3 ; 13/05/2015
 15245                              <1> 	;jz	error
 15246                              <1> 		; bge error1 / yes, error 1 
 15247                              <1> 			   ; / negative i-number means write
 15248 000043F8 66F7D8              <1>         neg	ax
 15249                              <1> 		; neg r1 / make it positive
 15250 000043FB E8FE160000          <1> 	call	writei
 15251                              <1>         	; jsr r0,writei / write data
 15252                              <1> rw0: ; 1:
 15253 00004400 A1[A8740000]        <1>         mov	eax, [u.nread]
 15254 00004405 A3[80740000]        <1> 	mov	[u.r0], eax
 15255                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
 15256                              <1> 				  ; / into (u.r0)
 15257 0000440A E98DFCFFFF          <1> 	jmp	sysret
 15258                              <1>         	; br sysret1
 15259                              <1> rw1:	
 15260                              <1> 	; 14/05/2015
 15261                              <1> 	; 13/05/2015
 15262                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15263                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
 15264                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
 15265                              <1> 	;
 15266                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
 15267                              <1> 				;(in the user's virtual memory space)
 15268                              <1> 	;mov	[u.count], edx 
 15269                              <1> 		; jsr r0,arg; u.base / get buffer pointer
 15270                              <1>         	; jsr r0,arg; u.count / get no. of characters
 15271                              <1> 	;;mov	eax, ebx ; file descriptor
 15272                              <1> 		; mov *u.r0,r1 / put file descriptor 
 15273                              <1> 		             ; / (index to u.fp table) in r1
 15274                              <1> 	; 13/05/2015
 15275 0000440F C705[80740000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
 15276 00004417 0000                <1>
 15277                              <1> 	;
 15278                              <1> 	;; call	getf
 15279                              <1>         ; eBX = File descriptor
 15280 00004419 E8E30A0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
 15281                              <1> 		; jsr r0,getf / get i-number of the file in r1
 15282                              <1> 	; AX = I-number of the file ; negative i-number means write
 15283                              <1> 	; 13/05/2015
 15284 0000441E 6683F801            <1> 	cmp 	ax, 1
 15285 00004422 7217                <1> 	jb	short rw2
 15286                              <1> 	;
 15287 00004424 890D[A0740000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
 15288                              <1> 				;(in the user's virtual memory space)
 15289 0000442A 8915[A4740000]      <1> 	mov	[u.count], edx 
 15290                              <1> 	; 14/05/2015
 15291 00004430 C705[D5740000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
 15292 00004438 0000                <1>
 15293 0000443A C3                  <1> 	retn
 15294                              <1>         	; rts r0
 15295                              <1> rw2:
 15296                              <1> 	; 13/05/2015
 15297 0000443B C705[D5740000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 15298 00004443 0000                <1>
 15299 00004445 C3                  <1> 	retn
 15300                              <1> rw3: 
 15301                              <1> 	; 13/05/2015
 15302 00004446 C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 15303 0000444E 0000                <1>
 15304 00004450 F9                  <1> 	stc
 15305 00004451 C3                  <1> 	retn
 15306                              <1> 
 15307                              <1> sysopen: ;<open file>
 15308                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15309                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
 15310                              <1> 	;
 15311                              <1> 	; 'sysopen' opens a file in following manner:
 15312                              <1> 	;    1) The second argument in a sysopen says whether to
 15313                              <1> 	;	open the file ro read (0) or write (>0).
 15314                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
 15315                              <1> 	;    3) The file is opened by 'iopen'.
 15316                              <1> 	;    4) Next housekeeping is performed on the fsp table
 15317                              <1> 	;	and the user's open file list - u.fp.
 15318                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
 15319                              <1> 	;	b) An entry for the file is created in the fsp table.
 15320                              <1> 	;	c) The number of this entry is put on u.fp list.
 15321                              <1> 	;	d) The file descriptor index to u.fp list is pointed
 15322                              <1> 	;	   to by u.r0.
 15323                              <1> 	;
 15324                              <1> 	; Calling sequence:
 15325                              <1> 	;	sysopen; name; mode
 15326                              <1> 	; Arguments:
 15327                              <1> 	;	name - file name or path name
 15328                              <1> 	;	mode - 0 to open for reading
 15329                              <1> 	;	       1 to open for writing
 15330                              <1> 	; Inputs: (arguments)
 15331                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
 15332                              <1> 	;		  is put into r0's location on the stack.	
 15333                              <1> 	; ...............................................................
 15334                              <1> 	;				
 15335                              <1> 	; Retro UNIX 8086 v1 modification: 
 15336                              <1> 	;       'sysopen' system call has two arguments; so,
 15337                              <1> 	;	* 1st argument, name is pointed to by BX register
 15338                              <1> 	;	* 2nd argument, mode is in CX register
 15339                              <1> 	;
 15340                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15341                              <1> 	;	to the user with the file descriptor/number 
 15342                              <1> 	;	(index to u.fp list).
 15343                              <1> 	;
 15344                              <1> 	;call	arg2
 15345                              <1> 	; * name - 'u.namep' points to address of file/path name
 15346                              <1> 	;          in the user's program segment ('u.segmnt')
 15347                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15348                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15349                              <1> 	;          which is on top of stack.
 15350                              <1> 	;
 15351                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
 15352                              <1> 	;
 15353                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
 15354                              <1> 
 15355 00004452 891D[98740000]      <1> 	mov	[u.namep], ebx
 15356 00004458 6651                <1> 	push	cx
 15357 0000445A E8D90A0000          <1> 	call	namei
 15358                              <1> 		; jsr r0,namei / i-number of file in r1
 15359                              <1>      	;and	ax, ax
 15360                              <1> 	;jz	error ; File not found
 15361 0000445F 723B                <1> 	jc	short fnotfound ; 14/05/2015
 15362                              <1> 	;jc	error ; 27/05/2013
 15363                              <1> 		; br  error2 / file not found
 15364 00004461 665A                <1>    	pop	dx ; mode
 15365 00004463 6652                <1> 	push	dx
 15366                              <1> 	;or	dx, dx
 15367 00004465 08D2                <1> 	or	dl, dl
 15368                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
 15369                              <1> 		         ; / 0 means, open for read)
 15370 00004467 7403                <1> 	jz	short sysopen_0
 15371                              <1> 		; beq 1f / yes, leave i-number positive
 15372                              <1> syscreat_0: ; 27/12/2015
 15373 00004469 66F7D8              <1> 	neg	ax
 15374                              <1>         	; neg r1 / open for writing so make i-number negative
 15375                              <1> sysopen_0: ;1:
 15376 0000446C E8361A0000          <1> 	call	iopen
 15377                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
 15378 00004471 665A                <1> 	pop	dx
 15379                              <1> 	;and	dx, dx
 15380 00004473 20D2                <1> 	and	dl, dl
 15381                              <1>         	; tst (sp)+ / pop the stack and test the mode
 15382 00004475 7403                <1> 	jz	short sysopen_2
 15383                              <1>         	; beq op1 / is open for read op1
 15384                              <1> sysopen_1: ;op0:
 15385 00004477 66F7D8              <1> 	neg	ax
 15386                              <1>         	; neg r1 
 15387                              <1> 		     ;/ make i-number positive if open for writing [???]
 15388                              <1> 	;; NOTE: iopen always make i-number positive.
 15389                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
 15390                              <1> sysopen_2: ;op1:
 15391 0000447A 31F6                <1>         xor     esi, esi
 15392                              <1>         	; clr r2 / clear registers
 15393 0000447C 31DB                <1>         xor     ebx, ebx
 15394                              <1> 		; clr r3
 15395                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
 15396 0000447E 389E[86740000]      <1>         cmp     [esi+u.fp], bl ; 0
 15397                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
 15398 00004484 7625                <1>         jna      short sysopen_4
 15399                              <1> 		; beq 1f / if byte in list is 0 branch
 15400 00004486 46                  <1>         inc     esi
 15401                              <1> 		; inc r2 / bump r2 so next byte can be checked
 15402 00004487 6683FE0A            <1>         cmp     si, 10
 15403                              <1> 		; cmp r2,$10. / reached end of list?
 15404 0000448B 72F1                <1> 	jb	short sysopen_3
 15405                              <1> 		; blt 1b / no, go back
 15406                              <1> toomanyf:
 15407                              <1> 	; 14/05/2015
 15408 0000448D C705[D5740000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
 15409 00004495 0000                <1>
 15410 00004497 E9E0FBFFFF          <1> 	jmp	error
 15411                              <1>         	; br error2 / yes, error (no files open)
 15412                              <1> fnotfound: 
 15413                              <1> 	; 14/05/2015
 15414 0000449C C705[D5740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
 15415 000044A4 0000                <1>
 15416 000044A6 E9D1FBFFFF          <1> 	jmp	error
 15417                              <1> 
 15418                              <1> sysopen_4: ; 1:
 15419 000044AB 6683BB[56720000]00  <1>         cmp     word [ebx+fsp], 0
 15420                              <1> 		; tst fsp(r3) / scan fsp entries
 15421 000044B3 7610                <1>         jna     short sysopen_5
 15422                              <1> 		; beq 1f / if 0 branch
 15423                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
 15424 000044B5 6683C30A            <1>         add     bx, 10 ; fsp structure size = 10 bytes/entry
 15425                              <1> 		; add $8.,r3 / add 8 to r3 
 15426                              <1> 			; / to bump it to next entry mfsp table
 15427 000044B9 6681FBF401          <1>         cmp     bx, nfiles*10
 15428                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
 15429 000044BE 72EB                <1> 	jb	short sysopen_4
 15430                              <1>        		; blt 1b / no, back
 15431 000044C0 E9B7FBFFFF          <1> 	jmp	error
 15432                              <1>         	; br error2 / yes, error
 15433                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
 15434 000044C5 668983[56720000]    <1>         mov     [ebx+fsp], ax
 15435                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
 15436                              <1> 			; / into next available entry in fsp table,
 15437 000044CC 668B3D[66740000]    <1> 	mov	di, [cdev] ; word ? byte ?
 15438 000044D3 6689BB[58720000]    <1>         mov     [ebx+fsp+2], di ; device number
 15439                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
 15440 000044DA 31FF                <1>         xor	edi, edi
 15441 000044DC 89BB[5A720000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
 15442                              <1> 		; clr fsp+4(r3)
 15443 000044E2 6689BB[5E720000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
 15444                              <1>        		; clr fsp+6(r3) / clear the next two words
 15445 000044E9 89D8                <1>   	mov	eax, ebx
 15446 000044EB B30A                <1> 	mov	bl, 10
 15447 000044ED F6F3                <1> 	div	bl 
 15448                              <1> 		; asr r3
 15449                              <1> 		; asr r3 / divide by 8 
 15450                              <1> 		; asr r3 ; / to get number of the fsp entry-1
 15451 000044EF FEC0                <1> 	inc	al
 15452                              <1>         	; inc r3 / add 1 to get fsp entry number
 15453 000044F1 8886[86740000]      <1>         mov     [esi+u.fp], al
 15454                              <1> 		; movb r3,u.fp(r2) / move entry number into 
 15455                              <1> 			; / next available slot in u.fp list
 15456 000044F7 8935[80740000]      <1>         mov     [u.r0], esi
 15457                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
 15458                              <1> 			     ; / into r0 loc on stack
 15459 000044FD E99AFBFFFF          <1>         jmp	sysret
 15460                              <1> 		; br sysret2
 15461                              <1> 
 15462                              <1> 	;
 15463                              <1> 	; 'fsp' table (10 bytes/entry)
 15464                              <1> 	; bit 15				   bit 0
 15465                              <1> 	; ---|-------------------------------------------
 15466                              <1> 	; r/w|		i-number of open file
 15467                              <1> 	; ---|-------------------------------------------
 15468                              <1> 	;		   device number
 15469                              <1> 	; -----------------------------------------------
 15470                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 15471                              <1> 	; -----------------------------------------------
 15472                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 15473                              <1> 	; ----------------------|------------------------
 15474                              <1> 	;  flag that says file 	| number of processes
 15475                              <1> 	;   has been deleted	| that have file open 
 15476                              <1> 	; ----------------------|------------------------
 15477                              <1> 	;
 15478                              <1> 
 15479                              <1> syscreat: ; < create file >
 15480                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
 15481                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15482                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
 15483                              <1> 	;
 15484                              <1> 	; 'syscreat' called with two arguments; name and mode.
 15485                              <1> 	; u.namep points to name of the file and mode is put
 15486                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
 15487                              <1> 	; If the file aready exists, it's mode and owner remain 
 15488                              <1> 	; unchanged, but it is truncated to zero length. If the file
 15489                              <1> 	; did not exist, an i-node is created with the new mode via
 15490                              <1> 	; 'maknod' whether or not the file already existed, it is
 15491                              <1> 	; open for writing. The fsp table is then searched for a free
 15492                              <1> 	; entry. When a free entry is found, proper data is placed
 15493                              <1> 	; in it and the number of this entry is put in the u.fp list.
 15494                              <1> 	; The index to the u.fp (also know as the file descriptor)
 15495                              <1> 	; is put in the user's r0. 			
 15496                              <1> 	;
 15497                              <1> 	; Calling sequence:
 15498                              <1> 	;	syscreate; name; mode
 15499                              <1> 	; Arguments:
 15500                              <1> 	;	name - name of the file to be created
 15501                              <1> 	;	mode - mode of the file to be created
 15502                              <1> 	; Inputs: (arguments)
 15503                              <1> 	; Outputs: *u.r0 - index to u.fp list 
 15504                              <1> 	;		   (the file descriptor of new file)
 15505                              <1> 	; ...............................................................
 15506                              <1> 	;				
 15507                              <1> 	; Retro UNIX 8086 v1 modification: 
 15508                              <1> 	;       'syscreate' system call has two arguments; so,
 15509                              <1> 	;	* 1st argument, name is pointed to by BX register
 15510                              <1> 	;	* 2nd argument, mode is in CX register
 15511                              <1> 	;
 15512                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15513                              <1> 	;	to the user with the file descriptor/number 
 15514                              <1> 	;	(index to u.fp list).
 15515                              <1> 	;
 15516                              <1> 	;call	arg2
 15517                              <1> 	; * name - 'u.namep' points to address of file/path name
 15518                              <1> 	;          in the user's program segment ('u.segmnt')
 15519                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15520                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15521                              <1> 	;          which is on top of stack.
 15522                              <1> 	;
 15523                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
 15524                              <1> 			    ; / on stack
 15525 00004502 891D[98740000]      <1> 	mov	[u.namep], ebx ; file name address
 15526 00004508 6651                <1> 	push	cx ; mode
 15527 0000450A E8290A0000          <1> 	call 	namei        	
 15528                              <1> 		; jsr r0,namei / get the i-number
 15529                              <1>         ;and	ax, ax
 15530                              <1> 	;jz	short syscreat_1	       	
 15531 0000450F 721E                <1> 	jc	short syscreat_1
 15532                              <1> 		; br  2f / if file doesn't exist 2f
 15533                              <1> 	; 27/12/2015
 15534 00004511 6683F829            <1> 	cmp	ax, 41 ; device inode ?
 15535 00004515 0F824EFFFFFF        <1>         jb      syscreat_0 ; yes
 15536                              <1> 	;
 15537 0000451B 66F7D8              <1> 	neg 	ax
 15538                              <1>         	; neg r1 / if file already exists make i-number 
 15539                              <1> 		       ; / negative (open for writing)
 15540 0000451E E884190000          <1> 	call	iopen
 15541                              <1>         	; jsr r0,iopen /
 15542 00004523 E835130000          <1> 	call	itrunc
 15543                              <1>         	; jsr r0,itrunc / truncate to 0 length
 15544 00004528 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
 15545 0000452A E948FFFFFF          <1>         jmp     sysopen_1
 15546                              <1>         	; br op0
 15547                              <1> syscreat_1: ; 2: / file doesn't exist
 15548 0000452F 6658                <1> 	pop	ax
 15549                              <1>         	; mov (sp)+,r1 / put the mode in r1
 15550 00004531 30E4                <1> 	xor	ah, ah	
 15551                              <1>         	; bic $!377,r1 / clear upper byte
 15552 00004533 E8D30C0000          <1> 	call 	maknod
 15553                              <1>         	; jsr r0,maknod / make an i-node for this file
 15554 00004538 66A1[B2740000]      <1> 	mov	ax, [u.dirbuf]
 15555                              <1>         	; mov u.dirbuf,r1 / put i-number 
 15556                              <1> 			        ; / for this new file in r1
 15557 0000453E E934FFFFFF          <1>         jmp     sysopen_1
 15558                              <1>         	; br op0 / open the file
 15559                              <1> 
 15560                              <1> sysmkdir: ; < make directory >
 15561                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15562                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 15563                              <1> 	;
 15564                              <1> 	; 'sysmkdir' creates an empty directory whose name is
 15565                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
 15566                              <1> 	; The special entries '.' and '..' are not present.
 15567                              <1> 	; Errors are indicated if the directory already exists or		
 15568                              <1> 	; user is not the super user. 
 15569                              <1> 	;
 15570                              <1> 	; Calling sequence:
 15571                              <1> 	;	sysmkdir; name; mode
 15572                              <1> 	; Arguments:
 15573                              <1> 	;	name - points to the name of the directory
 15574                              <1> 	;	mode - mode of the directory
 15575                              <1> 	; Inputs: (arguments)
 15576                              <1> 	; Outputs: -
 15577                              <1> 	;    (sets 'directory' flag to 1; 
 15578                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
 15579                              <1> 	; ...............................................................
 15580                              <1> 	;				
 15581                              <1> 	; Retro UNIX 8086 v1 modification: 
 15582                              <1> 	;       'sysmkdir' system call has two arguments; so,
 15583                              <1> 	;	* 1st argument, name is pointed to by BX register
 15584                              <1> 	;	* 2nd argument, mode is in CX register
 15585                              <1> 	;
 15586                              <1> 		
 15587                              <1> ; / make a directory
 15588                              <1> 
 15589                              <1> 	;call	arg2
 15590                              <1> 	; * name - 'u.namep' points to address of file/path name
 15591                              <1> 	;          in the user's program segment ('u.segmnt')
 15592                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15593                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15594                              <1> 	;          which is on top of stack.
 15595                              <1> 
 15596                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
 15597                              <1> 			    ; / on stack
 15598 00004543 891D[98740000]      <1> 	mov	[u.namep], ebx
 15599 00004549 6651                <1> 	push	cx ; mode
 15600 0000454B E8E8090000          <1> 	call	namei
 15601                              <1>         	; jsr r0,namei / get the i-number
 15602                              <1>         	;     br .+4 / if file not found branch around error
 15603                              <1>         ;xor 	ax, ax
 15604                              <1> 	;jnz	error
 15605 00004550 731C                <1> 	jnc	short dir_exists ; 14/05/2015
 15606                              <1> 	;jnc	error	
 15607                              <1> 		; br  error2 / directory already exists (error)
 15608 00004552 803D[CC740000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 15609                              <1>         	;tstb u.uid / is user the super user
 15610 00004559 7622                <1> 	jna	short dir_access_err ; 14/05/2015
 15611                              <1> 	;jna	error
 15612                              <1>         	;bne error2 / no, not allowed
 15613 0000455B 6658                <1> 	pop	ax
 15614                              <1>         	;mov (sp)+,r1 / put the mode in r1
 15615 0000455D 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
 15616                              <1>         	;bic $!317,r1 / all but su and ex
 15617                              <1> 	;or	ax , 4000h ; 1011111111111111b
 15618 00004561 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
 15619                              <1>         	;bis $40000,r1 / directory flag
 15620 00004564 E8A20C0000          <1> 	call	maknod
 15621                              <1>         	;jsr r0,maknod / make the i-node for the directory
 15622 00004569 E92EFBFFFF          <1> 	jmp	sysret
 15623                              <1>         	;br sysret2 /
 15624                              <1> dir_exists:
 15625                              <1> 	; 14/05/2015
 15626 0000456E C705[D5740000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
 15627 00004576 0000                <1>
 15628 00004578 E9FFFAFFFF          <1> 	jmp	error
 15629                              <1> dir_access_err:
 15630                              <1> 	; 14/05/2015
 15631 0000457D C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 15632 00004585 0000                <1>
 15633 00004587 E9F0FAFFFF          <1> 	jmp	error
 15634                              <1> 
 15635                              <1> sysclose: ;<close file>
 15636                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15637                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
 15638                              <1> 	;
 15639                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
 15640                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
 15641                              <1> 	; is put in r1 and 'fclose' is called.
 15642                              <1> 	;
 15643                              <1> 	; Calling sequence:
 15644                              <1> 	;	sysclose
 15645                              <1> 	; Arguments:
 15646                              <1> 	;	-  
 15647                              <1> 	; Inputs: *u.r0 - file descriptor
 15648                              <1> 	; Outputs: -
 15649                              <1> 	; ...............................................................
 15650                              <1> 	;				
 15651                              <1> 	; Retro UNIX 8086 v1 modification:
 15652                              <1> 	;	 The user/application program puts file descriptor
 15653                              <1> 	;        in BX register as 'sysclose' system call argument.
 15654                              <1> 	; 	 (argument transfer method 1)
 15655                              <1> 
 15656                              <1> 	; / close the file
 15657                              <1> 	
 15658 0000458C 89D8                <1> 	mov 	eax, ebx
 15659 0000458E E823090000          <1> 	call 	fclose
 15660                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
 15661                              <1> 		; jsr r0,fclose / close the file
 15662                              <1>                	; br error2 / unknown file descriptor
 15663                              <1> 		; br sysret2
 15664                              <1> 	; 14/05/2015
 15665 00004593 0F8303FBFFFF        <1> 	jnc	sysret
 15666 00004599 C705[D5740000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 15667 000045A1 0000                <1>
 15668 000045A3 E9D4FAFFFF          <1> 	jmp	error
 15669                              <1> 
 15670                              <1> sysemt:
 15671                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15672                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
 15673                              <1> 	;
 15674                              <1> 	; Retro UNIX 8086 v1 modification: 
 15675                              <1> 	;	'Enable Multi Tasking'  system call instead 
 15676                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
 15677                              <1> 	;
 15678                              <1> 	; Retro UNIX 8086 v1 feature only!
 15679                              <1> 	;	Using purpose: Kernel will start without time-out
 15680                              <1> 	;	(internal clock/timer) functionality.
 15681                              <1> 	;	Then etc/init will enable clock/timer for
 15682                              <1> 	;	multi tasking. (Then it will not be disabled again
 15683                              <1> 	;	except hardware reset/restart.)
 15684                              <1> 	;
 15685                              <1> 
 15686 000045A8 803D[CC740000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
 15687                              <1> 	;ja	error
 15688 000045AF 0F8770FBFFFF        <1> 	ja	badsys ; 14/05/2015
 15689                              <1> emt_0:
 15690 000045B5 FA                  <1> 	cli
 15691 000045B6 21DB                <1> 	and	ebx, ebx
 15692 000045B8 7410                <1> 	jz	short emt_2
 15693                              <1> 	; Enable multi tasking -time sharing-
 15694 000045BA B8[BF540000]        <1> 	mov	eax, clock
 15695                              <1> emt_1:
 15696 000045BF A3[1B080000]        <1> 	mov	[x_timer], eax
 15697 000045C4 FB                  <1> 	sti
 15698 000045C5 E9D2FAFFFF          <1> 	jmp	sysret
 15699                              <1> emt_2:
 15700                              <1> 	; Disable multi tasking -time sharing-
 15701 000045CA B8[23080000]        <1> 	mov	eax, u_timer
 15702 000045CF EBEE                <1> 	jmp	short emt_1
 15703                              <1> 
 15704                              <1> 	; Original UNIX v1 'sysemt' routine
 15705                              <1> ;sysemt:
 15706                              <1>         ;
 15707                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
 15708                              <1> 			 ; / in loc 30
 15709                              <1>         ;cmp    30,$core / was the argument a lower address 
 15710                              <1> 			; / than core
 15711                              <1>         ;blo    1f / yes, rtssym
 15712                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
 15713                              <1> 			; / and less than "ecore"
 15714                              <1>         ;blo    2f / yes, sysret2
 15715                              <1> ;1:
 15716                              <1>         ;mov    $rtssym,30
 15717                              <1> ;2:
 15718                              <1>         ;br     sysret2
 15719                              <1> 
 15720                              <1> sysilgins:
 15721                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15722                              <1> 	; 03/06/2013
 15723                              <1> 	; Retro UNIX 8086 v1 modification: 
 15724                              <1> 	;	not a valid system call ! (not in use)
 15725                              <1> 	;
 15726 000045D1 E94FFBFFFF          <1> 	jmp	badsys
 15727                              <1> 	;jmp	error
 15728                              <1> 	;;jmp 	sysret
 15729                              <1> 
 15730                              <1> 	; Original UNIX v1 'sysemt' routine
 15731                              <1> ;sysilgins: / calculate proper illegal instruction trap address
 15732                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
 15733                              <1> 			  ;/ put it in loc 8.,
 15734                              <1>         ;cmp    10,$core / making it the illegal instruction 
 15735                              <1> 		       ; / trap address
 15736                              <1>         ;blo    1f / is the address a user core address?  
 15737                              <1> 		; / yes, go to 2f
 15738                              <1>         ;cmp    10,$ecore
 15739                              <1>         ;blo    2f
 15740                              <1> ;1:
 15741                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
 15742                              <1> 		    ; / instruction trap address for the system
 15743                              <1> ;2:
 15744                              <1>         ;br     sysret2 / return to the caller via 'sysret'
 15745                              <1> 
 15746                              <1> sysmdate: ; < change the modification time of a file >
 15747                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 15748                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 15749                              <1> 	;
 15750                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
 15751                              <1> 	; file into core. The user is checked if he is the owner 
 15752                              <1> 	; or super user. If he is neither an error occurs.
 15753                              <1> 	; 'setimod' is then called to set the i-node modification
 15754                              <1> 	; byte and the modification time, but the modification time
 15755                              <1> 	; is overwritten by whatever get put on the stack during
 15756                              <1> 	; a 'systime' system call. This calls are restricted to
 15757                              <1> 	; the super user.		
 15758                              <1> 	;
 15759                              <1> 	; Calling sequence:
 15760                              <1> 	;	sysmdate; name
 15761                              <1> 	; Arguments:
 15762                              <1> 	;	name - points to the name of file
 15763                              <1> 	; Inputs: (arguments)
 15764                              <1> 	; Outputs: -
 15765                              <1> 	; ...............................................................
 15766                              <1> 	;				
 15767                              <1> 	; Retro UNIX 8086 v1 modification: 
 15768                              <1> 	;	 The user/application program puts address 
 15769                              <1> 	;	 of the file name in BX register 
 15770                              <1> 	;	 as 'sysmdate' system call argument.
 15771                              <1> 	;
 15772                              <1> ; / change the modification time of a file
 15773                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
 15774 000045D6 891D[98740000]      <1>         mov	[u.namep], ebx
 15775 000045DC E857090000          <1> 	call	namei
 15776                              <1> 		; jsr r0,namei / get its i-number
 15777 000045E1 0F82B5FEFFFF        <1>         jc	fnotfound ; file not found !
 15778                              <1> 	;jc	error       
 15779                              <1> 		; br error2 / no, such file
 15780 000045E7 E83C110000          <1> 	call	iget
 15781                              <1> 		; jsr r0,iget / get i-node into core
 15782 000045EC A0[CC740000]        <1> 	mov	al, [u.uid]
 15783 000045F1 3A05[59710000]      <1> 	cmp	al, [i.uid]
 15784                              <1>         	; cmpb u.uid,i.uid / is user same as owner
 15785 000045F7 7413                <1> 	je	short mdate_1
 15786                              <1>         	; beq 1f / yes
 15787 000045F9 20C0                <1> 	and	al, al
 15788                              <1> 		; tstb u.uid / no, is user the super user
 15789                              <1> 	;jnz	error
 15790                              <1> 		; bne error2 / no, error
 15791 000045FB 740F                <1> 	jz	short mdate_1
 15792 000045FD C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 15793 00004605 0000                <1>
 15794 00004607 E970FAFFFF          <1> 	jmp	error
 15795                              <1> mdate_1: ;1:
 15796 0000460C E82A120000          <1> 	call	setimod
 15797                              <1>         	; jsr r0,setimod / fill in modification data,
 15798                              <1> 		               ; / time etc.
 15799 00004611 BE[F0700000]        <1> 	mov	esi, p_time
 15800 00004616 BF[70710000]        <1> 	mov	edi, i.mtim
 15801 0000461B A5                  <1> 	movsd
 15802                              <1> 		; mov 4(sp),i.mtim / move present time to
 15803                              <1>         	; mov 2(sp),i.mtim+2 / modification time
 15804 0000461C E97BFAFFFF          <1>         jmp	sysret
 15805                              <1> 		; br sysret2
 15806                              <1> 
 15807                              <1> sysstty: ; < set tty status and mode >
 15808                              <1> 	; 17/11/2015
 15809                              <1> 	; 12/11/2015
 15810                              <1> 	; 29/10/2015
 15811                              <1> 	; 17/10/2015
 15812                              <1> 	; 13/10/2015
 15813                              <1> 	; 29/06/2015
 15814                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
 15815                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 15816                              <1> 	;
 15817                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
 15818                              <1> 	; whose file descriptor is in (u.r0).
 15819                              <1> 	;
 15820                              <1> 	; Calling sequence:
 15821                              <1> 	;	sysstty; arg
 15822                              <1> 	; Arguments:
 15823                              <1> 	;	arg - address of 3 consequitive words that contain
 15824                              <1> 	;	      the source of status data	
 15825                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
 15826                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 15827                              <1> 	; ...............................................................
 15828                              <1> 	;	
 15829                              <1> 	; Retro UNIX 8086 v1 modification: 
 15830                              <1> 	;	'sysstty' system call will set the tty
 15831                              <1> 	;	(clear keyboard buffer and set cursor position)
 15832                              <1> 	;	 in following manner:
 15833                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
 15834                              <1> 	;
 15835                              <1> 	; Inputs:
 15836                              <1> 	;	BX = 0 --> means
 15837                              <1> 	;	   If CL = FFh
 15838                              <1> 	;	      set cursor position for console tty, only 
 15839                              <1> 	;	      CH will be ignored (char. will not be written)	
 15840                              <1> 	;	   If CH = 0 (CL < FFh)
 15841                              <1> 	;	      set console tty for (current) process
 15842                              <1> 	;	      CL = tty number (0 to 9)
 15843                              <1> 	;	      (If CH = 0, character will not be written)			
 15844                              <1> 	;          If CH > 0 (CL < FFh)	
 15845                              <1> 	;             CL = tty number (0 to 9)
 15846                              <1> 	;	      CH = character will be written
 15847                              <1> 	;	        at requested cursor position (in DX)	
 15848                              <1> 	;	   DX = cursor position for tty number 0 to 7.	
 15849                              <1>   	;		(only tty number 0 to 7) 
 15850                              <1> 	;          DL = communication parameters (for serial ports) 
 15851                              <1> 	;	        (only for COM1 and COM2 serial ports)
 15852                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
 15853                              <1> 	;			or set cursor position	
 15854                              <1> 	;	   DH = 0FFh -> DL is not valid
 15855                              <1> 	;		do not set serial port parameters 
 15856                              <1> 	;		or do not set cursor position
 15857                              <1> 	;
 15858                              <1> 	;	BX > 0 --> points to name of tty
 15859                              <1> 	;    	   CH > 0 -->
 15860                              <1> 	;		CH = character will be written in current 
 15861                              <1> 	;            	cursor position (for tty number from 0 to 7)
 15862                              <1> 	;	     	or character will be sent to serial port
 15863                              <1> 	;	     	(for tty number 8 or 9)
 15864                              <1> 	;		CL = color of the character if tty number < 8.
 15865                              <1> 	;    	   CH = 0 --> Do not write a character, 
 15866                              <1> 	;		set mode (tty 8 to 9) or 
 15867                              <1> 	;		set current cursor positions (tty 0 to 7) only. 
 15868                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
 15869                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
 15870                              <1> 	;		(DL is not valid)
 15871                              <1> 	;	   DL = communication parameters 
 15872                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
 15873                              <1> 	; Outputs:
 15874                              <1> 	;	cf = 0 -> OK
 15875                              <1> 	;	     AL = tty number (0 to 9)
 15876                              <1> 	;	     AH = line status if tty number is 8 or 9
 15877                              <1> 	;	     AH = process number (of the caller) 	
 15878                              <1> 	;	cf = 1 means error (requested tty is not ready)
 15879                              <1> 	;	     AH = FFh if the tty is locked 
 15880                              <1> 	;		  (owned by another process)
 15881                              <1> 	;	        = process number (of the caller) 
 15882                              <1> 	;		  (if < FFh and tty number < 8)
 15883                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 15884                              <1> 	;	     AH = line status if tty number is 8 or 9
 15885                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
 15886                              <1> 	;
 15887                              <1> 	; 27/06/2015 (32 bit modifications)
 15888                              <1> 	; 14/01/2014
 15889 00004621 31C0                <1> 	xor 	eax, eax
 15890 00004623 6648                <1> 	dec	ax ; 17/10/2015
 15891 00004625 A3[80740000]        <1> 	mov	[u.r0], eax ; 0FFFFh
 15892 0000462A 21DB                <1> 	and	ebx, ebx
 15893 0000462C 0F85CB000000        <1>         jnz     sysstty_6
 15894                              <1> ; set console tty
 15895                              <1> 	; 29/10/2015
 15896                              <1> 	; 17/01/2014 
 15897 00004632 80F909              <1> 	cmp	cl, 9
 15898 00004635 7613                <1> 	jna	short sysstty_0
 15899                              <1> 	; 17/11/2015
 15900 00004637 80F9FF              <1> 	cmp	cl, 0FFh
 15901 0000463A 7202                <1> 	jb	short sysstty_13
 15902 0000463C 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
 15903                              <1> sysstty_13:
 15904 0000463E 8A1D[CF740000]      <1> 	mov	bl, [u.uno] ; process number
 15905 00004644 8A8B[D5710000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
 15906                              <1> sysstty_0:
 15907                              <1> 	; 29/06/2015
 15908 0000464A 6652                <1> 	push	dx
 15909 0000464C 6651                <1> 	push	cx
 15910 0000464E 30D2                <1> 	xor 	dl, dl	; sysstty call sign
 15911 00004650 88C8                <1> 	mov	al, cl
 15912 00004652 A2[80740000]        <1> 	mov	[u.r0], al ; tyy number (0 to 9)
 15913 00004657 E8E5180000          <1> 	call	ottyp
 15914 0000465C 6659                <1> 	pop	cx
 15915 0000465E 665A                <1> 	pop	dx
 15916                              <1> 	;
 15917 00004660 7257                <1> 	jc	short sysstty_pd_err
 15918                              <1> 	;
 15919 00004662 80F908              <1> 	cmp	cl, 8
 15920 00004665 7222                <1> 	jb	short sysstty_2
 15921                              <1> 	;
 15922 00004667 80FEFF              <1> 	cmp	dh, 0FFh
 15923 0000466A 741D                <1> 	je	short sysstty_2
 15924                              <1> 		; set communication parameters for serial ports
 15925                              <1> 	; 29/10/2015
 15926 0000466C 88D4                <1> 	mov	ah, dl ; communication parameters
 15927                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
 15928                              <1> 		;			 THRE int + RDA int 
 15929                              <1> 		; ah = 23h = 00100011b = 9600 baud,
 15930                              <1> 		;			 THRE int + RDA int 
 15931 0000466E 28C0                <1> 	sub	al, al ; 0
 15932                              <1> 	; 12/07/2014
 15933 00004670 80F909              <1> 	cmp	cl, 9
 15934 00004673 7202                <1> 	jb	short sysstty_1
 15935 00004675 FEC0                <1> 	inc	al
 15936                              <1> sysstty_1:
 15937 00004677 6651                <1> 	push	cx
 15938                              <1> 	; 29/06/2015	
 15939 00004679 E8ABF4FFFF          <1> 	call 	sp_setp ; Set serial port communication parameters
 15940 0000467E 66890D[81740000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
 15941                              <1> 			     ; Modem status (EAX bits 16 to 23)
 15942 00004685 6659                <1> 	pop	cx
 15943 00004687 7265                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 15944                              <1> sysstty_2:
 15945                              <1> 	; 17/01/2014
 15946 00004689 20ED                <1> 	and	ch, ch 	; set cursor position 
 15947                              <1> 			; or comm. parameters ONLY
 15948 0000468B 750D                <1> 	jnz	short sysstty_3
 15949 0000468D 0FB61D[CF740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 15950 00004694 888B[D5710000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
 15951                              <1> sysstty_3:
 15952                              <1> 	; 16/01/2014
 15953 0000469A 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
 15954                              <1> 	; 17/11/2015
 15955 0000469C B507                <1> 	mov 	ch, 7  ; Default color (light gray)
 15956 0000469E 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
 15957 000046A0 0F86C5000000        <1>         jna     sysstty_9
 15958                              <1> sysstty_12:
 15959                              <1> 	;; BX = 0, CL = 8 or CL = 9
 15960                              <1> 	; (Set specified serial port as console tty port)
 15961                              <1> 	; CH = character to be written
 15962                              <1> 	; 15/04/2014
 15963                              <1> 	; CH = 0 --> initialization only
 15964                              <1> 	; AL = character
 15965                              <1> 	; 26/06/2014
 15966 000046A6 880D[D4740000]      <1> 	mov	[u.ttyn], cl
 15967                              <1> 	; 12/07/2014
 15968 000046AC 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
 15969 000046AE 20C0                <1> 	and	al, al
 15970 000046B0 7416                <1> 	jz	short sysstty_4 ; al = ch = 0
 15971                              <1>  	; 04/07/2014
 15972 000046B2 E8981E0000          <1> 	call 	sndc
 15973                              <1> 	; 12/07/2014
 15974 000046B7 EB1B                <1> 	jmp	short sysstty_5
 15975                              <1> sysstty_pd_err: ; 29/06/2015
 15976                              <1> 	; 'permission denied !' error
 15977 000046B9 C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
 15978 000046C1 0000                <1>
 15979 000046C3 E9B4F9FFFF          <1> 	jmp	error
 15980                              <1> sysstty_4:
 15981                              <1> 	; 12/07/2014
 15982                              <1> 	;xchg 	ah, al	; al = 0 -> al = ah, ah = 0
 15983 000046C8 88E0                <1> 	mov	al, ah ; 29/06/2015
 15984 000046CA 2C08                <1> 	sub	al, 8
 15985                              <1> 	; 27/06/2015
 15986 000046CC E850F4FFFF          <1> 	call	sp_status ; get serial port status
 15987                              <1> 	; AL = Line status, AH = Modem status
 15988                              <1> 	; 12/11/2015
 15989 000046D1 3C80                <1> 	cmp	al, 80h
 15990 000046D3 F5                  <1> 	cmc
 15991                              <1> sysstty_5:
 15992 000046D4 66A3[81740000]      <1> 	mov	[u.r0+1], ax ; ah = line status
 15993                              <1> 		     ; EAX bits 16-23 = modem status	
 15994 000046DA 9C                  <1> 	pushf
 15995 000046DB 30D2                <1> 	xor	dl, dl ; sysstty call sign
 15996 000046DD A0[D4740000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
 15997 000046E2 E86D190000          <1> 	call	cttyp
 15998 000046E7 9D                  <1> 	popf
 15999 000046E8 0F83AEF9FFFF        <1> 	jnc	sysret	; time out error 
 16000                              <1> 
 16001                              <1> sysstty_tmout_err:
 16002 000046EE C705[D5740000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
 16003 000046F6 0000                <1>
 16004 000046F8 E97FF9FFFF          <1> 	jmp	error
 16005                              <1> sysstty_6:
 16006 000046FD 6652                <1> 	push	dx
 16007 000046FF 6651                <1> 	push	cx
 16008 00004701 891D[98740000]      <1> 	mov	[u.namep], ebx
 16009 00004707 E82C080000          <1> 	call	namei
 16010 0000470C 6659                <1> 	pop	cx
 16011 0000470E 665A                <1> 	pop	dx
 16012 00004710 720E                <1> 	jc	short sysstty_inv_dn
 16013                              <1> 	;
 16014 00004712 6683F813            <1> 	cmp	ax, 19  ; inode number of /dev/COM2
 16015 00004716 7708                <1> 	ja	short sysstty_inv_dn ; 27/06/2015
 16016                              <1> 	;
 16017 00004718 3C0A                <1> 	cmp	al, 10 ; /dev/tty0 .. /dev/tty7
 16018                              <1> 		       ; /dev/COM1, /dev/COM2
 16019 0000471A 7213                <1> 	jb	short sysstty_7
 16020 0000471C 2C0A                <1> 	sub	al, 10
 16021 0000471E EB20                <1> 	jmp	short sysstty_8
 16022                              <1> sysstty_inv_dn: 
 16023                              <1> 	; 27/06/2015
 16024                              <1> 	; Invalid device name (not a tty) ! error
 16025                              <1> 	; (Device is not a tty or device name not found)
 16026 00004720 C705[D5740000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 16027 00004728 0000                <1>
 16028 0000472A E94DF9FFFF          <1> 	jmp	error 
 16029                              <1> sysstty_7:
 16030 0000472F 3C01                <1> 	cmp	al, 1 ; /dev/tty
 16031 00004731 75ED                <1> 	jne	short sysstty_inv_dn ; 27/06/2015
 16032 00004733 0FB61D[CF740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 16033 0000473A 8A83[D5710000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
 16034                              <1> sysstty_8:	
 16035 00004740 A2[80740000]        <1> 	mov	[u.r0], al
 16036 00004745 6652                <1> 	push	dx
 16037 00004747 6650                <1> 	push	ax
 16038 00004749 6651                <1> 	push	cx	
 16039 0000474B E8F1170000          <1> 	call	ottyp
 16040 00004750 6659                <1> 	pop	cx
 16041 00004752 6658                <1> 	pop	ax
 16042 00004754 665A                <1> 	pop	dx
 16043 00004756 0F825DFFFFFF        <1>         jc      sysstty_pd_err ; 'permission denied !'
 16044                              <1> 	; 29/10/2015
 16045 0000475C 86E9                <1> 	xchg 	ch, cl
 16046                              <1> 		; cl = character, ch = color code
 16047 0000475E 86C1                <1> 	xchg	al, cl
 16048                              <1> 		; al = character, cl = tty number
 16049 00004760 80F907              <1> 	cmp	cl, 7
 16050 00004763 0F873DFFFFFF        <1>         ja      sysstty_12
 16051                              <1> 	;
 16052                              <1> 	; 16/01/2014
 16053 00004769 30FF                <1> 	xor	bh, bh
 16054                              <1> 	;
 16055                              <1> sysstty_9: 	; tty 0 to tty 7
 16056                              <1> 	; al = character
 16057 0000476B 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
 16058 0000476E 740F                <1> 	je	short sysstty_10
 16059 00004770 6651                <1> 	push	cx
 16060 00004772 6650                <1> 	push	ax	
 16061                              <1> 	; movzx, ebx, cl
 16062 00004774 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
 16063 00004776 E8C6CEFFFF          <1> 	call	set_cpos
 16064 0000477B 6658                <1> 	pop	ax
 16065 0000477D 6659                <1> 	pop	cx
 16066                              <1> sysstty_10: 
 16067                              <1> 	; 29/10/2015
 16068 0000477F 08C0                <1> 	or	al, al ; character
 16069 00004781 740F                <1> 	jz      short sysstty_11 ; al = 0
 16070                              <1> 	; 17/11/2015
 16071 00004783 3CFF                <1> 	cmp	al, 0FFh
 16072 00004785 730B                <1> 	jnb	short sysstty_11
 16073                              <1> 		; ch > 0 and ch < FFh
 16074                              <1> 	; write a character at current cursor position
 16075 00004787 88EC                <1> 	mov	ah, ch ; color/attribute
 16076                              <1> 	; 12/07/2014
 16077 00004789 6651                <1> 	push	cx
 16078 0000478B E8FCCFFFFF          <1> 	call	write_c_current
 16079 00004790 6659                <1> 	pop	cx
 16080                              <1> sysstty_11:
 16081                              <1> 	; 14/01/2014
 16082 00004792 30D2                <1> 	xor	dl, dl ; sysstty call sign
 16083                              <1> 	; 18/01/2014
 16084                              <1> 	;movzx	eax, cl ; 27/06/2015
 16085 00004794 88C8                <1> 	mov	al, cl
 16086 00004796 E8B9180000          <1> 	call	cttyp
 16087 0000479B E9FCF8FFFF          <1> 	jmp	sysret
 16088                              <1> 
 16089                              <1> ; Original UNIX v1 'sysstty' routine:
 16090                              <1> ; gtty:
 16091                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
 16092                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
 16093                              <1> 	; 		/ r2 has source
 16094                              <1>         ;mov    r2,-(sp)
 16095                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
 16096                              <1> ;1: / flush the clist wait till typewriter is quiescent
 16097                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
 16098                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
 16099                              <1>         ;mov    $240,*$ps / set processor priority to 5
 16100                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
 16101                              <1>         ;       br .+4 / list empty, skip branch
 16102                              <1>         ;br     1b / get another character until list is empty
 16103                              <1>         ;mov    0b,r1 / move cc offset to r1
 16104                              <1>         ;inc    r1 / bump it for output clist
 16105                              <1>         ;tstb   cc(r1) / is it 0
 16106                              <1>         ;beq    1f / yes, no characters to output
 16107                              <1>  	;mov    r1,0f / no, put offset in sleep arg
 16108                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
 16109                              <1>         ;br     1b / try to calm it down again
 16110                              <1> ;1:
 16111                              <1>         ;mov    (sp)+,r1
 16112                              <1>         ;mov    (sp)+,r2 / restore registers
 16113                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
 16114                              <1>         ;beq    1f / if 0, 1f
 16115                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
 16116                              <1>         ;                   / control status register
 16117                              <1> ;1:
 16118                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
 16119                              <1>         ;beq    1f / if 0 1f
 16120                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
 16121                              <1> 	;		    / control status reg
 16122                              <1> ;1:
 16123                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
 16124                              <1>         ;jmp     sysret2 / return to user
 16125                              <1> 
 16126                              <1> sysgtty: ; < get tty status >
 16127                              <1> 	; 23/11/2015
 16128                              <1> 	; 29/10/2015
 16129                              <1> 	; 17/10/2015
 16130                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
 16131                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 16132                              <1> 	;
 16133                              <1> 	; 'sysgtty' gets the status of tty in question. 
 16134                              <1> 	; It stores in the three words addressed by it's argument
 16135                              <1> 	; the status of the typewriter whose file descriptor
 16136                              <1> 	; in (u.r0).
 16137                              <1> 	;
 16138                              <1> 	; Calling sequence:
 16139                              <1> 	;	sysgtty; arg
 16140                              <1> 	; Arguments:
 16141                              <1> 	;	arg - address of 3 words destination of the status
 16142                              <1> 	; Inputs: ((*u.r0 - file descriptor))
 16143                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 16144                              <1> 	; ...............................................................
 16145                              <1> 	;	
 16146                              <1> 	; Retro UNIX 8086 v1 modification: 
 16147                              <1> 	;	'sysgtty' system call will return status of tty
 16148                              <1> 	;	(keyboard, serial port and video page status)
 16149                              <1> 	;	 in following manner:
 16150                              <1> 	;
 16151                              <1> 	; Inputs:
 16152                              <1> 	;	BX = 0 --> means 
 16153                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
 16154                              <1> 	;	                 for (current) process
 16155                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
 16156                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
 16157                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
 16158                              <1> 	;	     CH > 0 -->	tty number + 1
 16159                              <1> 	;
 16160                              <1> 	;	BX > 0 --> points to name of tty
 16161                              <1> 	;	     CL = 0 --> return keyboard status
 16162                              <1> 	;	     CL = 1 --> return video page status
 16163                              <1> 	;	     CH = undefined		 
 16164                              <1> 	;
 16165                              <1> 	; Outputs:
 16166                              <1> 	;	cf = 0 ->
 16167                              <1> 	;
 16168                              <1> 	;	     AL = tty number from 0 to 9
 16169                              <1> 	;		  (0 to 7 is also the video page of the tty)	
 16170                              <1> 	;	     AH = 0 if the tty is free/unused
 16171                              <1> 	;	     AH = the process number of the caller 
 16172                              <1>  	;	     AH = FFh if the tty is locked by another process
 16173                              <1> 	;
 16174                              <1> 	;	  (if calling is for serial port status)
 16175                              <1> 	;	     BX = serial port status if tty number is 8 or 9
 16176                              <1> 	;		  (BH = modem status, BL = Line status)
 16177                              <1> 	;	     CX = 0FFFFh (if data is ready)
 16178                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
 16179                              <1> 	;
 16180                              <1> 	;	  (if calling is for keyboard status)
 16181                              <1> 	;	     BX = current character in tty/keyboard buffer
 16182                              <1> 	;		  (BH = scan code, BL = ascii code)
 16183                              <1> 	;		  (BX=0 if there is not a waiting character)
 16184                              <1> 	;	     CX  is undefined
 16185                              <1> 	;
 16186                              <1> 	;	  (if calling is for video page status)	
 16187                              <1> 	;	     BX = cursor position on the video page
 16188                              <1> 	;		  if tty number < 8
 16189                              <1> 	;		  (BH = row, BL = column)
 16190                              <1> 	;	     CX = current character (in cursor position)
 16191                              <1> 	;		  on the video page of the tty 
 16192                              <1> 	;		  if tty number < 8
 16193                              <1> 	;		  (CH = color, CL = character)
 16194                              <1> 	;	
 16195                              <1> 	;	cf = 1 means error (requested tty is not ready)
 16196                              <1> 	;
 16197                              <1> 	;	     AH = FFh if the caller is not owner of
 16198                              <1> 	;		  specified tty or console tty
 16199                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 16200                              <1> 	;	     BX, CX are undefined if cf = 1
 16201                              <1> 	;
 16202                              <1> 	;	  (If tty number is 8 or 9)
 16203                              <1> 	;	     AL = tty number 
 16204                              <1> 	;	     AH = the process number of the caller 
 16205                              <1> 	;	     BX = serial port status
 16206                              <1> 	;  		 (BH = modem status, BL = Line status)
 16207                              <1> 	;	     CX = 0
 16208                              <1> 	;
 16209                              <1> 		
 16210                              <1> gtty:   ; get (requested) tty number
 16211                              <1> 	; 17/10/2015
 16212                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 16213                              <1> 	; 30/05/2013 - 12/07/2014
 16214                              <1> 	; Retro UNIX 8086 v1 modification ! 
 16215                              <1> 	;
 16216                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
 16217                              <1> 	;
 16218                              <1> 	; 28/06/2015 (32 bit modifications)
 16219                              <1> 	; 16/01/2014
 16220 000047A0 31C0                <1> 	xor 	eax, eax
 16221 000047A2 6648                <1> 	dec	ax ; 17/10/2015
 16222 000047A4 A3[80740000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
 16223 000047A9 80F901              <1> 	cmp	cl, 1
 16224 000047AC 760F                <1> 	jna	short sysgtty_0
 16225                              <1> sysgtty_invp:
 16226                              <1> 	; 28/06/2015
 16227 000047AE C705[D5740000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 16228 000047B6 0000                <1>
 16229 000047B8 E9BFF8FFFF          <1> 	jmp	error
 16230                              <1> sysgtty_0:	
 16231 000047BD 21DB                <1> 	and	ebx, ebx
 16232 000047BF 7430                <1> 	jz	short sysgtty_1
 16233                              <1> 	;
 16234 000047C1 891D[98740000]      <1> 	mov	[u.namep], ebx
 16235 000047C7 6651                <1> 	push	cx ; 23/11/2015
 16236 000047C9 E86A070000          <1> 	call	namei
 16237 000047CE 6659                <1> 	pop	cx ; 23/11/2015
 16238 000047D0 7210                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
 16239                              <1> 	;
 16240 000047D2 6683F801            <1> 	cmp	ax, 1
 16241 000047D6 7622                <1> 	jna	short sysgtty_2
 16242 000047D8 6683E80A            <1> 	sub	ax, 10
 16243 000047DC 6683F809            <1> 	cmp	ax, 9
 16244                              <1> 	;ja	short sysgtty_inv_dn
 16245                              <1> 	;mov	ch, al
 16246                              <1> 	;jmp	short sysgtty_4
 16247                              <1> 	; 23/11/2015
 16248 000047E0 7629                <1> 	jna	short sysgtty_4
 16249                              <1> sysgtty_inv_dn: 
 16250                              <1> 	; 28/06/2015
 16251                              <1> 	; Invalid device name (not a tty) ! error
 16252                              <1> 	; (Device is not a tty or device name not found)
 16253 000047E2 C705[D5740000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 16254 000047EA 0000                <1>
 16255 000047EC E98BF8FFFF          <1> 	jmp	error 
 16256                              <1> sysgtty_1:
 16257                              <1> 	; 16/01/2014
 16258 000047F1 80FD0A              <1> 	cmp	ch, 10
 16259 000047F4 77B8                <1> 	ja	short sysgtty_invp ; 28/06/2015
 16260 000047F6 FECD                <1> 	dec	ch ; 0 -> FFh (negative)
 16261 000047F8 790F                <1> 	jns	short sysgtty_3 ; not negative
 16262                              <1> 	;
 16263                              <1> sysgtty_2:
 16264                              <1> 	; get tty number of console tty
 16265 000047FA 8A25[CF740000]      <1> 	mov	ah, [u.uno]
 16266                              <1>  	; 28/06/2015
 16267 00004800 0FB6DC              <1> 	movzx 	ebx, ah
 16268 00004803 8AAB[D5710000]      <1> 	mov	ch, [ebx+p.ttyc-1]
 16269                              <1> sysgtty_3:
 16270 00004809 88E8                <1> 	mov	al, ch
 16271                              <1> sysgtty_4:
 16272 0000480B A2[80740000]        <1> 	mov	[u.r0], al
 16273                              <1>  	; 28/06/2015
 16274                              <1> 	;cmp	al, 9
 16275                              <1> 	;ja	short sysgtty_invp
 16276 00004810 8B2D[7C740000]      <1> 	mov	ebp, [u.usp]
 16277                              <1> 	; 23/11/2015
 16278 00004816 20C9                <1> 	and	cl, cl
 16279 00004818 7436                <1> 	jz	short sysgtty_6 ; keyboard status
 16280 0000481A 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
 16281 0000481C 7232                <1> 	jb	short sysgtty_6 ; video page status
 16282                              <1> 	; serial port status
 16283                              <1> 	; 12/07/2014
 16284                              <1> 	;mov	dx, 0
 16285                              <1> 	;je	short sysgtty_5
 16286                              <1> 	;inc	dl
 16287                              <1> ;sysgtty_5:
 16288                              <1> 	; 28/06/2015
 16289 0000481E 2C08                <1> 	sub	al, 8
 16290 00004820 E8FCF2FFFF          <1> 	call	sp_status ; serial (COM) port (line) status
 16291                              <1> 	; AL = Line status, AH = Modem status
 16292 00004825 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
 16293 00004829 8A25[CF740000]      <1> 	mov	ah, [u.uno]
 16294 0000482F 8825[81740000]      <1>         mov     [u.r0+1], ah
 16295 00004835 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)	
 16296                              <1> 				; (in ECX)
 16297 0000483B A880                <1> 	test	al, 80h
 16298 0000483D 7565                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
 16299 0000483F A801                <1> 	test	al, 1
 16300 00004841 0F8455F8FFFF        <1> 	jz	sysret
 16301 00004847 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)	
 16302 0000484B E94CF8FFFF          <1> 	jmp	sysret
 16303                              <1> sysgtty_6:
 16304 00004850 A2[D4740000]        <1> 	mov	[u.ttyn], al ; tty number
 16305                              <1> 	;movzx	ebx, al
 16306 00004855 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
 16307 00004857 D0E3                <1> 	shl 	bl, 1  ; aligned to word
 16308                              <1> 	; 22/04/2014 - 29/06/2015
 16309 00004859 81C3[F4700000]      <1>         add     ebx, ttyl
 16310 0000485F 8A23                <1>  	mov	ah, [ebx]
 16311 00004861 3A25[CF740000]      <1> 	cmp	ah, [u.uno]
 16312 00004867 7404                <1> 	je	short sysgtty_7
 16313 00004869 20E4                <1> 	and	ah, ah
 16314                              <1> 	;jz	short sysgtty_7
 16315 0000486B 7506                <1> 	jnz	short sysgtty_8
 16316                              <1> 	;mov	ah, 0FFh
 16317                              <1> sysgtty_7:
 16318 0000486D 8825[81740000]      <1>         mov     [u.r0+1], ah
 16319                              <1> sysgtty_8:
 16320 00004873 08C9                <1> 	or	cl, cl
 16321 00004875 7510                <1> 	jnz	short sysgtty_9
 16322 00004877 B001                <1> 	mov	al, 1  ; test a key is available
 16323 00004879 E8621C0000          <1> 	call	getc
 16324 0000487E 66894510            <1> 	mov	[ebp+16], ax ; bx, character
 16325 00004882 E915F8FFFF          <1> 	jmp	sysret
 16326                              <1> sysgtty_9:
 16327 00004887 8A1D[D4740000]      <1> 	mov	bl, [u.ttyn]
 16328                              <1> 	; bl = video page number
 16329 0000488D E8CF1D0000          <1> 	call 	get_cpos
 16330                              <1> 	; dx = cursor position
 16331 00004892 66895510            <1> 	mov	[ebp+16], dx ; bx
 16332                              <1> 	;mov	bl, [u.ttyn]
 16333                              <1> 	; bl = video page number
 16334 00004896 E8D71D0000          <1> 	call	read_ac_current
 16335                              <1> 	; ax = character and attribute/color
 16336 0000489B 66894518            <1> 	mov	[ebp+24], ax ; cx
 16337 0000489F E9F8F7FFFF          <1> 	jmp	sysret
 16338                              <1> sysgtty_dnr_err:
 16339                              <1> 	; 'device not responding !' error	
 16340                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
 16341 000048A4 C705[D5740000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ;  25				
 16342 000048AC 0000                <1>
 16343 000048AE E9C9F7FFFF          <1> 	jmp	error	
 16344                              <1> 
 16345                              <1> ; Original UNIX v1 'sysgtty' routine:
 16346                              <1> ; sysgtty:
 16347                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
 16348                              <1> 	;	       / r2 has destination
 16349                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
 16350                              <1> 	;                     / in 1st word of dest
 16351                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
 16352                              <1> 	;                     / in 2nd word of dest
 16353                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
 16354                              <1>         ;jmp    sysret2 / return to user
 16355                              <1> 	
 16356                              <1> ; Original UNIX v1 'gtty' routine:
 16357                              <1> ; gtty:
 16358                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
 16359                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
 16360                              <1>         ;jsr    r0,getf / get the i-number of the file
 16361                              <1>         ;tst    r1 / is it open for reading
 16362                              <1>         ;bgt    1f / yes
 16363                              <1>         ;neg    r1 / no, i-number is negative, 
 16364                              <1> 	;          / so make it positive
 16365                              <1> ;1:
 16366                              <1>         ;sub    $14.,r1 / get i-number of tty0
 16367                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
 16368                              <1>         ;bhis   error9 / no, error
 16369                              <1>         ;asl    r1 / 0%2
 16370                              <1>         ;asl    r1 / 0%4 / yes
 16371                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
 16372                              <1> 	;	       ; / tty block
 16373                              <1>         ;mov    u.off,r2 / put argument in r2
 16374                              <1>         ;rts    r0 / return
 16375                                  %include 'u2.s'        ; 11/05/2015
 16376                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS2.INC
 16377                              <1> ; Last Modification: 03/01/2016
 16378                              <1> ; ----------------------------------------------------------------------------
 16379                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 16380                              <1> ; (v0.1 - Beginning: 11/07/2012)
 16381                              <1> ;
 16382                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 16383                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 16384                              <1> ; <Bell Laboratories (17/3/1972)>
 16385                              <1> ; <Preliminary Release of UNIX Implementation Document>
 16386                              <1> ;
 16387                              <1> ; Retro UNIX 8086 v1 - U2.ASM (24/03/2014) //// UNIX v1 -> u2.s
 16388                              <1> ;
 16389                              <1> ; ****************************************************************************
 16390                              <1> 
 16391                              <1> syslink:
 16392                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 16393                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 16394                              <1> 	;
 16395                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
 16396                              <1> 	; name 1 is a file that already exists. name 2 is the name
 16397                              <1> 	; given to the entry that will go in the current directory.
 16398                              <1> 	; name2 will then be a link to the name 1 file. The i-number
 16399                              <1> 	; in the name 2 entry of current directory is the same
 16400                              <1> 	; i-number for the name 1 file.
 16401                              <1> 	;
 16402                              <1> 	; Calling sequence:
 16403                              <1> 	;	syslink; name 1; name 2
 16404                              <1> 	; Arguments:
 16405                              <1> 	;	name 1 - file name to which link will be created.
 16406                              <1> 	;	name 2 - name of entry in current directory that
 16407                              <1> 	;		 links to name 1.
 16408                              <1> 	; Inputs: -
 16409                              <1> 	; Outputs: -
 16410                              <1> 	; ...............................................................
 16411                              <1> 	;	
 16412                              <1> 	; Retro UNIX 8086 v1 modification: 
 16413                              <1> 	;       'syslink' system call has two arguments; so,
 16414                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
 16415                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
 16416                              <1> 	;
 16417                              <1> 		; / name1, name2
 16418                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
 16419 000048B3 891D[98740000]      <1> 	mov	[u.namep], ebx
 16420 000048B9 51                  <1> 	push	ecx
 16421 000048BA E879060000          <1> 	call	namei
 16422                              <1> 		; jsr r0,namei / find the i-number associated with
 16423                              <1> 			     ; / the 1st path name
 16424                              <1>      	;;and	ax, ax
 16425                              <1> 	;;jz	error ; File not found
 16426                              <1> 	;jc	error 
 16427                              <1> 		; br error9 / cannot be found
 16428 000048BF 730F                <1> 	jnc	short syslink0
 16429                              <1> 	;pop 	ecx
 16430                              <1> 	; 'file not found !' error
 16431 000048C1 C705[D5740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 16432 000048C9 0000                <1>
 16433 000048CB E9ACF7FFFF          <1> 	jmp	error
 16434                              <1> syslink0:
 16435 000048D0 E8530E0000          <1> 	call	iget
 16436                              <1> 		; jsr r0,iget / get the i-node into core
 16437 000048D5 8F05[98740000]      <1> 	pop	dword [u.namep] ; ecx
 16438                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
 16439 000048DB 6650                <1> 	push	ax
 16440                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
 16441                              <1> 			    ; / (a link to this file is to be created)
 16442 000048DD 66FF35[66740000]    <1> 	push	word [cdev]
 16443                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
 16444 000048E4 E855000000          <1> 	call	isdir
 16445                              <1> 		; jsr r0,isdir / is it a directory
 16446 000048E9 E84A060000          <1> 	call	namei
 16447                              <1> 		; jsr r0,namei / no, get i-number of name2
 16448                              <1> 	;jnc	error
 16449                              <1> 		; br .+4   / not found 
 16450                              <1> 			 ; / so r1 = i-number of current directory
 16451                              <1> 			 ; / ii = i-number of current directory
 16452                              <1> 		; br error9 / file already exists., error
 16453 000048EE 720F                <1> 	jc	short syslink1
 16454                              <1> 	; pop ax
 16455                              <1> 	; pop ax
 16456                              <1> 	; 'file exists !' error
 16457 000048F0 C705[D5740000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
 16458 000048F8 0000                <1>
 16459 000048FA E97DF7FFFF          <1> 	jmp	error
 16460                              <1> syslink1:
 16461 000048FF 6659                <1> 	pop	cx
 16462                              <1> 	;cmp	cx, [cdev]
 16463 00004901 3A0D[66740000]      <1> 	cmp	cl, [cdev]
 16464                              <1> 	;jne	error
 16465                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
 16466                              <1> 			       ; / end of current directory
 16467                              <1> 	        ; bne error9
 16468 00004907 740F                <1> 	je	short syslink2
 16469                              <1> 	; 'not same drive !' error
 16470 00004909 C705[D5740000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
 16471 00004911 0000                <1>
 16472 00004913 E964F7FFFF          <1> 	jmp	error
 16473                              <1> syslink2:
 16474 00004918 6658                <1> 	pop	ax
 16475 0000491A 6650                <1> 	push	ax
 16476 0000491C 66A3[B2740000]      <1> 	mov	[u.dirbuf], ax
 16477                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
 16478 00004922 E8A8000000          <1> 	call	mkdir
 16479                              <1> 		; jsr r0,mkdir / make directory entry for name2 
 16480                              <1> 		 	     ; / in current directory
 16481 00004927 6658                <1> 	pop	ax
 16482                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
 16483 00004929 E8FA0D0000          <1> 	call	iget
 16484                              <1> 		; jsr r0,iget / get i-node into core
 16485 0000492E FE05[58710000]      <1> 	inc	byte [i.nlks]
 16486                              <1> 		; incb i.nlks / add 1 to its number of links
 16487 00004934 E8020F0000          <1> 	call	setimod
 16488                              <1> 		; jsr r0,setimod / set the i-node modified flag
 16489 00004939 E95EF7FFFF          <1> 	jmp	sysret
 16490                              <1> 
 16491                              <1> isdir:
 16492                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 16493                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16494                              <1> 	;
 16495                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
 16496                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
 16497                              <1> 	;  called by syslink and sysunlink to make sure directories
 16498                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
 16499                              <1> 	; 'isdir' does not bother checking. The current i-node
 16500                              <1> 	;  is not disturbed.			
 16501                              <1> 	;		
 16502                              <1> 	; INPUTS ->
 16503                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
 16504                              <1> 	;    u.uid - user id
 16505                              <1> 	; OUTPUTS ->
 16506                              <1> 	;    r1 - contains current i-number upon exit
 16507                              <1> 	;    	 (current i-node back in core) 
 16508                              <1> 	;	
 16509                              <1> 	; ((AX = R1))
 16510                              <1> 	;
 16511                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 16512                              <1> 	;
 16513                              <1> 
 16514                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
 16515                              <1> 	; / there is an error unless super user made the call
 16516                              <1> 	
 16517 0000493E 803D[CC740000]00    <1> 	cmp	byte [u.uid], 0 
 16518                              <1> 		; tstb u.uid / super user
 16519 00004945 762D                <1> 	jna	short isdir1
 16520                              <1> 		; beq 1f / yes, don't care
 16521 00004947 66FF35[62740000]    <1> 	push	word [ii]
 16522                              <1> 		; mov ii,-(sp) / put current i-number on stack
 16523 0000494E E8D50D0000          <1> 	call	iget
 16524                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
 16525 00004953 66F705[56710000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
 16526 0000495B 40                  <1>
 16527                              <1> 		; bit $40000,i.flgs / is it a directory
 16528                              <1> 	;jnz	error
 16529                              <1> 		; bne error9 / yes, error
 16530 0000495C 740F                <1> 	jz	short isdir0
 16531 0000495E C705[D5740000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
 16532 00004966 0000                <1>
 16533                              <1> 				; 'permission denied !' error
 16534                              <1> 	; pop	ax
 16535 00004968 E90FF7FFFF          <1> 	jmp	error	
 16536                              <1> isdir0:	
 16537 0000496D 6658                <1> 	pop	ax
 16538                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
 16539 0000496F E8B40D0000          <1> 	call	iget
 16540                              <1> 		; jsr r0,iget / get it back in
 16541                              <1> isdir1: ; 1:
 16542 00004974 C3                  <1> 	retn
 16543                              <1> 		; rts r0
 16544                              <1> 
 16545                              <1> sysunlink:
 16546                              <1> 	; 04/12/2015 (14 byte file names)
 16547                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 16548                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 16549                              <1> 	;
 16550                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
 16551                              <1> 	; name from its directory. If this entry was the last link
 16552                              <1> 	; to the file, the contents of the file are freed and the
 16553                              <1> 	; file is destroyed. If, however, the file was open in any
 16554                              <1> 	; process, the actual destruction is delayed until it is 
 16555                              <1> 	; closed, even though the directory entry has disappeared.
 16556                              <1> 	; 
 16557                              <1> 	; The error bit (e-bit) is set to indicate that the file	
 16558                              <1> 	; does not exist or that its directory can not be written.
 16559                              <1> 	; Write permission is not required on the file itself.
 16560                              <1> 	; It is also illegal to unlink a directory (except for
 16561                              <1> 	; the superuser).
 16562                              <1> 	;
 16563                              <1> 	; Calling sequence:
 16564                              <1> 	;	sysunlink; name
 16565                              <1> 	; Arguments:
 16566                              <1> 	;	name - name of directory entry to be removed 
 16567                              <1> 	; Inputs: -
 16568                              <1> 	; Outputs: -
 16569                              <1> 	; ...............................................................
 16570                              <1> 	;				
 16571                              <1> 	; Retro UNIX 8086 v1 modification:
 16572                              <1> 	;	 The user/application program puts address of the name
 16573                              <1> 	;        in BX register as 'sysunlink' system call argument.
 16574                              <1> 
 16575                              <1> 	; / name - remove link name
 16576 00004975 891D[98740000]      <1> 	mov	[u.namep], ebx
 16577                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
 16578 0000497B E8B8050000          <1> 	call	namei
 16579                              <1> 		; jsr r0,namei / find the i-number associated 
 16580                              <1> 			     ; / with the path name
 16581                              <1> 	;jc	error
 16582                              <1> 		; br error9 / not found
 16583 00004980 730F                <1> 	jnc	short sysunlink1
 16584                              <1> 	; 'file not found !' error
 16585 00004982 C705[D5740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 16586 0000498A 0000                <1>
 16587 0000498C E9EBF6FFFF          <1> 	jmp	error
 16588                              <1> sysunlink1:
 16589 00004991 6650                <1> 	push	ax
 16590                              <1> 		; mov r1,-(sp) / put its i-number on the stack
 16591 00004993 E8A6FFFFFF          <1> 	call	isdir
 16592                              <1> 		; jsr r0,isdir / is it a directory
 16593 00004998 6631C0              <1> 	xor 	ax, ax
 16594 0000499B 66A3[B2740000]      <1> 	mov	[u.dirbuf], ax ; 0
 16595                              <1> 		; clr u.dirbuf / no, clear the location that will
 16596                              <1> 			   ; / get written into the i-number portion
 16597                              <1> 			 ; / of the entry
 16598 000049A1 832D[9C740000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
 16599                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
 16600 000049A8 E86E000000          <1> 	call	wdir
 16601                              <1> 		; jsr r0,wdir / free the directory entry
 16602 000049AD 6658                <1> 	pop	ax
 16603                              <1> 		; mov (sp)+,r1 / get i-number back
 16604 000049AF E8740D0000          <1> 	call	iget
 16605                              <1> 		; jsr r0,iget / get i-node
 16606 000049B4 E8820E0000          <1> 	call	setimod
 16607                              <1> 		; jsr r0,setimod / set modified flag
 16608 000049B9 FE0D[58710000]      <1> 	dec	byte [i.nlks]
 16609                              <1> 		; decb i.nlks / decrement the number of links
 16610 000049BF 0F85D7F6FFFF        <1> 	jnz	sysret
 16611                              <1> 		; bgt sysret9 / if this was not the last link
 16612                              <1> 			    ; / to file return
 16613                              <1> 	; AX = r1 = i-number
 16614 000049C5 E893090000          <1> 	call	anyi
 16615                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
 16616                              <1> 			 ; / Then free contents of file and destroy it.
 16617 000049CA E9CDF6FFFF          <1> 	jmp	sysret
 16618                              <1> 		; br sysret9
 16619                              <1> 
 16620                              <1> mkdir:
 16621                              <1> 	; 04/12/2015 (14 byte directory names)
 16622                              <1> 	; 12/10/2015
 16623                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
 16624                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 16625                              <1> 	;
 16626                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
 16627                              <1> 	; by u.namep into the current directory.
 16628                              <1> 	;
 16629                              <1> 	; INPUTS ->
 16630                              <1> 	;    u.namep - points to a file name 
 16631                              <1> 	;	           that is about to be a directory entry.
 16632                              <1> 	;    ii - current directory's i-number.	
 16633                              <1> 	; OUTPUTS ->
 16634                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
 16635                              <1> 	;    u.off - points to entry to be filled 
 16636                              <1> 	;	     in the current directory		
 16637                              <1> 	;    u.base - points to start of u.dirbuf.
 16638                              <1> 	;    r1 - contains i-number of current directory 
 16639                              <1> 	;	
 16640                              <1> 	; ((AX = R1)) output
 16641                              <1> 	;
 16642                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
 16643                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 16644                              <1> 	;
 16645                              <1> 
 16646                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 16647 000049CF 31C0                <1> 	xor 	eax, eax
 16648 000049D1 BF[B4740000]        <1> 	mov     edi, u.dirbuf+2
 16649 000049D6 89FE                <1> 	mov	esi, edi
 16650 000049D8 AB                  <1> 	stosd
 16651 000049D9 AB                  <1> 	stosd
 16652                              <1> 	; 04/12/2015 (14 byte directory names)
 16653 000049DA AB                  <1> 	stosd
 16654 000049DB 66AB                <1> 	stosw
 16655                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
 16656 000049DD 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
 16657                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 16658                              <1> 	;mov 	ebp, [u.namep]
 16659 000049DF E899060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 16660                              <1> 		; esi = physical address (page start + offset)
 16661                              <1> 		; ecx = byte count in the page (1 - 4096)
 16662                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 16663                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
 16664                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
 16665                              <1> mkdir_1: ; 1: 
 16666 000049E4 45                  <1> 	inc	ebp ; 12/10/2015
 16667                              <1> 	;
 16668                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
 16669                              <1> 	 ; 01/08/2013
 16670 000049E5 AC                  <1> 	lodsb
 16671                              <1> 		; movb (r2)+,r1 / move character in name to r1
 16672 000049E6 20C0                <1> 	and 	al, al
 16673 000049E8 7427                <1> 	jz 	short mkdir_3 	  
 16674                              <1> 		; beq 1f / if null, done
 16675 000049EA 3C2F                <1> 	cmp	al, '/'
 16676                              <1> 		; cmp r1,$'/ / is it a "/"?
 16677 000049EC 7414                <1> 	je	short mkdir_err
 16678                              <1> 	;je	error
 16679                              <1> 		; beq error9 / yes, error
 16680                              <1> 	; 12/10/2015
 16681 000049EE 6649                <1> 	dec	cx
 16682 000049F0 7505                <1> 	jnz	short mkdir_2
 16683                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 16684 000049F2 E88C060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 16685                              <1> 		; esi = physical address (page start + offset)
 16686                              <1> 		; ecx = byte count in the page
 16687                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 16688                              <1> mkdir_2:
 16689 000049F7 81FF[C2740000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
 16690                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
 16691                              <1> 				     ; / a char?
 16692 000049FD 74E5                <1> 	je	short mkdir_1
 16693                              <1> 		; beq 1b / yes, go back
 16694 000049FF AA                  <1> 	stosb
 16695                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
 16696 00004A00 EBE2                <1> 	jmp 	short mkdir_1
 16697                              <1> 		; br 1b / get next char
 16698                              <1> mkdir_err:
 16699                              <1> 	; 17/06/2015
 16700 00004A02 C705[D5740000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 16701 00004A0A 0000                <1>
 16702 00004A0C E96BF6FFFF          <1> 	jmp	error
 16703                              <1> 
 16704                              <1> mkdir_3: ; 1:
 16705 00004A11 A1[94740000]        <1> 	mov	eax, [u.dirp]
 16706 00004A16 A3[9C740000]        <1> 	mov	[u.off], eax
 16707                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
 16708                              <1> 				 ; / slot to u.off
 16709                              <1> wdir: ; 29/04/2013
 16710 00004A1B C705[A0740000]-     <1>         mov     dword [u.base], u.dirbuf
 16711 00004A21 [B2740000]          <1>
 16712                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
 16713 00004A25 C705[A4740000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
 16714 00004A2D 0000                <1>
 16715                              <1> 		; mov $10.,u.count / u.count = 10
 16716 00004A2F 66A1[62740000]      <1> 	mov	ax, [ii] 
 16717                              <1> 		; mov ii,r1 / r1 has i-number of current directory
 16718 00004A35 B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
 16719 00004A37 E8C70D0000          <1> 	call 	access
 16720                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
 16721                              <1> 				 ; / for writing
 16722                              <1> 	; AX = i-number of current directory
 16723                              <1> 	; 01/08/2013
 16724 00004A3C FE05[E7740000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
 16725 00004A42 E8B7100000          <1> 	call	writei
 16726                              <1> 		; jsr r0,writei / write into directory
 16727 00004A47 C3                  <1> 	retn	
 16728                              <1> 		; rts r0
 16729                              <1> 
 16730                              <1> sysexec:
 16731                              <1> 	; 23/10/2015
 16732                              <1> 	; 19/10/2015
 16733                              <1> 	; 18/10/2015
 16734                              <1> 	; 10/10/2015
 16735                              <1> 	; 26/08/2015
 16736                              <1> 	; 05/08/2015
 16737                              <1> 	; 29/07/2015
 16738                              <1> 	; 25/07/2015
 16739                              <1> 	; 24/07/2015
 16740                              <1> 	; 21/07/2015
 16741                              <1> 	; 20/07/2015
 16742                              <1> 	; 02/07/2015
 16743                              <1> 	; 01/07/2015
 16744                              <1> 	; 25/06/2015
 16745                              <1> 	; 24/06/2015
 16746                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 16747                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 16748                              <1> 	;
 16749                              <1> 	; 'sysexec' initiates execution of a file whose path name if
 16750                              <1> 	; pointed to by 'name' in the sysexec call. 
 16751                              <1> 	; 'sysexec' performs the following operations:
 16752                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
 16753                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
 16754                              <1> 	;    3. sets trap vectors to system routines.
 16755                              <1> 	;    4. loads arguments to be passed to executing file into
 16756                              <1> 	;	highest locations of user's core
 16757                              <1> 	;    5. puts pointers to arguments in locations immediately
 16758                              <1> 	;	following arguments.
 16759                              <1> 	;    6.	saves number of arguments in next location.
 16760                              <1> 	;    7. intializes user's stack area so that all registers
 16761                              <1> 	;	will be zeroed and the PS is cleared and the PC set
 16762                              <1> 	;	to core when 'sysret' restores registers 
 16763                              <1> 	;	and does an rti.
 16764                              <1> 	;    8. inializes u.r0 and u.sp
 16765                              <1> 	;    9. zeros user's core down to u.r0
 16766                              <1> 	;   10.	reads executable file from storage device into core
 16767                              <1> 	;	starting at location 'core'.
 16768                              <1> 	;   11.	sets u.break to point to end of user's code with
 16769                              <1> 	;	data area appended.
 16770                              <1> 	;   12.	calls 'sysret' which returns control at location
 16771                              <1> 	;	'core' via 'rti' instruction. 		  		
 16772                              <1> 	;
 16773                              <1> 	; Calling sequence:
 16774                              <1> 	;	sysexec; namep; argp
 16775                              <1> 	; Arguments:
 16776                              <1> 	;	namep - points to pathname of file to be executed
 16777                              <1> 	;	argp  - address of table of argument pointers
 16778                              <1> 	;	argp1... argpn - table of argument pointers
 16779                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
 16780                              <1> 	; Inputs: (arguments)
 16781                              <1> 	; Outputs: -	
 16782                              <1> 	; ...............................................................
 16783                              <1> 	;
 16784                              <1> 	; Retro UNIX 386 v1 modification: 
 16785                              <1> 	;	User application runs in it's own virtual space 
 16786                              <1> 	;	which is izolated from kernel memory (and other
 16787                              <1> 	;	memory pages) via 80386	paging in ring 3 
 16788                              <1> 	;	privilige mode. Virtual start address is always 0.
 16789                              <1> 	;	User's core memory starts at linear address 400000h
 16790                              <1> 	;	(the end of the 1st 4MB).
 16791                              <1> 	;
 16792                              <1> 	; Retro UNIX 8086 v1 modification: 
 16793                              <1> 	;	user/application segment and system/kernel segment
 16794                              <1> 	;	are different and sysenter/sysret/sysrele routines
 16795                              <1> 	;	are different (user's registers are saved to 
 16796                              <1> 	;	and then restored from system's stack.)
 16797                              <1> 	;
 16798                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 16799                              <1> 	;	      arguments which were in these registers;
 16800                              <1> 	;	      but, it returns by putting the 1st argument
 16801                              <1> 	;	      in 'u.namep' and the 2nd argument
 16802                              <1> 	;	      on top of stack. (1st argument is offset of the
 16803                              <1> 	;	      file/path name in the user's program segment.)		 	
 16804                              <1> 	
 16805                              <1> 	;call	arg2
 16806                              <1> 	; * name - 'u.namep' points to address of file/path name
 16807                              <1> 	;          in the user's program segment ('u.segmnt')
 16808                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16809                              <1> 	; * argp - sysexec argument 2 is in CX register 
 16810                              <1> 	;          which is on top of stack.
 16811                              <1> 	;
 16812                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
 16813                              <1> 
 16814                              <1> 	; 23/06/2015 (32 bit modifications)
 16815                              <1> 
 16816 00004A48 891D[98740000]      <1> 	mov	[u.namep], ebx ; argument 1
 16817                              <1>         ; 18/10/2015
 16818 00004A4E 890D[00750000]      <1> 	mov     [argv], ecx  ; * ; argument 2
 16819 00004A54 E8DF040000          <1> 	call	namei
 16820                              <1> 		; jsr r0,namei / namei returns i-number of file 
 16821                              <1> 			     ; / named in sysexec call in r1
 16822                              <1> 	;jc	error
 16823                              <1> 		; br error9
 16824 00004A59 731E                <1> 	jnc	short sysexec_0
 16825                              <1> 	;
 16826                              <1> 	; 'file not found !' error
 16827 00004A5B C705[D5740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
 16828 00004A63 0000                <1>
 16829 00004A65 E912F6FFFF          <1> 	jmp	error 
 16830                              <1> sysexec_not_exf:
 16831                              <1> 	; 'not executable file !' error
 16832 00004A6A C705[D5740000]1600- <1> 	mov	dword [u.error], ERR_NOT_EXECUTABLE
 16833 00004A72 0000                <1>
 16834 00004A74 E903F6FFFF          <1> 	jmp	error 
 16835                              <1> sysexec_0:
 16836 00004A79 E8AA0C0000          <1> 	call	iget
 16837                              <1> 		; jsr r0,iget / get i-node for file to be executed
 16838 00004A7E 66F705[56710000]10- <1>         test    word [i.flgs], 10h
 16839 00004A86 00                  <1>
 16840                              <1> 		; bit $20,i.flgs / is file executable
 16841 00004A87 74E1                <1> 	jz	short sysexec_not_exf
 16842                              <1> 	;jz	error
 16843                              <1> 		; beq error9
 16844                              <1> 	;;
 16845 00004A89 E819140000          <1> 	call	iopen
 16846                              <1> 		; jsr r0,iopen / gets i-node for file with i-number
 16847                              <1> 			     ; / given in r1 (opens file)
 16848                              <1> 	; AX = i-number of the file
 16849 00004A8E 66F705[56710000]20- <1> 	test	word [i.flgs], 20h
 16850 00004A96 00                  <1>
 16851                              <1> 		; bit $40,i.flgs / test user id on execution bit
 16852 00004A97 7415                <1> 	jz	short sysexec_1
 16853                              <1> 		; beq 1f
 16854 00004A99 803D[CC740000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013
 16855                              <1> 		; tstb u.uid / test user id
 16856 00004AA0 760C                <1> 	jna	short sysexec_1
 16857                              <1> 		; beq 1f / super user
 16858 00004AA2 8A0D[59710000]      <1> 	mov	cl, [i.uid]
 16859 00004AA8 880D[CC740000]      <1> 	mov	[u.uid], cl ; 02/08/2013
 16860                              <1> 		; movb i.uid,u.uid / put user id of owner of file
 16861                              <1> 				 ; / as process user id
 16862                              <1> sysexec_1:
 16863                              <1> 	; 18/10/2215
 16864                              <1> 	; 10/10/2015
 16865                              <1> 	; 24/07/2015
 16866                              <1> 	; 21/07/2015
 16867                              <1> 	; 25/06/2015
 16868                              <1> 	; 24/06/2015
 16869                              <1>         ; Moving arguments to the end of [u.upage]
 16870                              <1> 	; (by regarding page borders in user's memory space)
 16871                              <1> 	;
 16872                              <1> 	; 10/10/2015
 16873                              <1> 	; 21/07/2015
 16874 00004AAE 89E5                <1> 	mov	ebp, esp ; (**)
 16875                              <1> 	; 18/10/2015
 16876 00004AB0 89EF                <1> 	mov 	edi, ebp
 16877 00004AB2 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
 16878                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
 16879 00004AB7 29CF                <1> 	sub	edi, ecx
 16880 00004AB9 89FC                <1> 	mov	esp, edi
 16881 00004ABB 31C0                <1> 	xor	eax, eax
 16882 00004ABD A3[A8740000]        <1> 	mov 	[u.nread], eax ; 0
 16883 00004AC2 49                  <1> 	dec	ecx ; 256 - 1
 16884 00004AC3 890D[A4740000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
 16885                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
 16886                              <1> sysexec_2:
 16887 00004AC9 8B35[00750000]      <1> 	mov	esi, [argv] ; 18/10/2015 
 16888 00004ACF E873020000          <1> 	call	get_argp
 16889 00004AD4 B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
 16890                              <1> sysexec_3:
 16891 00004AD9 21C0                <1> 	and	eax, eax
 16892 00004ADB 7456                <1> 	jz	short sysexec_6
 16893                              <1> 	; 18/10/2015
 16894 00004ADD 010D[00750000]      <1> 	add	[argv], ecx ; 4
 16895 00004AE3 66FF05[FE740000]    <1> 	inc	word [argc]
 16896                              <1> 	;
 16897 00004AEA A3[A0740000]        <1> 	mov	[u.base], eax
 16898                              <1>  	; 23/10/2015
 16899 00004AEF 66C705[E5740000]00- <1> 	mov	word [u.pcount], 0
 16900 00004AF7 00                  <1>
 16901                              <1> sysexec_4:
 16902 00004AF8 E8BC110000          <1> 	call	cpass ; get a character from user's core memory
 16903 00004AFD 750B                <1>         jnz      short sysexec_5
 16904                              <1> 		; (max. 255 chars + null)
 16905                              <1> 	; 18/10/2015
 16906 00004AFF 28C0                <1> 	sub 	al, al
 16907 00004B01 AA                  <1> 	stosb
 16908 00004B02 FF05[A8740000]      <1> 	inc	dword [u.nread]
 16909 00004B08 EB29                <1> 	jmp	short sysexec_6
 16910                              <1> sysexec_5:
 16911 00004B0A AA                  <1> 	stosb
 16912 00004B0B 20C0                <1> 	and 	al, al
 16913 00004B0D 75E9                <1> 	jnz	short sysexec_4
 16914 00004B0F B904000000          <1> 	mov	ecx, 4
 16915 00004B14 390D[FC740000]      <1> 	cmp	[ncount], ecx ; 4
 16916 00004B1A 72AD                <1> 	jb	short sysexec_2
 16917 00004B1C 8B35[F8740000]      <1> 	mov	esi, [nbase]
 16918 00004B22 010D[F8740000]      <1> 	add	[nbase], ecx ; 4	
 16919 00004B28 66290D[FC740000]    <1> 	sub	[ncount], cx 
 16920 00004B2F 8B06                <1> 	mov	eax, [esi]
 16921 00004B31 EBA6                <1> 	jmp	short sysexec_3
 16922                              <1> sysexec_6:
 16923                              <1> 	; 18/10/2015
 16924                              <1> 	; argument list transfer from user's core memory to
 16925                              <1> 	; kernel stack frame is OK here.
 16926                              <1> 	; [u.nread] = ; argument list length
 16927                              <1> 	;mov	[argv], esp ; start address of argument list 	
 16928                              <1> 	;
 16929                              <1> 	; 18/10/2015
 16930                              <1> 	; 24/07/2015
 16931                              <1>         ; 21/07/2015
 16932                              <1> 	; 02/07/2015
 16933                              <1> 	; 25/06/2015
 16934                              <1> 	; 24/06/2015
 16935                              <1> 	; 23/06/2015
 16936                              <1> 	;
 16937 00004B33 8B1D[DD740000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
 16938 00004B39 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
 16939 00004B3B 740A                <1> 	jz	short sysexec_7
 16940 00004B3D A1[D9740000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
 16941 00004B42 E829E6FFFF          <1> 	call	deallocate_page_dir
 16942                              <1> sysexec_7:
 16943 00004B47 E859E5FFFF          <1> 	call	make_page_dir
 16944                              <1> 	;jc	short sysexec_14
 16945 00004B4C 0F82C0EDFFFF        <1> 	jc	panic  ; allocation error 
 16946                              <1> 		       ; after a deallocation would be nonsence !?
 16947                              <1> 	; 24/07/2015
 16948                              <1> 	; map kernel pages (1st 4MB) to PDE 0
 16949                              <1> 	;     of the user's page directory
 16950                              <1> 	;     (It is needed for interrupts!)
 16951                              <1> 	; 18/10/2015
 16952 00004B52 8B15[A8700000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
 16953 00004B58 8B02                <1> 	mov	eax, [edx] ; physical address of
 16954                              <1> 			   ; kernel's first page table (1st 4 MB)
 16955                              <1> 			   ; (PDE 0 of kernel's page directory)
 16956 00004B5A 8B15[D9740000]      <1> 	mov 	edx, [u.pgdir]
 16957 00004B60 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
 16958                              <1> 	;
 16959                              <1> 	; 20/07/2015
 16960 00004B62 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
 16961                              <1> 	; 18/10/2015
 16962 00004B67 BE[F0740000]        <1> 	mov	esi, pcore ; physical start address
 16963                              <1> sysexec_8:	
 16964 00004B6C B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
 16965 00004B71 E84DE5FFFF          <1> 	call	make_page_table
 16966 00004B76 0F8296EDFFFF        <1> 	jc	panic
 16967                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
 16968 00004B7C E850E5FFFF          <1> 	call	make_page ; make new page, clear and set the pte 
 16969 00004B81 0F828BEDFFFF        <1> 	jc	panic
 16970                              <1> 	;
 16971 00004B87 8906                <1> 	mov	[esi], eax ; 24/06/2015
 16972                              <1> 	; ebx = virtual address (24/07/2015)
 16973 00004B89 E866EAFFFF          <1> 	call 	add_to_swap_queue
 16974                              <1> 	; 18/10/2015
 16975 00004B8E 81FE[F4740000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
 16976 00004B94 740C                <1> 	je	short sysexec_9 ; yes
 16977 00004B96 BE[F4740000]        <1> 	mov	esi, ecore  ; physical address of the last page 
 16978                              <1> 	; 20/07/2015
 16979 00004B9B BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
 16980                              <1> 	; ebx = virtual end address + segment base address - 4K
 16981 00004BA0 EBCA                <1>         jmp     short sysexec_8
 16982                              <1> 
 16983                              <1> sysexec_9:
 16984                              <1> 	; 18/10/2015
 16985                              <1> 	; 26/08/2015
 16986                              <1> 	; 25/06/2015
 16987                              <1> 	; move arguments from kernel stack to [ecore]
 16988                              <1> 	; (argument list/line will be copied from kernel stack
 16989                              <1> 	; frame to the last (stack) page of user's core memory)
 16990                              <1> 	; 18/10/2015
 16991 00004BA2 8B3D[F4740000]      <1> 	mov	edi, [ecore]
 16992 00004BA8 81C700100000        <1> 	add	edi, PAGE_SIZE
 16993 00004BAE 0FB705[FE740000]    <1> 	movzx	eax, word [argc]
 16994 00004BB5 09C0                <1> 	or	eax, eax
 16995 00004BB7 7509                <1> 	jnz	short sysexec_10
 16996 00004BB9 89FB                <1> 	mov 	ebx, edi
 16997 00004BBB 83EB04              <1> 	sub	ebx, 4 
 16998 00004BBE 8903                <1> 	mov	[ebx], eax ; 0
 16999 00004BC0 EB40                <1> 	jmp 	short sysexec_13
 17000                              <1> sysexec_10:
 17001 00004BC2 8B0D[A8740000]      <1> 	mov	ecx, [u.nread]
 17002                              <1> 	;mov 	esi, [argv}
 17003 00004BC8 89E6                <1> 	mov	esi, esp ; start address of argument list
 17004 00004BCA 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
 17005 00004BCC 89C2                <1> 	mov	edx, eax
 17006 00004BCE FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
 17007 00004BD0 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
 17008 00004BD3 89FB                <1> 	mov	ebx, edi
 17009 00004BD5 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
 17010 00004BD8 29D3                <1> 	sub 	ebx, edx
 17011 00004BDA 89FA                <1> 	mov	edx, edi
 17012 00004BDC F3A4                <1> 	rep	movsb
 17013 00004BDE 89D6                <1> 	mov 	esi, edx
 17014 00004BE0 89DF                <1> 	mov 	edi, ebx
 17015 00004BE2 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
 17016 00004BE7 2B15[F4740000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
 17017 00004BED AB                  <1> 	stosd	; eax = argument count	
 17018                              <1> sysexec_11:
 17019 00004BEE 89F0                <1> 	mov	eax, esi
 17020 00004BF0 01D0                <1> 	add	eax, edx
 17021 00004BF2 AB                  <1> 	stosd  ; eax = virtual address
 17022 00004BF3 FE0D[FE740000]      <1> 	dec	byte [argc]
 17023 00004BF9 7407                <1> 	jz	short sysexec_13
 17024                              <1> sysexec_12:
 17025 00004BFB AC                  <1> 	lodsb
 17026 00004BFC 20C0                <1> 	and	al, al
 17027 00004BFE 75FB                <1> 	jnz	short sysexec_12
 17028 00004C00 EBEC                <1> 	jmp	short sysexec_11
 17029                              <1> 	;
 17030                              <1> 	; 1:
 17031                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
 17032                              <1> 			     ; / pointers to arguments to be passed
 17033                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
 17034                              <1> 			      ; / u.quit = 1 take quit
 17035                              <1> 		; mov $1,u.intr / u.intr determines handling of 
 17036                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
 17037                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
 17038                              <1> 			       ; / system routine
 17039                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector 
 17040                              <1> 			       ; / set to take system routine
 17041                              <1> 		; mov $sstack,sp / stack space used during swapping
 17042                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
 17043                              <1> 		; mov $ecore,r5 / r5 has end of core
 17044                              <1> 		; mov $core,r4 / r4 has start of users core
 17045                              <1> 		; mov r4,u.base / u.base has start of users core
 17046                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
 17047                              <1> 	; 1:
 17048                              <1> 		; tst (r2)+ / argument char = "nul"
 17049                              <1> 		; bne 1b
 17050                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of 
 17051                              <1> 			  ; / end of argument pointer list
 17052                              <1> 	; 1:
 17053                              <1> 	     ; / move arguments to bottom of users core
 17054                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 17055                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
 17056                              <1> 			    ; / ptr list
 17057                              <1> 		; blo 1f / branch to 1f when all arguments
 17058                              <1> 		       ; / are moved
 17059                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 17060                              <1> 	; 2:
 17061                              <1> 		; tstb (r3)+
 17062                              <1> 		; bne 2b / scan argument for \0 (nul)
 17063                              <1> 
 17064                              <1> 	; 2:
 17065                              <1> 		; movb -(r3),-(r5) / move argument char 
 17066                              <1> 				 ; / by char starting at "ecore"
 17067                              <1> 		; cmp r3,(r2) / moved all characters in 
 17068                              <1> 			    ; / this argument
 17069                              <1> 		; bhi 2b / branch 2b if not
 17070                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
 17071                              <1> 			     ; / r5 has pointer to nth arg
 17072                              <1> 		; br 1b / string
 17073                              <1> 	; 1:
 17074                              <1> 		; clrb -(r5)
 17075                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
 17076                              <1> 			; / last word of argument strings
 17077                              <1> 		; mov $core,r2
 17078                              <1> 	
 17079                              <1> 	; 1: / move argument pointers into core following 
 17080                              <1> 	      ; / argument strings
 17081                              <1> 		; cmp r2,r4
 17082                              <1> 		; bhis 1f / branch to 1f when all pointers
 17083                              <1> 			; / are moved
 17084                              <1> 		; mov (r2)+,-(r5)
 17085                              <1> 		; br 1b
 17086                              <1> 	; 1:
 17087                              <1> 		; sub $core,r4 / gives number of arguments *2
 17088                              <1> 		; asr r4 / divide r4 by 2 to calculate 
 17089                              <1> 		       ; / the number of args stored
 17090                              <1> 		; mov r4,-(r5) / save number of arguments ahead
 17091                              <1> 			     ; / of the argument pointers
 17092                              <1> sysexec_13:
 17093                              <1> 	; 19/10/2015
 17094                              <1> 	; 18/10/2015
 17095                              <1> 	; 29/07/2015
 17096                              <1> 	; 25/07/2015
 17097                              <1> 	; 24/07/2015
 17098                              <1> 	; 20/07/2015
 17099                              <1> 	; 25/06/2015
 17100                              <1> 	; 24/06/2015
 17101                              <1> 	; 23/06/2015
 17102                              <1> 	;
 17103                              <1> 	; moving arguments to [ecore] is OK here..
 17104                              <1> 	; 18/10/2015
 17105 00004C02 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
 17106                              <1> 	; ebx = beginning addres of argument list pointers
 17107                              <1> 	;	in user's stack
 17108                              <1> 	; 19/10/2015
 17109 00004C04 2B1D[F4740000]      <1> 	sub 	ebx, [ecore]
 17110 00004C0A 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
 17111                              <1> 			; end of core - 4096 (last page)
 17112                              <1> 			; (virtual address)
 17113 00004C10 891D[00750000]      <1> 	mov	[argv], ebx
 17114 00004C16 891D[AC740000]      <1> 	mov	[u.break], ebx ; available user memory
 17115                              <1> 	;
 17116 00004C1C 29C0                <1> 	sub	eax, eax
 17117 00004C1E C705[A4740000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
 17118 00004C26 0000                <1>
 17119                              <1> 		; mov $14,u.count
 17120 00004C28 C705[90740000]-     <1> 	mov	dword [u.fofp], u.off
 17121 00004C2E [9C740000]          <1>
 17122                              <1> 		; mov $u.off,u.fofp
 17123 00004C32 A3[9C740000]        <1> 	mov	[u.off], eax ; 0
 17124                              <1> 		; clr u.off / set offset in file to be read to zero
 17125                              <1> 	; 25/07/2015
 17126 00004C37 A3[A0740000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
 17127                              <1> 	; 25/06/2015 
 17128 00004C3C 66A1[62740000]      <1> 	mov	ax, [ii]
 17129                              <1> 	; AX = i-number of the executable file
 17130 00004C42 E8C10C0000          <1> 	call	readi
 17131                              <1> 		; jsr r0,readi / read in first six words of 
 17132                              <1> 			; / user's file, starting at $core
 17133                              <1> 		; mov sp,r5 / put users stack address in r5
 17134                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
 17135                              <1> 				; / from r5 (leaves number of words
 17136                              <1> 				; / less 26 available for
 17137                              <1> 			     	; / program in user core
 17138                              <1> 		; mov r5,u.count /
 17139                              <1> 	; 25/06/2015
 17140 00004C47 8B0D[AC740000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
 17141 00004C4D 890D[A4740000]      <1> 	mov	[u.count], ecx ; save for overrun check
 17142                              <1> 	;
 17143 00004C53 8B0D[A8740000]      <1> 	mov	ecx, [u.nread]
 17144 00004C59 890D[AC740000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
 17145 00004C5F 80F920              <1> 	cmp	cl, 32
 17146 00004C62 7540                <1>         jne     short sysexec_15
 17147                              <1> 	;:
 17148                              <1> 	; 25/06/2015
 17149                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
 17150                              <1> 	; 18/10/2015
 17151 00004C64 8B35[F0740000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
 17152                              <1> 		             ; (phys. start addr. of the exec. file)
 17153 00004C6A AD                  <1> 	lodsd
 17154 00004C6B 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
 17155 00004C6F 7533                <1> 	jne	short sysexec_15
 17156                              <1> 		; cmp core,$405 / br .+14 is first instruction 
 17157                              <1> 			      ; / if file is standard a.out format
 17158                              <1> 		; bne 1f / branch, if not standard format
 17159 00004C71 AD                  <1> 	lodsd
 17160 00004C72 89C1                <1> 	mov	ecx, eax ; text (code) section size
 17161 00004C74 AD                  <1> 	lodsd
 17162 00004C75 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
 17163                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
 17164                              <1> 		              ; / number of bytes in program text	
 17165                              <1> 		; sub $14,r5 / subtract 12
 17166 00004C77 89CB                <1> 	mov	ebx, ecx
 17167                              <1> 	;
 17168                              <1> 	; 25/06/2015
 17169                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
 17170                              <1> 	;	and SINGLIX operating systems (as code template).
 17171                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
 17172                              <1> 	;	due to RUFS (floppy disk file system) restriction...
 17173                              <1> 	;	Overrun is not possible for current version. 	
 17174                              <1> 	;
 17175 00004C79 AD                  <1> 	lodsd	
 17176 00004C7A 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
 17177 00004C7C 3B1D[A4740000]      <1> 	cmp	ebx, [u.count]
 17178 00004C82 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
 17179                              <1> 	;
 17180                              <1> 	; 24/07/2015
 17181                              <1> 	; add bss section size to [u.break]
 17182 00004C84 0105[AC740000]      <1> 	add 	[u.break], eax
 17183                              <1> 	;
 17184 00004C8A 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
 17185                              <1> 	;cmp	ecx, [u.count]
 17186                              <1> 	;jnb	short sysexec_16
 17187                              <1> 		; cmp r5,u.count /
 17188                              <1> 		; bgt 1f / branch if r5 greater than u.count
 17189 00004C8D 890D[A4740000]      <1> 	mov	[u.count], ecx ; required read count
 17190                              <1> 		; mov r5,u.count
 17191                              <1> 	;
 17192 00004C93 EB2A                <1> 	jmp	short sysexec_16
 17193                              <1> 	;
 17194                              <1> sysexec_14:
 17195                              <1> 	; 23/06/2015
 17196                              <1> 	; insufficient (out of) memory
 17197 00004C95 C705[D5740000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
 17198 00004C9D 0000                <1>
 17199 00004C9F E9D8F3FFFF          <1> 	jmp	error
 17200                              <1> 	;
 17201                              <1> sysexec_15:
 17202                              <1> 	; 25/06/2015
 17203 00004CA4 0FB715[5A710000]    <1>         movzx   edx, word [i.size] ; file size
 17204 00004CAB 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
 17205 00004CAD 7627                <1> 	jna	short sysexec_17 ; no need to next read
 17206 00004CAF 01D1                <1> 	add	ecx, edx ; [i.size]
 17207 00004CB1 3B0D[A4740000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
 17208 00004CB7 77DC                <1> 	ja	short sysexec_14
 17209 00004CB9 8915[A4740000]      <1> 	mov	[u.count], edx
 17210                              <1> sysexec_16:
 17211 00004CBF 66A1[62740000]      <1> 	mov	ax, [ii] ; i-number
 17212 00004CC5 E83E0C0000          <1> 	call	readi
 17213                              <1> 		; add core+10,u.nread / add size of user data area 
 17214                              <1> 		                    ; / to u.nread
 17215                              <1> 		; br 2f
 17216                              <1> 	; 1:
 17217                              <1> 		; jsr r0,readi / read in rest of file
 17218                              <1> 	; 2:
 17219 00004CCA 8B0D[A8740000]      <1> 	mov	ecx, [u.nread]
 17220 00004CD0 010D[AC740000]      <1> 	add	[u.break], ecx
 17221                              <1> 		; mov u.nread,u.break / set users program break to end of 
 17222                              <1> 				    ; / user code
 17223                              <1> 		; add $core+14,u.break / plus data area
 17224                              <1> sysexec_17: ; 20/07/2015
 17225                              <1> 	;mov	ax, [ii] ;rgc i-number
 17226 00004CD6 E8F9120000          <1> 	call	iclose
 17227                              <1> 		; jsr r0,iclose / does nothing
 17228 00004CDB 31C0                <1>         xor     eax, eax
 17229 00004CDD FEC0                <1> 	inc	al
 17230 00004CDF 66A3[C4740000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
 17231 00004CE5 66A3[C6740000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
 17232                              <1> 	; 02/07/2015
 17233 00004CEB 833D[DD740000]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller sys_init (kernel) ?
 17234 00004CF2 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
 17235                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
 17236 00004CF4 8B15[A8700000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
 17237 00004CFA 8915[DD740000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here 
 17238                              <1> sysexec_18:
 17239                              <1> 	; 18/10/2015
 17240                              <1> 	; 05/08/2015
 17241                              <1> 	; 29/07/2015
 17242 00004D00 8B2D[00750000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
 17243                              <1> 			    ; list pointers (argument count)
 17244 00004D06 FA                  <1> 	cli
 17245 00004D07 8B25[44700000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
 17246                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
 17247                              <1> 			    ; for this process	 
 17248                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
 17249                              <1> 	;xor	eax, eax ; 0
 17250 00004D0D FEC8                <1> 	dec	al ; eax = 0
 17251 00004D0F 66BA2300            <1> 	mov	dx, UDATA
 17252 00004D13 6652                <1> 	push	dx  ; user's stack segment
 17253 00004D15 55                  <1> 	push	ebp ; user's stack pointer
 17254                              <1> 		    ; (points to number of arguments)
 17255 00004D16 FB                  <1> 	sti
 17256 00004D17 9C                  <1> 	pushfd	; EFLAGS
 17257                              <1> 		; Set IF for enabling interrupts in user mode	
 17258                              <1> 	;or	dword [esp], 200h 
 17259                              <1> 	;
 17260                              <1> 	;mov	bx, UCODE
 17261                              <1> 	;push	bx ; user's code segment
 17262 00004D18 6A1B                <1> 	push	UCODE
 17263                              <1> 	;push	0
 17264 00004D1A 50                  <1> 	push	eax ; EIP (=0) - start address -	
 17265                              <1> 		; clr -(r5) / popped into ps when rti in 
 17266                              <1> 			  ; / sysrele is executed
 17267                              <1> 		; mov $core,-(r5) / popped into pc when rti 
 17268                              <1> 		                ; / in sysrele is executed
 17269                              <1> 		;mov r5,0f / load second copyz argument
 17270                              <1> 		;tst -(r5) / decrement r5
 17271 00004D1B 8925[78740000]      <1> 	mov	[u.sp], esp ; 29/07/2015
 17272                              <1> 	; 05/08/2015
 17273                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
 17274                              <1> 	; ('push dx' would cause to general protection fault, 
 17275                              <1> 	; after 'pop ds' etc.)
 17276                              <1> 	;
 17277                              <1> 	;; push dx ; ds (UDATA)
 17278                              <1> 	;; push dx ; es (UDATA)
 17279                              <1> 	;; push dx ; fs (UDATA)
 17280                              <1> 	;; push dx ; gs (UDATA)
 17281                              <1> 	;
 17282                              <1> 	; This is a trick to prevent general protection fault
 17283                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
 17284 00004D21 8EC2                <1> 	mov 	es, dx ; UDATA
 17285 00004D23 06                  <1> 	push 	es ; ds (UDATA)
 17286 00004D24 06                  <1> 	push 	es ; es (UDATA)
 17287 00004D25 06                  <1> 	push 	es ; fs (UDATA)
 17288 00004D26 06                  <1> 	push	es ; gs (UDATA)
 17289 00004D27 66BA1000            <1> 	mov	dx, KDATA
 17290 00004D2B 8EC2                <1> 	mov	es, dx
 17291                              <1> 	;
 17292                              <1> 	;; pushad simulation
 17293 00004D2D 89E5                <1> 	mov	ebp, esp ; esp before pushad
 17294 00004D2F 50                  <1> 	push	eax ; eax (0)
 17295 00004D30 50                  <1> 	push	eax ; ecx (0)
 17296 00004D31 50                  <1> 	push	eax ; edx (0)
 17297 00004D32 50                  <1> 	push	eax ; ebx (0)
 17298 00004D33 55                  <1> 	push	ebp ; esp before pushad
 17299 00004D34 50                  <1> 	push	eax ; ebp (0)
 17300 00004D35 50                  <1> 	push	eax ; esi (0)		
 17301 00004D36 50                  <1> 	push	eax ; edi (0)	
 17302                              <1> 	;
 17303 00004D37 A3[80740000]        <1> 	mov	[u.r0], eax ; eax = 0
 17304 00004D3C 8925[7C740000]      <1> 	mov	[u.usp], esp
 17305                              <1> 		; mov r5,u.r0 /
 17306                              <1> 		; sub $16.,r5 / skip 8 words
 17307                              <1> 		; mov r5,u.sp / assign user stack pointer value, 
 17308                              <1> 		;             / effectively zeroes all regs
 17309                              <1> 			    ; / when sysrele is executed
 17310                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
 17311                              <1> 		; clr u.break
 17312                              <1> 		; mov r5,sp / point sp to user's stack
 17313                              <1> 	;
 17314 00004D42 E958F3FFFF          <1> 	jmp	sysret0
 17315                              <1> 	;jmp	sysret
 17316                              <1> 		; br sysret3 / return to core image at $core
 17317                              <1> 
 17318                              <1> get_argp:
 17319                              <1> 	; 18/10/2015 (nbase, ncount)
 17320                              <1> 	; 21/07/2015
 17321                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
 17322                              <1> 	; Get (virtual) address of argument from user's core memory
 17323                              <1> 	;
 17324                              <1> 	; INPUT:
 17325                              <1> 	;	esi = virtual address of argument pointer
 17326                              <1> 	; OUTPUT:
 17327                              <1> 	;	eax = virtual address of argument
 17328                              <1> 	;
 17329                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
 17330                              <1> 	;
 17331 00004D47 833D[DD740000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
 17332                              <1> 				    ; (the caller is kernel)
 17333 00004D4E 7667                <1>         jna     short get_argpk 
 17334                              <1> 	;
 17335 00004D50 89F3                <1>      	mov	ebx, esi
 17336 00004D52 E873E9FFFF          <1> 	call	get_physical_addr ; get physical address
 17337 00004D57 0F8289000000        <1>         jc      get_argp_err
 17338 00004D5D A3[F8740000]        <1> 	mov 	[nbase], eax ; physical address	
 17339 00004D62 66890D[FC740000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
 17340 00004D69 B804000000          <1> 	mov	eax, 4 ; 21/07/2015
 17341 00004D6E 6639C1              <1> 	cmp	cx, ax ; 4
 17342 00004D71 735D                <1> 	jnb	short get_argp2
 17343 00004D73 89F3                <1> 	mov	ebx, esi
 17344 00004D75 01CB                <1> 	add	ebx, ecx
 17345 00004D77 E84EE9FFFF          <1> 	call	get_physical_addr ; get physical address
 17346 00004D7C 7268                <1> 	jc	short get_argp_err
 17347                              <1> 	;push	esi
 17348 00004D7E 89C6                <1> 	mov	esi, eax
 17349 00004D80 66870D[FC740000]    <1> 	xchg	cx, [ncount]
 17350 00004D87 8735[F8740000]      <1> 	xchg	esi, [nbase]
 17351 00004D8D B504                <1> 	mov	ch, 4
 17352 00004D8F 28CD                <1> 	sub	ch, cl
 17353                              <1> get_argp0:
 17354 00004D91 AC                  <1> 	lodsb
 17355 00004D92 6650                <1> 	push	ax
 17356 00004D94 FEC9                <1> 	dec	cl
 17357 00004D96 75F9                <1>         jnz     short get_argp0
 17358 00004D98 8B35[F8740000]      <1> 	mov	esi, [nbase]
 17359                              <1> 	; 21/07/2015
 17360 00004D9E 0FB6C5              <1> 	movzx	eax, ch
 17361 00004DA1 0105[F8740000]      <1> 	add	[nbase], eax
 17362 00004DA7 662905[FC740000]    <1> 	sub	[ncount], ax
 17363                              <1> get_argp1:
 17364 00004DAE AC                  <1> 	lodsb
 17365 00004DAF FECD                <1> 	dec	ch
 17366 00004DB1 743D                <1>         jz      short get_argp3
 17367 00004DB3 6650                <1>         push	ax
 17368 00004DB5 EBF7                <1> 	jmp     short get_argp1
 17369                              <1> get_argpk:
 17370                              <1> 	; Argument is in kernel's memory space
 17371 00004DB7 66C705[FC740000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
 17372 00004DBF 10                  <1>
 17373 00004DC0 8935[F8740000]      <1> 	mov	[nbase], esi
 17374 00004DC6 8305[F8740000]04    <1> 	add	dword [nbase], 4
 17375 00004DCD 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
 17376 00004DCF C3                  <1> 	retn
 17377                              <1> get_argp2:
 17378                              <1> 	; 21/07/2015
 17379                              <1> 	;mov	eax, 4
 17380 00004DD0 8B15[F8740000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
 17381 00004DD6 0105[F8740000]      <1> 	add	[nbase], eax
 17382 00004DDC 662905[FC740000]    <1> 	sub	[ncount], ax
 17383                              <1> 	;
 17384 00004DE3 8B02                <1> 	mov	eax, [edx]
 17385 00004DE5 C3                  <1> 	retn
 17386                              <1> get_argp_err:
 17387 00004DE6 A3[D5740000]        <1> 	mov	[u.error], eax
 17388 00004DEB E98CF2FFFF          <1> 	jmp	error
 17389                              <1> get_argp3:
 17390 00004DF0 B103                <1> 	mov	cl, 3
 17391                              <1> get_argp4:
 17392 00004DF2 C1E008              <1> 	shl	eax, 8
 17393 00004DF5 665A                <1> 	pop	dx
 17394 00004DF7 88D0                <1> 	mov 	al, dl
 17395 00004DF9 E2F7                <1>         loop    get_argp4
 17396                              <1> 	;pop	esi
 17397 00004DFB C3                  <1> 	retn	
 17398                              <1> 
 17399                              <1> sysfstat: 
 17400                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17401                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17402                              <1> 	;
 17403                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
 17404                              <1> 	; on open files instead of files given by name. It puts the
 17405                              <1> 	; buffer address on the stack, gets the i-number and
 17406                              <1> 	; checks to see if the file is open for reading or writing.
 17407                              <1> 	; If the file is open for writing (i-number is negative)
 17408                              <1> 	; the i-number is set positive and a branch into 'sysstat'
 17409                              <1> 	; is made.	
 17410                              <1> 	;
 17411                              <1> 	; Calling sequence:
 17412                              <1> 	;	sysfstat; buf
 17413                              <1> 	; Arguments:
 17414                              <1> 	;	buf - buffer address
 17415                              <1> 	;
 17416                              <1> 	; Inputs: *u.r0 - file descriptor
 17417                              <1> 	; Outputs: buffer is loaded with file information
 17418                              <1> 	; ...............................................................
 17419                              <1> 	;				
 17420                              <1> 	; Retro UNIX 8086 v1 modification:
 17421                              <1> 	;       'sysfstat' system call has two arguments; so,
 17422                              <1> 	;	* 1st argument, file descriptor is in BX register
 17423                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 17424                              <1> 
 17425                              <1> 	; / set status of open file
 17426                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
 17427 00004DFC 51                  <1> 	push	ecx
 17428                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
 17429                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
 17430                              <1> 		; jsr r0,getf / get the files i-number
 17431                              <1> 	; BX = file descriptor (file number)
 17432 00004DFD E8FF000000          <1> 	call	getf1
 17433 00004E02 6621C0              <1> 	and	ax, ax ; i-number of the file
 17434                              <1> 		; tst	r1 / is it 0?
 17435                              <1> 	;jz	error
 17436                              <1> 		; beq error3 / yes, error
 17437 00004E05 750F                <1> 	jnz	short sysfstat1
 17438 00004E07 C705[D5740000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 17439 00004E0F 0000                <1>
 17440 00004E11 E966F2FFFF          <1> 	jmp	error
 17441                              <1> sysfstat1:
 17442 00004E16 80FC80              <1> 	cmp	ah, 80h
 17443 00004E19 7223                <1>         jb      short sysstat1
 17444                              <1> 		; bgt 1f / if i-number is negative (open for writing)
 17445 00004E1B 66F7D8              <1> 	neg	ax
 17446                              <1> 		; neg r1 / make it positive, then branch
 17447 00004E1E EB1E                <1> 	jmp	short sysstat1
 17448                              <1> 		; br 1f / to 1f
 17449                              <1> sysstat:
 17450                              <1> 	; 18/10/2015
 17451                              <1> 	; 07/10/2015
 17452                              <1> 	; 02/09/2015
 17453                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17454                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17455                              <1> 	;
 17456                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
 17457                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
 17458                              <1> 	; long and information about the file placed in it.	
 17459                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
 17460                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
 17461                              <1> 	; is then loaded and the results are given in the UNIX
 17462                              <1> 	; Programmers Manual sysstat (II).	
 17463                              <1> 	;
 17464                              <1> 	; Calling sequence:
 17465                              <1> 	;	sysstat; name; buf
 17466                              <1> 	; Arguments:
 17467                              <1> 	;	name - points to the name of the file
 17468                              <1> 	;	buf - address of a 34 bytes buffer
 17469                              <1> 	; Inputs: -
 17470                              <1> 	; Outputs: buffer is loaded with file information
 17471                              <1> 	; ...............................................................
 17472                              <1> 	;				
 17473                              <1> 	; Retro UNIX 8086 v1 modification: 
 17474                              <1> 	;       'sysstat' system call has two arguments; so,
 17475                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 17476                              <1> 	;	to get sysstat system call arguments from the user;
 17477                              <1> 	;	* 1st argument, name is pointed to by BX register
 17478                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 17479                              <1> 	;
 17480                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 17481                              <1> 	;	      arguments which were in these registers;
 17482                              <1> 	;	      but, it returns by putting the 1st argument
 17483                              <1> 	;	      in 'u.namep' and the 2nd argument
 17484                              <1> 	;	      on top of stack. (1st argument is offset of the
 17485                              <1> 	;	      file/path name in the user's program segment.)		 	
 17486                              <1> 	
 17487                              <1> 	; / ; name of file; buffer - get files status
 17488                              <1> 		; jsr r0,arg2 / get the 2 arguments
 17489 00004E20 891D[98740000]      <1> 	mov	[u.namep], ebx
 17490 00004E26 51                  <1> 	push	ecx
 17491 00004E27 E80C010000          <1> 	call	namei
 17492                              <1> 		; jsr r0,namei / get the i-number for the file
 17493                              <1> 	;jc	error
 17494                              <1> 		; br error3 / no such file, error
 17495 00004E2C 7310                <1> 	jnc	short sysstat1
 17496                              <1> 	; pop 	ecx
 17497                              <1> sysstat_err0:
 17498                              <1> 	; 'file not found !' error
 17499 00004E2E C705[D5740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17500 00004E36 0000                <1>
 17501 00004E38 E93FF2FFFF          <1> 	jmp	error
 17502                              <1> 
 17503 00004E3D 00                  <1> statx: db 0
 17504                              <1> 
 17505                              <1> sysstat1: ; 1:
 17506 00004E3E E8E5080000          <1> 	call	iget
 17507                              <1> 		; jsr r0,iget / get the i-node into core
 17508                              <1> 	; 07/10/2015 (ax = [ii], inode number)
 17509                              <1> 	; 02/09/2015
 17510 00004E43 8F05[A0740000]      <1> 	pop	dword [u.base]
 17511                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
 17512 00004E49 E858000000          <1> 	call	sysstat_gpa ; get physical address
 17513 00004E4E 730A                <1> 	jnc 	short sysstat2
 17514                              <1> sysstat_err1:
 17515 00004E50 A3[D5740000]        <1> 	mov	dword [u.error], eax ; error code
 17516 00004E55 E922F2FFFF          <1> 	jmp	error
 17517                              <1> sysstat2:
 17518 00004E5A A0[62740000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
 17519 00004E5F AA                  <1> 	stosb
 17520 00004E60 FF05[A0740000]      <1> 	inc 	dword [u.base]
 17521 00004E66 6649                <1> 	dec 	cx
 17522 00004E68 7505                <1> 	jnz	short sysstat3
 17523 00004E6A E837000000          <1> 	call	sysstat_gpa
 17524                              <1> 	;jc	short sysstat_err1
 17525                              <1> sysstat3:
 17526 00004E6F A0[63740000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
 17527 00004E74 AA                  <1> 	stosb
 17528                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
 17529 00004E75 FF05[A0740000]      <1> 	inc 	dword [u.base]
 17530                              <1> 	;dec 	word [u.pcount]
 17531 00004E7B 6649                <1> 	dec	cx
 17532 00004E7D 7505                <1> 	jnz	short sysstat4
 17533 00004E7F E822000000          <1> 	call	sysstat_gpa
 17534                              <1> 	;jc	short sysstat_err1	
 17535                              <1> sysstat4:
 17536 00004E84 BE[56710000]        <1> 	mov	esi, inode
 17537                              <1> 		; mov $inode,r2 / r2 points to i-node
 17538                              <1> sysstat5: ; 1:
 17539 00004E89 A4                  <1> 	movsb
 17540                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
 17541 00004E8A FF05[A0740000]      <1> 	inc 	dword [u.base]
 17542                              <1> 	;dec 	word [u.pcount]
 17543 00004E90 6649                <1> 	dec	cx
 17544 00004E92 7505                <1> 	jnz	short sysstat6
 17545 00004E94 E80D000000          <1> 	call	sysstat_gpa
 17546                              <1> 	;jc	short sysstat_err1
 17547                              <1> sysstat6:		
 17548 00004E99 81FE[76710000]      <1> 	cmp	esi, inode + 32
 17549                              <1> 		; cmp r2,$inode+32 / done?
 17550 00004E9F 75E8                <1> 	jne	short sysstat5
 17551                              <1> 		; bne 1b / no, go back
 17552 00004EA1 E9F6F1FFFF          <1> 	jmp	sysret
 17553                              <1> 		; br sysret3 / return through sysret
 17554                              <1> 	;
 17555                              <1> sysstat_gpa: ; get physical address of file status buffer
 17556                              <1> 	; 02/09/2015
 17557 00004EA6 8B1D[A0740000]      <1> 	mov 	ebx, [u.base]
 17558                              <1> 	; 07/10/2015
 17559 00004EAC E819E8FFFF          <1> 	call	get_physical_addr ; get physical address
 17560                              <1> 	;jc	short sysstat_gpa1
 17561 00004EB1 729D                <1> 	jc	short sysstat_err1
 17562                              <1> 	; 18/10/2015
 17563 00004EB3 89C7                <1> 	mov	edi, eax ; physical address
 17564                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
 17565                              <1> ;sysstat_gpa1:
 17566 00004EB5 C3                  <1> 	retn
 17567                              <1> 
 17568                              <1> fclose:
 17569                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
 17570                              <1> 	;            (32 bit offset pointer modification)
 17571                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
 17572                              <1> 	;
 17573                              <1> 	; Given the file descriptor (index to the u.fp list)
 17574                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
 17575                              <1> 	; If i-node is active (i-number > 0) the entry in 
 17576                              <1> 	; u.fp list is cleared. If all the processes that opened
 17577                              <1> 	; that file close it, then fsp etry is freed and the file
 17578                              <1> 	; is closed. If not a return is taken. 
 17579                              <1> 	; If the file has been deleted while open, 'anyi' is called
 17580                              <1> 	; to see anyone else has it open, i.e., see if it is appears
 17581                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
 17582                              <1> 	; a check is made to see if the file is special.	
 17583                              <1> 	;
 17584                              <1> 	; INPUTS ->
 17585                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
 17586                              <1> 	;    u.fp - list of entries in the fsp table
 17587                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
 17588                              <1> 	; OUTPUTS ->
 17589                              <1> 	;    r1 - contains the same file descriptor
 17590                              <1> 	;    r2 - contains i-number
 17591                              <1> 	;
 17592                              <1> 	; ((AX = R1))
 17593                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
 17594                              <1> 	;
 17595                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
 17596                              <1> 	;              if i-number of the file is 0. (error)  	
 17597                              <1> 	;
 17598 00004EB6 0FB7D0              <1> 	movzx	edx, ax ; **
 17599 00004EB9 6650                <1> 	push	ax ; ***
 17600                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
 17601                              <1> 			     ; / the index to u.fp list)
 17602 00004EBB E83F000000          <1> 	call	getf
 17603                              <1> 		; jsr r0,getf / r1 contains i-number, 
 17604                              <1> 			    ; / cdev has device =, u.fofp 
 17605                              <1> 			    ; / points to 3rd word of fsp entry
 17606 00004EC0 6683F801            <1> 	cmp	ax, 1 ; r1
 17607                              <1> 		; tst r1 / is i-number 0?
 17608 00004EC4 7236                <1> 	jb	short fclose_2
 17609                              <1> 		; beq 1f / yes, i-node not active so return
 17610                              <1> 		; tst (r0)+ / no, jump over error return
 17611 00004EC6 89D3                <1> 	mov	ebx, edx ; **
 17612 00004EC8 6689C2              <1> 	mov 	dx, ax ; *
 17613                              <1> 		; mov r1,r2 / move i-number to r2 ;*
 17614                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
 17615                              <1> 			    ; / which is index to u.fp ; **
 17616 00004ECB C683[86740000]00    <1> 	mov	byte [ebx+u.fp], 0
 17617                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
 17618 00004ED2 8B1D[90740000]      <1> 	mov	ebx, [u.fofp]
 17619                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
 17620                              <1> fclose_0:
 17621 00004ED8 FE4B04              <1> 	dec	byte [ebx+4] ; 18/06/2015
 17622                              <1> 		; decb 2(r1) / decrement the number of processes 
 17623                              <1> 			   ; / that have opened the file
 17624 00004EDB 791F                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
 17625                              <1> 		; bge 1f / if all processes haven't closed the file, return
 17626                              <1> 	;
 17627 00004EDD 6652                <1> 	push	dx ;*
 17628                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
 17629 00004EDF 6631C0              <1> 	xor	ax, ax ; 0
 17630 00004EE2 668943FC            <1> 	mov	[ebx-4], ax ; 0
 17631                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
 17632 00004EE6 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
 17633                              <1> 		; tstb	3(r1) / has this file been deleted
 17634 00004EE9 20C0                <1> 	and	al, al
 17635 00004EEB 7408                <1> 	jz	short fclose_1
 17636                              <1> 		; beq 2f / no, branch
 17637 00004EED 6689D0              <1> 	mov	ax, dx ; *
 17638                              <1> 		; mov r2,r1 / yes, put i-number back into r1
 17639                              <1> 	; AX = inode number
 17640 00004EF0 E868040000          <1> 	call	anyi
 17641                              <1> 		; jsr r0,anyi / free all blocks related to i-number
 17642                              <1> 			    ; / check if file appears in fsp again
 17643                              <1> fclose_1: ; 2:
 17644 00004EF5 6658                <1> 	pop	ax ; *
 17645                              <1> 		; mov (sp)+,r1 / put i-number back into r1
 17646 00004EF7 E8D8100000          <1> 	call	iclose ; close if it is special file 
 17647                              <1> 		; jsr r0,iclose / check to see if its a special file
 17648                              <1> fclose_2: ; 1:
 17649 00004EFC 6658                <1> 	pop	ax ; ***
 17650                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
 17651 00004EFE C3                  <1> 	retn
 17652                              <1> 		; rts r0
 17653                              <1> 
 17654                              <1> getf:	; / get the device number and the i-number of an open file
 17655                              <1> 	; 13/05/2015
 17656                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 17657                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 17658                              <1> 	;
 17659 00004EFF 89C3                <1> 	mov	ebx, eax
 17660                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
 17661 00004F01 83FB0A              <1> 	cmp	ebx, 10
 17662                              <1> 		; cmp r1,$10. / user limited to 10 open files
 17663 00004F04 730A                <1>         jnb	short getf2 ; 13/05/2015
 17664                              <1> 	;jnb     error
 17665                              <1> 		; bhis error3 / u.fp is table of users open files, 
 17666                              <1> 			    ; / index in fsp table
 17667 00004F06 8A9B[86740000]      <1> 	mov	bl, [ebx+u.fp]
 17668                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
 17669                              <1> 		                  ; / in fsp table
 17670 00004F0C 08DB                <1> 	or	bl, bl
 17671 00004F0E 7503                <1> 	jnz	short getf3
 17672                              <1> 	;jz	short getf4
 17673                              <1> 		; beq 1f / if its zero return
 17674                              <1> getf2:
 17675                              <1> 	; 'File not open !' error (ax=0)
 17676 00004F10 29C0                <1> 	sub	eax, eax
 17677 00004F12 C3                  <1> 	retn
 17678                              <1> getf3:	
 17679                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
 17680                              <1> 	;
 17681                              <1> 	; 'fsp' table (10 bytes/entry)
 17682                              <1> 	; bit 15				   bit 0
 17683                              <1> 	; ---|-------------------------------------------
 17684                              <1> 	; r/w|		i-number of open file
 17685                              <1> 	; ---|-------------------------------------------
 17686                              <1> 	;		   device number
 17687                              <1> 	; -----------------------------------------------
 17688                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 17689                              <1> 	; -----------------------------------------------
 17690                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 17691                              <1> 	; ----------------------|------------------------
 17692                              <1> 	;  flag that says file 	| number of processes
 17693                              <1> 	;   has been deleted	| that have file open 
 17694                              <1> 	; ----------------------|------------------------
 17695                              <1> 	;
 17696 00004F13 B80A000000          <1> 	mov	eax, 10
 17697 00004F18 F6E3                <1> 	mul	bl
 17698 00004F1A BB[50720000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
 17699 00004F1F 01C3                <1> 	add	ebx, eax
 17700                              <1> 		; asl r1
 17701                              <1> 		; asl r1 / multiply by 8 to get index into 
 17702                              <1> 		       ; / fsp table entry
 17703                              <1> 		; asl r1
 17704                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
 17705                              <1> 			      ; / in the fsp entry
 17706 00004F21 891D[90740000]      <1> 	mov	[u.fofp], ebx
 17707                              <1> 		; mov r1,u.fofp / save address of 3rd word 
 17708                              <1> 			      ; / in fsp entry in u.fofp
 17709 00004F27 4B                  <1> 	dec	ebx
 17710 00004F28 4B                  <1> 	dec	ebx
 17711 00004F29 668B03              <1> 	mov	ax, [ebx]
 17712                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
 17713 00004F2C 66A3[66740000]      <1> 	mov	[cdev], ax ; ;;in fact (!) 
 17714                              <1> 			     ;;dev number is in 1 byte
 17715                              <1> 		; mov -(r1),cdev / remove the device number  cdev
 17716 00004F32 4B                  <1> 	dec	ebx
 17717 00004F33 4B                  <1> 	dec	ebx
 17718 00004F34 668B03              <1> 	mov	ax, [ebx]
 17719                              <1> 		; mov -(r1),r1 / and the i-number  r1
 17720                              <1> getf4:	; 1:
 17721 00004F37 C3                  <1> 	retn
 17722                              <1> 		; rts r0
 17723                              <1> 
 17724                              <1> namei:
 17725                              <1> 	; 04/12/2015 (14 byte file names)
 17726                              <1> 	; 18/10/2015 (nbase, ncount)
 17727                              <1> 	; 12/10/2015
 17728                              <1> 	; 21/08/2015
 17729                              <1> 	; 18/07/2015
 17730                              <1> 	; 02/07/2015
 17731                              <1> 	; 17/06/2015
 17732                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
 17733                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 17734                              <1> 	;
 17735                              <1> 	; 'namei' takes a file path name and returns i-number of
 17736                              <1> 	; the file in the current directory or the root directory
 17737                              <1> 	; (if the first character of the pathname is '/').	
 17738                              <1> 	;
 17739                              <1> 	; INPUTS ->
 17740                              <1> 	;    u.namep - points to a file path name
 17741                              <1> 	;    u.cdir - i-number of users directory
 17742                              <1> 	;    u.cdev - device number on which user directory resides	
 17743                              <1> 	; OUTPUTS ->
 17744                              <1> 	;    r1 - i-number of file
 17745                              <1> 	;    cdev
 17746                              <1> 	;    u.dirbuf - points to directory entry where a match 
 17747                              <1> 	;               occurs in the search for file path name.
 17748                              <1> 	;	        If no match u.dirb points to the end of 
 17749                              <1> 	;               the directory and r1 = i-number of the current
 17750                              <1> 	;	        directory.	
 17751                              <1> 	; ((AX = R1))
 17752                              <1> 	;
 17753                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
 17754                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 17755                              <1> 	;
 17756                              <1> 
 17757 00004F38 66A1[84740000]      <1> 	mov	ax, [u.cdir]
 17758                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
 17759                              <1> 			      ; / in r1
 17760 00004F3E 668B15[CA740000]    <1> 	mov	dx, [u.cdrv]
 17761 00004F45 668915[66740000]    <1> 	mov	[cdev], dx 	    ; NOTE: Retro UNIX 8086 v1 
 17762                              <1> 				    ; device/drive number is in 1 byte, 
 17763                              <1> 				    ; not in 1 word!
 17764                              <1> 		; mov u.cdev,cdev / device number for users directory 
 17765                              <1> 				; / into cdev
 17766                              <1> 	; 12/10/2015
 17767                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 17768                              <1>       	 ; convert virtual (pathname) addr to physical address
 17769 00004F4C E82C010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
 17770                              <1> 		; esi = physical address of [u.namep]
 17771                              <1> 		; ecx = byte count in the page
 17772 00004F51 803E2F              <1> 	cmp	byte [esi], '/'
 17773                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
 17774 00004F54 751E                <1> 	jne	short namei_1
 17775                              <1> 		; bne 1f
 17776 00004F56 FF05[98740000]      <1> 	inc	dword [u.namep]
 17777                              <1> 		; inc u.namep / go to next char
 17778 00004F5C 6649                <1> 	dec	cx ; remain byte count in the page
 17779 00004F5E 7506                <1> 	jnz	short namei_0
 17780                              <1> 	; 12/10/2015
 17781 00004F60 E818010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 17782                              <1> 		; esi = physical address (page start + offset)
 17783                              <1> 		; ecx = byte count in the page
 17784 00004F65 4E                  <1> 	dec	esi
 17785                              <1> namei_0:
 17786 00004F66 46                  <1> 	inc 	esi  ; go to next char
 17787 00004F67 66A1[70740000]      <1> 	mov	ax, [rootdir] ; 09/07/2013
 17788                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
 17789 00004F6D C605[66740000]00    <1> 	mov	byte [cdev], 0
 17790                              <1> 		; clr cdev / clear device number
 17791                              <1> namei_1: ; 1:
 17792 00004F74 F606FF              <1> 	test	byte [esi], 0FFh
 17793 00004F77 74BE                <1> 	jz	short getf4
 17794                              <1> 	;jz      nig
 17795                              <1> 		; tstb *u.namep / is the character in file name a nul
 17796                              <1> 		; beq nig / yes, end of file name reached; 
 17797                              <1> 			; / branch to "nig"
 17798                              <1> namei_2: ; 1:
 17799                              <1> 	; 18/10/2015
 17800 00004F79 8935[F8740000]      <1> 	mov 	[nbase], esi
 17801 00004F7F 66890D[FC740000]    <1> 	mov 	[ncount], cx
 17802                              <1> 	;
 17803                              <1> 	;mov	dx, 2
 17804 00004F86 B202                <1> 	mov	dl, 2 ; user flag (read, non-owner)
 17805 00004F88 E876080000          <1> 	call	access
 17806                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
 17807                              <1> 	; 'access' will not return here if user has not "r" permission !
 17808 00004F8D 66F705[56710000]00- <1> 	test 	word [i.flgs], 4000h
 17809 00004F95 40                  <1>
 17810                              <1> 		; bit $40000,i.flgs / directory i-node?
 17811 00004F96 746A                <1>         jz      short namei_err
 17812                              <1> 		; beq error3 / no, got an error
 17813                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 17814 00004F98 31C0                <1> 	xor	eax, eax
 17815 00004F9A A3[9C740000]        <1> 	mov	[u.off], eax ; 0
 17816 00004F9F 66A1[5A710000]      <1> 	mov	ax, [i.size]
 17817 00004FA5 A3[94740000]        <1> 	mov	[u.dirp], eax
 17818                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
 17819                              <1> 		; clr u.off / u.off is file offset used by user
 17820 00004FAA C705[90740000]-     <1> 	mov	dword [u.fofp], u.off
 17821 00004FB0 [9C740000]          <1>
 17822                              <1> 		; mov $u.off,u.fofp / u.fofp is a pointer to 
 17823                              <1> 				  ; / the offset portion of fsp entry
 17824                              <1> namei_3: ; 2:
 17825 00004FB4 C705[A0740000]-     <1> 	mov	dword [u.base], u.dirbuf
 17826 00004FBA [B2740000]          <1>
 17827                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
 17828                              <1> 				    ; / copied from a directory
 17829 00004FBE C705[A4740000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
 17830 00004FC6 0000                <1>
 17831                              <1>  		; mov $10.,u.count / u.count is byte count 
 17832                              <1> 				 ; / for reads and writes
 17833 00004FC8 66A1[62740000]      <1> 	mov 	ax, [ii]
 17834                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
 17835 00004FCE FE05[E7740000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
 17836 00004FD4 E82F090000          <1>     	call	readi
 17837                              <1> 		; jsr r0,readi / read 10. bytes of file 
 17838                              <1> 		      ; with i-number (r1); i.e. read a directory entry
 17839 00004FD9 8B0D[A8740000]      <1> 	mov 	ecx, [u.nread]
 17840 00004FDF 09C9                <1> 	or 	ecx, ecx
 17841                              <1> 		; tst u.nread
 17842 00004FE1 741B                <1> 	jz	short nib
 17843                              <1> 		; ble nib / gives error return
 17844                              <1> 	;
 17845 00004FE3 668B1D[B2740000]    <1> 	mov 	bx, [u.dirbuf]
 17846 00004FEA 6621DB              <1> 	and 	bx, bx       
 17847                              <1> 		; tst u.dirbuf /
 17848 00004FED 7522                <1> 	jnz	short namei_4
 17849                              <1> 		; bne 3f / branch when active directory entry 
 17850                              <1> 		       ; / (i-node word in entry non zero)
 17851 00004FEF A1[9C740000]        <1> 	mov	eax, [u.off]
 17852 00004FF4 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
 17853 00004FF7 A3[94740000]        <1> 	mov	[u.dirp], eax
 17854                              <1> 		; mov u.off,u.dirp
 17855                              <1> 		; sub $10.,u.dirp
 17856 00004FFC EBB6                <1> 	jmp	short namei_3
 17857                              <1> 		; br 2b
 17858                              <1> 
 17859                              <1> 	; 18/07/2013
 17860                              <1> nib: 
 17861 00004FFE 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
 17862 00005000 F9                  <1> 	stc
 17863                              <1> nig:
 17864 00005001 C3                  <1> 	retn
 17865                              <1> 
 17866                              <1> namei_err:
 17867                              <1> 	; 16/06/2015
 17868 00005002 C705[D5740000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
 17869 0000500A 0000                <1>
 17870 0000500C E96BF0FFFF          <1> 	jmp	error
 17871                              <1> 
 17872                              <1> namei_4: ; 3:
 17873                              <1> 	; 18/10/2015
 17874                              <1> 	; 12/10/2015
 17875                              <1> 	; 21/08/2015
 17876                              <1> 	; 18/07/2015
 17877 00005011 8B2D[98740000]      <1> 	mov	ebp, [u.namep]
 17878                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
 17879 00005017 BF[B4740000]        <1> 	mov 	edi, u.dirbuf + 2
 17880                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
 17881                              <1> 	; 18/10/2015
 17882 0000501C 8B35[F8740000]      <1> 	mov	esi, [nbase]	
 17883 00005022 668B0D[FC740000]    <1> 	mov	cx, [ncount]
 17884                              <1> 	;
 17885 00005029 6621C9              <1> 	and	cx, cx
 17886 0000502C 7505                <1> 	jnz	short namei_5	
 17887                              <1> 	;
 17888 0000502E E850000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 17889                              <1> 		; esi = physical address (page start + offset)
 17890                              <1> 		; ecx = byte count in the page
 17891                              <1> namei_5: ; 3:
 17892 00005033 45                  <1> 	inc	ebp ; 18/07/2015
 17893 00005034 AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
 17894                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
 17895 00005035 08C0                <1> 	or 	al, al
 17896 00005037 741D                <1> 	jz 	short namei_7
 17897                              <1> 		; beq 3f / if char is nul, then the last char in string
 17898                              <1> 			; / has been moved
 17899 00005039 3C2F                <1> 	cmp	al, '/'
 17900                              <1> 		; cmp r4,$'/ / is char a </>
 17901 0000503B 7419                <1> 	je 	short namei_7
 17902                              <1> 		; beq 3f	
 17903                              <1> 	; 12/10/2015
 17904 0000503D 6649                <1> 	dec	cx ; remain byte count in the page
 17905 0000503F 7505                <1> 	jnz	short namei_6
 17906 00005041 E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 17907                              <1> 		; esi = physical address (page start + offset)
 17908                              <1> 		; ecx = byte count in the page
 17909                              <1> namei_6:
 17910 00005046 81FF[C2740000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 17911                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
 17912                              <1> 				     ; / all 8 bytes of file name
 17913 0000504C 74E5                <1> 	je	short namei_5
 17914                              <1> 		; beq 3b
 17915 0000504E AE                  <1> 	scasb	
 17916                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
 17917                              <1> 			      ; / char read from directory
 17918 0000504F 74E2                <1> 	je 	short namei_5
 17919                              <1> 		; beq 3b / branch if chars match
 17920                              <1> 
 17921 00005051 E95EFFFFFF          <1>         jmp    namei_3 ; 2b
 17922                              <1> 		; br 2b / file names do not match go to next directory entry
 17923                              <1> namei_7: ; 3:
 17924 00005056 81FF[C2740000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 17925                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
 17926 0000505C 740A                <1> 	je	short namei_8
 17927                              <1> 		; beq 3f
 17928 0000505E 8A27                <1> 	mov 	ah, [edi]
 17929                              <1> 	;inc 	edi 
 17930 00005060 20E4                <1> 	and 	ah, ah
 17931                              <1> 		; tstb (r3)+ /
 17932 00005062 0F854CFFFFFF        <1>         jnz     namei_3
 17933                              <1> 		; bne 2b
 17934                              <1> namei_8: ; 3
 17935 00005068 892D[98740000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
 17936                              <1> 		; mov r2,u.namep / u.namep points to char 
 17937                              <1> 			       ; / following a / or nul
 17938                              <1> 	;mov	bx, [u.dirbuf]
 17939                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
 17940                              <1> 				; / entry to r1
 17941 0000506E 20C0                <1> 	and 	al, al
 17942                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
 17943                              <1> 		      ;  / if r4 = </> then go to next directory
 17944                              <1> 	; mov	ax, bx
 17945 00005070 66A1[B2740000]      <1> 	mov 	ax, [u.dirbuf] ; 17/06/2015
 17946 00005076 0F85FDFEFFFF        <1>         jnz     namei_2 
 17947                              <1> 		; bne 1b
 17948                              <1> 	; AX = i-number of the file
 17949                              <1> ;;nig:
 17950 0000507C C3                  <1> 	retn
 17951                              <1> 		; tst (r0)+ / gives non-error return
 17952                              <1> ;;nib:
 17953                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
 17954                              <1> 		       ; ax = 0 -> file not found 
 17955                              <1> ;;	stc	; 27/05/2013
 17956                              <1> ;;	retn
 17957                              <1> 		; rts r0
 17958                              <1> 
 17959                              <1> trans_addr_nmbp:
 17960                              <1> 	; 18/10/2015
 17961                              <1> 	; 12/10/2015
 17962 0000507D 8B2D[98740000]      <1> 	mov 	ebp, [u.namep]
 17963                              <1> trans_addr_nm: 
 17964                              <1> 	; Convert virtual (pathname) address to physical address
 17965                              <1> 	; (Retro UNIX 386 v1 feature only !)
 17966                              <1> 	; 18/10/2015
 17967                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
 17968                              <1> 	; 02/07/2015
 17969                              <1> 	; 17/06/2015
 17970                              <1> 	; 16/06/2015
 17971                              <1> 	;
 17972                              <1> 	; INPUTS: 
 17973                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
 17974                              <1> 	;	[u.pgdir] = user's page directory
 17975                              <1> 	; OUTPUT:
 17976                              <1> 	;       esi = physical address of the pathname
 17977                              <1> 	;	ecx = remain byte count in the page
 17978                              <1> 	;
 17979                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI)
 17980                              <1> 	;
 17981 00005083 833D[DD740000]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
 17982 0000508A 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
 17983                              <1> 				     ; it is already physical address
 17984 0000508C 50                  <1>    	push	eax	
 17985 0000508D 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
 17986 0000508F E836E6FFFF          <1>        	call	get_physical_addr ; get physical address
 17987 00005094 7204                <1> 	jc	short tr_addr_nm_err
 17988                              <1> 	; 18/10/2015
 17989                              <1> 	; eax = physical address 
 17990                              <1> 	; cx = remain byte count in page (1-4096) 
 17991                              <1> 		; 12/10/2015 (cx = [u.pncount])
 17992 00005096 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
 17993 00005098 58                  <1> 	pop	eax 
 17994 00005099 C3                  <1> 	retn
 17995                              <1> 
 17996                              <1> tr_addr_nm_err:
 17997 0000509A A3[D5740000]        <1> 	mov	[u.error], eax
 17998                              <1> 	;pop 	eax
 17999 0000509F E9D8EFFFFF          <1> 	jmp	error
 18000                              <1> 
 18001                              <1> trans_addr_nmk:
 18002                              <1> 	; 12/10/2015
 18003                              <1> 	; 02/07/2015
 18004 000050A4 8B35[98740000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
 18005 000050AA 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
 18006 000050AE C3                  <1> 	retn
 18007                              <1> 
 18008                              <1> syschdir:
 18009                              <1> 	; / makes the directory specified in the argument
 18010                              <1> 	; / the current directory
 18011                              <1> 	;
 18012                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18013                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18014                              <1> 	;
 18015                              <1> 	; 'syschdir' makes the directory specified in its argument
 18016                              <1> 	; the current working directory.
 18017                              <1> 	;
 18018                              <1> 	; Calling sequence:
 18019                              <1> 	;	syschdir; name
 18020                              <1> 	; Arguments:
 18021                              <1> 	;	name - address of the path name of a directory
 18022                              <1> 	;	       terminated by nul byte.	
 18023                              <1> 	; Inputs: -
 18024                              <1> 	; Outputs: -
 18025                              <1> 	; ...............................................................
 18026                              <1> 	;				
 18027                              <1> 	; Retro UNIX 8086 v1 modification:
 18028                              <1> 	;	 The user/application program puts address of 
 18029                              <1> 	;	 the path name in BX register as 'syschdir' 
 18030                              <1> 	; 	 system call argument.
 18031                              <1> 
 18032 000050AF 891D[98740000]      <1> 	mov	[u.namep], ebx
 18033                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
 18034 000050B5 E87EFEFFFF          <1> 	call	namei
 18035                              <1> 		; jsr r0,namei / find its i-number
 18036                              <1> 	;jc	error
 18037                              <1> 		; br error3
 18038 000050BA 730F                <1> 	jnc	short syschdir0
 18039                              <1> 	; 'directory not found !' error
 18040 000050BC C705[D5740000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
 18041 000050C4 0000                <1>
 18042 000050C6 E9B1EFFFFF          <1> 	jmp	error
 18043                              <1> syschdir0:
 18044 000050CB E833070000          <1> 	call	access
 18045                              <1> 		; jsr r0,access; 2 / get i-node into core
 18046 000050D0 66F705[56710000]00- <1> 	test	word [i.flgs], 4000h
 18047 000050D8 40                  <1>
 18048                              <1> 		; bit $40000,i.flgs / is it a directory?
 18049                              <1> 	;jz	error 
 18050                              <1> 		; beq error3 / no error
 18051 000050D9 750F                <1> 	jnz	short syschdir1
 18052 000050DB C705[D5740000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 18053 000050E3 0000                <1>
 18054 000050E5 E992EFFFFF          <1> 	jmp	error
 18055                              <1> syschdir1:
 18056 000050EA 66A3[84740000]      <1> 	mov	[u.cdir], ax
 18057                              <1> 		; mov r1,u.cdir / move i-number to users 
 18058                              <1> 			      ; / current directory
 18059 000050F0 66A1[66740000]      <1> 	mov	ax, [cdev]
 18060 000050F6 66A3[CA740000]      <1> 	mov	[u.cdrv], ax
 18061                              <1> 		; mov cdev,u.cdev / move its device to users 
 18062                              <1> 			        ; / current device
 18063 000050FC E99BEFFFFF          <1> 	jmp	sysret
 18064                              <1> 		; br sysret3
 18065                              <1> 	
 18066                              <1> syschmod: ; < change mode of file >
 18067                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18068                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 18069                              <1> 	;
 18070                              <1> 	; 'syschmod' changes mode of the file whose name is given as
 18071                              <1> 	; null terminated string pointed to by 'name' has it's mode 
 18072                              <1> 	; changed to 'mode'.
 18073                              <1> 	;
 18074                              <1> 	; Calling sequence:
 18075                              <1> 	;	syschmod; name; mode
 18076                              <1> 	; Arguments:
 18077                              <1> 	;	name - address of the file name
 18078                              <1> 	;	       terminated by null byte.
 18079                              <1> 	;	mode - (new) mode/flags < attributes >
 18080                              <1> 	;	
 18081                              <1> 	; Inputs: -
 18082                              <1> 	; Outputs: -
 18083                              <1> 	; ...............................................................
 18084                              <1> 	;				
 18085                              <1> 	; Retro UNIX 8086 v1 modification: 
 18086                              <1> 	;       'syschmod' system call has two arguments; so,
 18087                              <1> 	;	* 1st argument, name is pointed to by BX register
 18088                              <1> 	;	* 2nd argument, mode is in CX register
 18089                              <1> 	;
 18090                              <1> 	; Mode bits (Flags):
 18091                              <1> 	;	bit 0 - write permission for non-owner (1)
 18092                              <1> 	;	bit 1 - read permission for non-owner (2)
 18093                              <1> 	;	bit 2 - write permission for owner (4)
 18094                              <1> 	;	bit 3 - read permission for owner (8)
 18095                              <1> 	;	bit 4 - executable flag (16) 	
 18096                              <1> 	;	bit 5 - set user ID on execution flag (32) 
 18097                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
 18098                              <1> 	;	bit 12 - large file flag (4096)
 18099                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
 18100                              <1> 	;	bit 14 - directory flag (16384)
 18101                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
 18102                              <1> 
 18103                              <1> 	; / name; mode
 18104 00005101 E814000000          <1> 	call	isown
 18105                              <1> 		;jsr r0,isown / get the i-node and check user status
 18106 00005106 66F705[56710000]00- <1> 	test	word [i.flgs], 4000h
 18107 0000510E 40                  <1>
 18108                              <1> 		; bit	$40000,i.flgs / directory?
 18109 0000510F 7402                <1> 	jz	short syschmod1
 18110                              <1> 		; beq 2f / no
 18111                              <1> 	; AL = (new) mode
 18112 00005111 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
 18113                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
 18114                              <1> 			   ; / executable modes
 18115                              <1> syschmod1: ; 2:
 18116 00005113 A2[56710000]        <1> 	mov	[i.flgs], al	
 18117                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
 18118 00005118 EB42                <1> 	jmp	short isown1
 18119                              <1> 		; br 1f
 18120                              <1> 
 18121                              <1> isown:
 18122                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18123                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 18124                              <1> 	;
 18125                              <1> 	; 'isown' is given a file name (the 1st argument).
 18126                              <1> 	;  It find the i-number of that file via 'namei' 
 18127                              <1> 	;  then gets the i-node into core via 'iget'.
 18128                              <1> 	;  It then tests to see if the user is super user. 
 18129                              <1> 	;  If not, it cheks to see if the user is owner of 
 18130                              <1> 	;  the file. If he is not an error occurs.
 18131                              <1> 	;  If user is the owner 'setimod' is called to indicate
 18132                              <1> 	;  the inode has been modificed and the 2nd argument of
 18133                              <1> 	;  the call is put in r2.
 18134                              <1> 	;
 18135                              <1> 	; INPUTS ->
 18136                              <1> 	;    arguments of syschmod and syschown calls
 18137                              <1> 	; OUTPUTS ->
 18138                              <1> 	;    u.uid - id of user
 18139                              <1> 	;    imod - set to a 1
 18140                              <1> 	;    r2 - contains second argument of the system call				 	
 18141                              <1> 	;
 18142                              <1> 	;   ((AX=R2) output as 2nd argument)
 18143                              <1> 	;
 18144                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 18145                              <1> 	;
 18146                              <1> 		; jsr r0,arg2 / u.namep points to file name
 18147                              <1> 	;; ! 2nd argument on top of stack !
 18148                              <1> 	;; 22/06/2015 - 32 bit modifications
 18149                              <1> 	;; 07/07/2013
 18150 0000511A 891D[98740000]      <1> 	mov	[u.namep], ebx ;; 1st argument
 18151 00005120 51                  <1> 	push 	ecx ;; 2nd argument
 18152                              <1> 	;;
 18153 00005121 E812FEFFFF          <1> 	call	namei
 18154                              <1> 		; jsr r0,namei / get its i-number
 18155                              <1>        ; Retro UNIX 8086 v1 modification !
 18156                              <1>        ; ax = 0 -> file not found 
 18157                              <1> 	;and	ax, ax
 18158                              <1> 	;jz	error
 18159                              <1> 	;jc	error ; 27/05/2013
 18160                              <1> 		; br error3
 18161 00005126 730F                <1> 	jnc	short isown0
 18162                              <1> 	; 'file not found !' error
 18163 00005128 C705[D5740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 18164 00005130 0000                <1>
 18165 00005132 E945EFFFFF          <1> 	jmp	error
 18166                              <1> isown0:
 18167 00005137 E8EC050000          <1> 	call	iget
 18168                              <1> 		; jsr r0,iget / get i-node into core
 18169 0000513C A0[CC740000]        <1> 	mov	al, [u.uid] ; 02/08/2013
 18170 00005141 08C0                <1> 	or	al, al
 18171                              <1> 		; tstb u.uid / super user?
 18172 00005143 7417                <1> 	jz	short isown1
 18173                              <1> 		; beq 1f / yes, branch
 18174 00005145 3A05[59710000]      <1> 	cmp	al, [i.uid]
 18175                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
 18176                              <1> 				 ; / the file
 18177                              <1> 	;jne	error
 18178                              <1> 		; beq 1f / yes
 18179                              <1> 		; jmp error3 / no, error
 18180 0000514B 740F                <1> 	je	short isown1
 18181                              <1> 
 18182 0000514D C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
 18183 00005155 0000                <1>
 18184                              <1> 			;  'permission denied !' error
 18185 00005157 E920EFFFFF          <1> 	jmp	error
 18186                              <1> isown1: ; 1:
 18187 0000515C E8DA060000          <1> 	call	setimod
 18188                              <1> 		; jsr r0,setimod / indicates 
 18189                              <1> 		;	       ; / i-node has been modified
 18190 00005161 58                  <1> 	pop	eax ; 2nd argument
 18191                              <1> 		; mov (sp)+,r2 / mode is put in r2 
 18192                              <1> 		       ; / (u.off put on stack with 2nd arg)
 18193 00005162 C3                  <1> 	retn
 18194                              <1> 		; rts r0
 18195                              <1> 
 18196                              <1> ;;arg:  ; < get system call arguments >
 18197                              <1> 	; 'arg' extracts an argument for a routine whose call is 
 18198                              <1> 	; of form:
 18199                              <1> 	;	sys 'routine' ; arg1
 18200                              <1> 	;		or
 18201                              <1> 	;	sys 'routine' ; arg1 ; arg2
 18202                              <1> 	;		or
 18203                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
 18204                              <1> 	;	
 18205                              <1> 	; INPUTS ->
 18206                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
 18207                              <1> 	;	This pointers's value is actually the value of
 18208                              <1> 	;	update pc at the the trap to sysent (unkni) is
 18209                              <1> 	;	made to process the sys instruction
 18210                              <1> 	;    r0 - contains the return address for the routine
 18211                              <1> 	;	that called arg. The data in the word pointer 
 18212                              <1> 	;	to by the return address is used as address
 18213                              <1> 	;	in which the extracted argument is stored   		
 18214                              <1> 	;    	
 18215                              <1> 	; OUTPUTS ->
 18216                              <1> 	;    'address' - contains the extracted argument 
 18217                              <1> 	;    u.sp+18 - is incremented by 2 
 18218                              <1> 	;    r1 - contains the extracted argument
 18219                              <1> 	;    r0 - points to the next instruction to be
 18220                              <1> 	;	 executed in the calling routine.
 18221                              <1> 	;
 18222                              <1>   
 18223                              <1> 	; mov u.sp,r1
 18224                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
 18225                              <1> 			; / into argument of arg2
 18226                              <1> 	; add $2,18.(r1) / point pc on stack 
 18227                              <1> 			      ; / to next system argument
 18228                              <1> 	; rts r0
 18229                              <1> 
 18230                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
 18231                              <1> 	; 'arg2' takes first argument in system call
 18232                              <1> 	;  (pointer to name of the file) and puts it in location
 18233                              <1> 	;  u.namep; takes second argument and puts it in u.off
 18234                              <1> 	;  and on top of the stack
 18235                              <1> 	;	
 18236                              <1> 	; INPUTS ->
 18237                              <1> 	;    u.sp, r0
 18238                              <1> 	;    	
 18239                              <1> 	; OUTPUTS ->
 18240                              <1> 	;    u.namep
 18241                              <1> 	;    u.off 
 18242                              <1> 	;    u.off pushed on stack
 18243                              <1> 	;    r1
 18244                              <1> 	;
 18245                              <1> 
 18246                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
 18247                              <1> 				; / first arg in sys call
 18248                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
 18249                              <1> 				; / second arg in sys call
 18250                              <1> 	; mov r0,r1 / r0 points to calling routine
 18251                              <1> 	; mov (sp),r0 / put operation code back in r0
 18252                              <1> 	; mov u.off,(sp) / put pointer to second argument 
 18253                              <1> 			; / on stack
 18254                              <1> 	; jmp (r1) / return to calling routine
 18255                              <1> 
 18256                              <1> syschown: ; < change owner of file >
 18257                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18258                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18259                              <1> 	;
 18260                              <1> 	; 'syschown' changes the owner of the file whose name is given
 18261                              <1> 	; as null terminated string pointed to by 'name' has it's owner
 18262                              <1> 	; changed to 'owner'
 18263                              <1> 	;
 18264                              <1> 	; Calling sequence:
 18265                              <1> 	;	syschown; name; owner
 18266                              <1> 	; Arguments:
 18267                              <1> 	;	name - address of the file name
 18268                              <1> 	;	       terminated by null byte.
 18269                              <1> 	;	owner - (new) owner (number/ID)
 18270                              <1> 	;	
 18271                              <1> 	; Inputs: -
 18272                              <1> 	; Outputs: -
 18273                              <1> 	; ...............................................................
 18274                              <1> 	;				
 18275                              <1> 	; Retro UNIX 8086 v1 modification: 
 18276                              <1> 	;       'syschown' system call has two arguments; so,
 18277                              <1> 	;	* 1st argument, name is pointed to by BX register
 18278                              <1> 	;	* 2nd argument, owner number is in CX register
 18279                              <1> 	;
 18280                              <1> 	; / name; owner
 18281 00005163 E8B2FFFFFF          <1> 	call	isown
 18282                              <1> 		; jsr r0,isown / get the i-node and check user status
 18283 00005168 803D[CC740000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
 18284                              <1> 		; tstb u.uid / super user
 18285 0000516F 7418                <1> 	jz	short syschown1
 18286                              <1> 		; beq 2f / yes, 2f
 18287 00005171 F605[56710000]20    <1>         test    byte [i.flgs], 20h ; 32
 18288                              <1> 		; bit $40,i.flgs / no, set userid on execution?
 18289                              <1> 	;jnz	error
 18290                              <1> 		; bne 3f / yes error, could create Trojan Horses
 18291 00005178 740F                <1> 	jz	short syschown1
 18292                              <1> 	; 'permission denied !'
 18293 0000517A C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
 18294 00005182 0000                <1>
 18295 00005184 E9F3EEFFFF          <1> 	jmp	error
 18296                              <1> syschown1: ; 2:
 18297                              <1> 	; AL = owner (number/ID)
 18298 00005189 A2[59710000]        <1> 	mov	[i.uid], al ; 23/06/2015
 18299                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
 18300                              <1> 			       ; / in the i-node
 18301 0000518E E909EFFFFF          <1> 	jmp	sysret
 18302                              <1> 	; 1: 
 18303                              <1> 		; jmp sysret4
 18304                              <1> 	; 3:
 18305                              <1> 		; jmp	error
 18306                              <1> 
 18307                              <1> systime: ; / get time of year
 18308                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18309                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 18310                              <1> 	;
 18311                              <1> 	; 20/06/2013
 18312                              <1> 	; 'systime' gets the time of the year.
 18313                              <1> 	; The present time is put on the stack.
 18314                              <1> 	;
 18315                              <1> 	; Calling sequence:
 18316                              <1> 	;	systime
 18317                              <1> 	; Arguments: -
 18318                              <1> 	;	
 18319                              <1> 	; Inputs: -
 18320                              <1> 	; Outputs: sp+2, sp+4 - present time
 18321                              <1> 	; ...............................................................
 18322                              <1> 	;	
 18323                              <1> 	; Retro UNIX 8086 v1 modification: 
 18324                              <1> 	;       'systime' system call will return to the user
 18325                              <1> 	;	with unix time (epoch) in DX:AX register pair
 18326                              <1> 	;
 18327                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
 18328                              <1> 	;	system call for PC compatibility !!		 	
 18329                              <1> 
 18330 00005193 E81FEAFFFF          <1> 	call 	epoch
 18331 00005198 A3[80740000]        <1> 	mov 	[u.r0], eax
 18332                              <1> 		; mov s.time,4(sp)
 18333                              <1> 		; mov s.time+2,2(sp) / put the present time 
 18334                              <1> 				   ; / on the stack
 18335                              <1> 		; br sysret4
 18336 0000519D E9FAEEFFFF          <1> 	jmp	sysret 
 18337                              <1> 
 18338                              <1> sysstime: ; / set time
 18339                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18340                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18341                              <1> 	;
 18342                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
 18343                              <1> 	;
 18344                              <1> 	; Calling sequence:
 18345                              <1> 	;	sysstime
 18346                              <1> 	; Arguments: -
 18347                              <1> 	;	
 18348                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
 18349                              <1> 	; Outputs: -
 18350                              <1> 	; ...............................................................
 18351                              <1> 	;	
 18352                              <1> 	; Retro UNIX 8086 v1 modification: 
 18353                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
 18354                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
 18355                              <1> 	; 
 18356                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 18357                              <1> 	;	to get sysstime system call arguments from the user;
 18358                              <1> 	;	* 1st argument, lowword of unix time is in BX register
 18359                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
 18360                              <1> 	;
 18361                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
 18362                              <1> 	;	system call for PC compatibility !!	
 18363                              <1> 
 18364 000051A2 803D[CC740000]00    <1> 	cmp	byte [u.uid], 0
 18365                              <1> 		; tstb u.uid / is user the super user
 18366                              <1> 	;ja	error
 18367                              <1> 		; bne error4 / no, error
 18368 000051A9 760F                <1> 	jna	short systime1
 18369                              <1> 	; 'permission denied !'
 18370 000051AB C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
 18371 000051B3 0000                <1>
 18372 000051B5 E9C2EEFFFF          <1> 	jmp	error
 18373                              <1> systime1:
 18374                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
 18375                              <1> 	; EBX = unix (epoch) time (from user)
 18376 000051BA 89D8                <1> 	mov	eax, ebx
 18377 000051BC E878EBFFFF          <1> 	call 	set_date_time
 18378                              <1> 		; mov 4(sp),s.time
 18379                              <1> 		; mov 2(sp),s.time+2 / set the system time
 18380 000051C1 E9D6EEFFFF          <1> 	jmp	sysret
 18381                              <1> 		; br sysret4
 18382                              <1> 
 18383                              <1> sysbreak:
 18384                              <1> 	; 18/10/2015
 18385                              <1> 	; 07/10/2015
 18386                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18387                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
 18388                              <1> 	;
 18389                              <1> 	; 'sysbreak' sets the programs break points. 
 18390                              <1> 	; It checks the current break point (u.break) to see if it is
 18391                              <1> 	; between "core" and the stack (sp). If it is, it is made an
 18392                              <1> 	; even address (if it was odd) and the area between u.break
 18393                              <1> 	; and the stack is cleared. The new breakpoint is then put
 18394                              <1> 	; in u.break and control is passed to 'sysret'.
 18395                              <1> 	;
 18396                              <1> 	; Calling sequence:
 18397                              <1> 	;	sysbreak; addr
 18398                              <1> 	; Arguments: -
 18399                              <1> 	;	
 18400                              <1> 	; Inputs: u.break - current breakpoint
 18401                              <1> 	; Outputs: u.break - new breakpoint 
 18402                              <1> 	;	area between old u.break and the stack (sp) is cleared.
 18403                              <1> 	; ...............................................................
 18404                              <1> 	;	
 18405                              <1> 	; Retro UNIX 8086 v1 modification:
 18406                              <1> 	;	The user/application program puts breakpoint address
 18407                              <1> 	;       in BX register as 'sysbreak' system call argument.
 18408                              <1> 	; 	(argument transfer method 1)
 18409                              <1> 	;
 18410                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
 18411                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
 18412                              <1> 	;  NOTE:
 18413                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
 18414                              <1> 	;	'u.break' address) of user's memory for original unix's
 18415                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
 18416                              <1> 
 18417                              <1> 		; mov u.break,r1 / move users break point to r1
 18418                              <1> 		; cmp r1,$core / is it the same or lower than core?
 18419                              <1> 		; blos 1f / yes, 1f
 18420                              <1> 	; 23/06/2015
 18421 000051C6 8B2D[AC740000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
 18422                              <1> 	;and	ebp, ebp
 18423                              <1> 	;jz	short sysbreak_3 
 18424                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
 18425                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
 18426 000051CC 8B15[78740000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
 18427 000051D2 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
 18428                              <1> 	; 07/10/2015
 18429 000051D5 891D[AC740000]      <1> 	mov	[u.break], ebx ; virtual address !!!
 18430                              <1> 	;
 18431 000051DB 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
 18432                              <1> 			   ; with top of user's stack (virtual!)
 18433 000051DD 7327                <1> 	jnb	short sysbreak_3
 18434                              <1> 		; cmp r1,sp / is it the same or higher 
 18435                              <1> 			  ; / than the stack?
 18436                              <1> 		; bhis 1f / yes, 1f
 18437 000051DF 89DE                <1> 	mov	esi, ebx
 18438 000051E1 29EE                <1> 	sub	esi, ebp ; new break point - old break point
 18439 000051E3 7621                <1> 	jna	short sysbreak_3 
 18440                              <1> 	;push	ebx
 18441                              <1> sysbreak_1:
 18442 000051E5 89EB                <1> 	mov	ebx, ebp  
 18443 000051E7 E8DEE4FFFF          <1> 	call	get_physical_addr ; get physical address
 18444 000051EC 0F82A8FEFFFF        <1> 	jc	tr_addr_nm_err
 18445                              <1> 	; 18/10/2015
 18446 000051F2 89C7                <1> 	mov	edi, eax 
 18447 000051F4 29C0                <1> 	sub	eax, eax ; 0
 18448                              <1> 		 ; ECX = remain byte count in page (1-4096)
 18449 000051F6 39CE                <1> 	cmp	esi, ecx
 18450 000051F8 7302                <1> 	jnb	short sysbreak_2
 18451 000051FA 89F1                <1> 	mov	ecx, esi
 18452                              <1> sysbreak_2:
 18453 000051FC 29CE                <1> 	sub	esi, ecx
 18454 000051FE 01CD                <1> 	add	ebp, ecx
 18455 00005200 F3AA                <1> 	rep 	stosb
 18456 00005202 09F6                <1> 	or	esi, esi
 18457 00005204 75DF                <1> 	jnz	short sysbreak_1
 18458                              <1> 	;
 18459                              <1> 		; bit $1,r1 / is it an odd address
 18460                              <1> 		; beq 2f / no, its even
 18461                              <1> 		; clrb (r1)+ / yes, make it even
 18462                              <1> 	; 2: / clear area between the break point and the stack
 18463                              <1> 		; cmp r1,sp / is it higher or same than the stack
 18464                              <1> 		; bhis 1f / yes, quit
 18465                              <1> 		; clr (r1)+ / clear word
 18466                              <1> 		; br 2b / go back
 18467                              <1> 	;pop	ebx
 18468                              <1> sysbreak_3: ; 1:
 18469                              <1> 	;mov	[u.break], ebx ; virtual address !!!
 18470                              <1> 		; jsr r0,arg; u.break / put the "address" 
 18471                              <1> 			; / in u.break (set new break point)
 18472                              <1> 		; br sysret4 / br sysret
 18473 00005206 E991EEFFFF          <1> 	jmp	sysret
 18474                              <1> 
 18475                              <1> 
 18476                              <1> maknod: 
 18477                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18478                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18479                              <1> 	;
 18480                              <1> 	; 'maknod' creates an i-node and makes a directory entry
 18481                              <1> 	; for this i-node in the current directory.
 18482                              <1> 	;
 18483                              <1> 	; INPUTS ->
 18484                              <1> 	;    r1 - contains mode
 18485                              <1> 	;    ii - current directory's i-number	
 18486                              <1> 	;    	
 18487                              <1> 	; OUTPUTS ->
 18488                              <1> 	;    u.dirbuf - contains i-number of free i-node 
 18489                              <1> 	;    i.flgs - flags in new i-node 
 18490                              <1> 	;    i.uid - filled with u.uid
 18491                              <1> 	;    i.nlks - 1 is put in the number of links
 18492                              <1> 	;    i.ctim - creation time				
 18493                              <1> 	;    i.ctim+2 - modification time
 18494                              <1> 	;    imod - set via call to setimod
 18495                              <1> 	;	
 18496                              <1> 	; ((AX = R1)) input
 18497                              <1> 	;
 18498                              <1> 	; (Retro UNIX Prototype : 
 18499                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
 18500                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 18501                              <1> 
 18502                              <1> 	; / r1 contains the mode
 18503 0000520B 80CC80              <1> 	or 	ah, 80h  ; 10000000b
 18504                              <1> 		; bis	$100000,r1 / allocate flag set
 18505 0000520E 6650                <1> 	push	ax
 18506                              <1> 		; mov r1,-(sp) / put mode on stack
 18507                              <1> 	; 31/07/2013
 18508 00005210 66A1[62740000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
 18509                              <1> 		; mov ii,r1 / move current i-number to r1
 18510 00005216 B201                <1> 	mov	dl, 1 ; owner flag mask
 18511 00005218 E8E6050000          <1> 	call	access	
 18512                              <1> 		; jsr r0,access; 1 / get its i-node into core
 18513 0000521D 6650                <1> 	push	ax
 18514                              <1> 		; mov r1,-(sp) / put i-number on stack
 18515 0000521F 66B82800            <1> 	mov	ax, 40
 18516                              <1> 		; mov $40.,r1 / r1 = 40
 18517                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
 18518 00005223 6640                <1> 	inc	ax
 18519                              <1> 		; inc r1 / r1 = r1 + 1
 18520 00005225 E8AA060000          <1> 	call	imap
 18521                              <1> 		; jsr r0,imap / get byte address and bit position in 
 18522                              <1> 			    ; /	inode map in r2 & m
 18523                              <1>           ; DX (MQ) has a 1 in the calculated bit position
 18524                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
 18525                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
 18526                              <1> 	;	       Inode count must be checked here
 18527                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
 18528 0000522A 8413                <1> 	test	[ebx], dl
 18529                              <1> 		; bitb mq,(r2) / is the i-node active
 18530 0000522C 75F5                <1> 	jnz	short maknod1
 18531                              <1> 		; bne 1b / yes, try the next one
 18532 0000522E 0813                <1> 	or	[ebx], dl
 18533                              <1> 		; bisb mq,(r2) / no, make it active 
 18534                              <1> 			     ; / (put a 1 in the bit map)
 18535 00005230 E8F3040000          <1> 	call	iget
 18536                              <1> 		; jsr r0,iget / get i-node into core
 18537 00005235 66F705[56710000]00- <1> 	test	word [i.flgs], 8000h 
 18538 0000523D 80                  <1>
 18539                              <1> 		; tst i.flgs / is i-node already allocated
 18540 0000523E 75E3                <1> 	jnz	short maknod1	
 18541                              <1> 		; blt 1b / yes, look for another one
 18542 00005240 66A3[B2740000]      <1> 	mov	[u.dirbuf], ax
 18543                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
 18544 00005246 6658                <1> 	pop	ax
 18545                              <1> 		; mov (sp)+,r1 / get current i-number back
 18546 00005248 E8DB040000          <1> 	call	iget
 18547                              <1> 		; jsr r0,iget / get i-node in core
 18548 0000524D E87DF7FFFF          <1> 	call	mkdir
 18549                              <1> 		; jsr r0,mkdir / make a directory entry 
 18550                              <1> 			     ; / in current directory
 18551 00005252 66A1[B2740000]      <1> 	mov	ax, [u.dirbuf]
 18552                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
 18553 00005258 E8CB040000          <1> 	call	iget
 18554                              <1> 		; jsr r0,iget / get it into core
 18555                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
 18556 0000525D B908000000          <1> 	mov	ecx, 8 
 18557 00005262 31C0                <1> 	xor	eax, eax ; 0
 18558 00005264 BF[56710000]        <1> 	mov	edi, inode 
 18559 00005269 F3AB                <1> 	rep	stosd
 18560                              <1> 	;
 18561 0000526B 668F05[56710000]    <1> 	pop	word [i.flgs]
 18562                              <1> 		; mov (sp)+,i.flgs / fill flags
 18563 00005272 8A0D[CC740000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
 18564 00005278 880D[59710000]      <1> 	mov 	[i.uid], cl
 18565                              <1> 		; movb u.uid,i.uid / user id	
 18566 0000527E C605[58710000]01    <1> 	mov     byte [i.nlks], 1
 18567                              <1> 		; movb $1,i.nlks / 1 link
 18568                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
 18569                              <1> 	;mov	eax, [s.time]
 18570                              <1> 	;mov 	[i.ctim], eax
 18571                              <1> 	 	; mov s.time,i.ctim / time created
 18572                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
 18573                              <1> 	; Retro UNIX 8086 v1 modification !
 18574                              <1> 	; i.ctime=0, i.ctime+2=0 and
 18575                              <1>         ; 'setimod' will set ctime of file via 'epoch'
 18576 00005285 E8B1050000          <1> 	call setimod
 18577                              <1> 		; jsr r0,setimod / set modified flag
 18578 0000528A C3                  <1> 	retn
 18579                              <1> 		; rts r0 / return
 18580                              <1> 
 18581                              <1> sysseek: ; / moves read write pointer in an fsp entry
 18582                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18583                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 18584                              <1> 	;
 18585                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
 18586                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
 18587                              <1> 	; The file descriptor refers to a file open for reading or
 18588                              <1> 	; writing. The read (or write) pointer is set as follows:
 18589                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
 18590                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
 18591                              <1> 	;	  current location plus offset.
 18592                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
 18593                              <1> 	;	  size of file plus offset.
 18594                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
 18595                              <1> 	;
 18596                              <1> 	; Calling sequence:
 18597                              <1> 	;	sysseek; offset; ptrname
 18598                              <1> 	; Arguments:
 18599                              <1> 	;	offset - number of bytes desired to move 
 18600                              <1> 	;		 the r/w pointer
 18601                              <1> 	;	ptrname - a switch indicated above
 18602                              <1> 	;
 18603                              <1> 	; Inputs: r0 - file descriptor 
 18604                              <1> 	; Outputs: -
 18605                              <1> 	; ...............................................................
 18606                              <1> 	;	
 18607                              <1> 	; Retro UNIX 8086 v1 modification: 
 18608                              <1> 	;       'sysseek' system call has three arguments; so,
 18609                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
 18610                              <1> 	;	* 2nd argument, offset is in CX register
 18611                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
 18612                              <1> 	;	
 18613                              <1> 
 18614 0000528B E823000000          <1> 	call	seektell
 18615                              <1> 	; AX = u.count
 18616                              <1> 	; BX = *u.fofp
 18617                              <1> 		; jsr r0,seektell / get proper value in u.count
 18618                              <1> 		; add u.base,u.count / add u.base to it
 18619 00005290 0305[A0740000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
 18620 00005296 8903                <1> 	mov	[ebx], eax
 18621                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
 18622 00005298 E9FFEDFFFF          <1> 	jmp	sysret
 18623                              <1> 		; br sysret4
 18624                              <1> 
 18625                              <1> systell: ; / get the r/w pointer
 18626                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18627                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 18628                              <1> 	;
 18629                              <1> 	; Retro UNIX 8086 v1 modification:
 18630                              <1> 	; ! 'systell' does not work in original UNIX v1,
 18631                              <1> 	; 	    it returns with error !
 18632                              <1> 	; Inputs: r0 - file descriptor 
 18633                              <1> 	; Outputs: r0 - file r/w pointer
 18634                              <1> 
 18635                              <1> 	;xor	ecx, ecx ; 0
 18636 0000529D BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
 18637                              <1> 	;call 	seektell
 18638 000052A2 E812000000          <1> 	call 	seektell0 ; 05/08/2013
 18639                              <1> 	;mov	ebx, [u.fofp]
 18640 000052A7 8B03                <1> 	mov	eax, [ebx]
 18641 000052A9 A3[80740000]        <1> 	mov	[u.r0], eax
 18642 000052AE E9E9EDFFFF          <1> 	jmp	sysret
 18643                              <1> 
 18644                              <1> ; Original unix v1 'systell' system call:
 18645                              <1> 		; jsr r0,seektell
 18646                              <1> 		; br error4
 18647                              <1> 
 18648                              <1> seektell:
 18649                              <1> 	; 03/01/2016
 18650                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18651                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 18652                              <1> 	;
 18653                              <1> 	; 'seektell' puts the arguments from sysseek and systell
 18654                              <1> 	; call in u.base and u.count. It then gets the i-number of
 18655                              <1> 	; the file from the file descriptor in u.r0 and by calling
 18656                              <1> 	; getf. The i-node is brought into core and then u.count
 18657                              <1> 	; is checked to see it is a 0, 1, or 2.
 18658                              <1> 	; If it is 0 - u.count stays the same
 18659                              <1> 	;          1 - u.count = offset (u.fofp)
 18660                              <1> 	;	   2 - u.count = i.size (size of file)
 18661                              <1> 	; 	 		
 18662                              <1> 	; !! Retro UNIX 8086 v1 modification:
 18663                              <1> 	;	Argument 1, file descriptor is in BX;
 18664                              <1> 	;	Argument 2, offset is in CX;
 18665                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
 18666                              <1> 	;
 18667                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
 18668                              <1> 	; call 	arg
 18669                              <1> 	;
 18670                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
 18671                              <1> 	;
 18672 000052B3 890D[A0740000]      <1> 	mov 	[u.base], ecx ; offset
 18673                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
 18674                              <1> seektell0:
 18675 000052B9 8915[A4740000]      <1> 	mov 	[u.count], edx
 18676                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
 18677                              <1> 	; mov	ax, bx
 18678                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
 18679                              <1> 			     ; / (index in u.fp list)
 18680                              <1> 	; call	getf
 18681                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
 18682                              <1> 	; BX = file descriptor (file number)
 18683 000052BF E83DFCFFFF          <1> 	call	getf1
 18684 000052C4 6609C0              <1> 	or	ax, ax ; i-number of the file
 18685                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
 18686                              <1> 		             ; / put it on the stack
 18687                              <1> 	;jz	error
 18688                              <1> 		; beq error4 / if i-number is 0, not active so error
 18689 000052C7 750F                <1> 	jnz	short seektell1
 18690 000052C9 C705[D5740000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 18691 000052D1 0000                <1>
 18692 000052D3 E9A4EDFFFF          <1> 	jmp	error
 18693                              <1> seektell1:
 18694                              <1> 	;push	eax
 18695 000052D8 80FC80              <1> 	cmp	ah, 80h
 18696 000052DB 7203                <1> 	jb	short seektell2
 18697                              <1> 		; bgt .+4 / if its positive jump
 18698 000052DD 66F7D8              <1> 	neg	ax
 18699                              <1> 		; neg r1 / if not make it positive
 18700                              <1> seektell2:
 18701 000052E0 E843040000          <1> 	call	iget
 18702                              <1> 		; jsr r0,iget / get its i-node into core
 18703 000052E5 8B1D[90740000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
 18704 000052EB 803D[A4740000]01    <1> 	cmp	byte [u.count], 1
 18705                              <1> 		; cmp u.count,$1 / is ptr name =1
 18706 000052F2 7705                <1> 	ja	short seektell3
 18707                              <1> 		; blt 2f / no its zero
 18708 000052F4 740A                <1> 	je	short seektell_4
 18709                              <1> 		; beq 1f / yes its 1
 18710 000052F6 31C0                <1> 	xor	eax, eax
 18711                              <1> 	;jmp	short seektell_5
 18712 000052F8 C3                  <1> 	retn
 18713                              <1> seektell3:
 18714                              <1> 	; 03/01/2016
 18715                              <1> 	;movzx	eax, word [i.size]
 18716 000052F9 66A1[5A710000]      <1>         mov   	ax, [i.size]
 18717                              <1>                 ; mov i.size,u.count /  put number of bytes 
 18718                              <1>                                    ; / in file in u.count
 18719                              <1> 	;jmp	short seektell_5
 18720                              <1> 		; br 2f
 18721 000052FF C3                  <1> 	retn
 18722                              <1> seektell_4: ; 1: / ptrname =1
 18723                              <1> 	;mov	ebx, [u.fofp]
 18724 00005300 8B03                <1> 	mov	eax, [ebx]
 18725                              <1> 		; mov *u.fofp,u.count / put offset in u.count
 18726                              <1> ;seektell_5: ; 2: / ptrname =0
 18727                              <1> 	;mov	[u.count], eax
 18728                              <1> 	;pop	eax 
 18729                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
 18730 00005302 C3                  <1> 	retn
 18731                              <1> 		; rts r0
 18732                              <1> 
 18733                              <1> sysintr: ; / set interrupt handling
 18734                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18735                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 18736                              <1> 	;
 18737                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
 18738                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
 18739                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
 18740                              <1> 	; If one does the interrupt character in the tty buffer is
 18741                              <1> 	; cleared and 'sysret'is called. If one does not exits
 18742                              <1> 	; 'sysret' is just called.	
 18743                              <1> 	;
 18744                              <1> 	; Calling sequence:
 18745                              <1> 	;	sysintr; arg
 18746                              <1> 	; Argument:
 18747                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
 18748                              <1> 	;	    - if 1, intterupts cause their normal result
 18749                              <1> 	;		 i.e force an exit.
 18750                              <1> 	;	    - if arg is a location within the program,
 18751                              <1> 	;		control is passed to that location when
 18752                              <1> 	;		an interrupt occurs.	
 18753                              <1> 	; Inputs: -
 18754                              <1> 	; Outputs: -
 18755                              <1> 	; ...............................................................
 18756                              <1> 	;	
 18757                              <1> 	; Retro UNIX 8086 v1 modification: 
 18758                              <1> 	;       'sysintr' system call sets u.intr to value of BX
 18759                              <1> 	;	then branches into sysquit.
 18760                              <1> 	;
 18761 00005303 66891D[C4740000]    <1> 	mov	[u.intr], bx
 18762                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
 18763                              <1> 		; br 1f / go into quit routine
 18764 0000530A E98DEDFFFF          <1> 	jmp	sysret
 18765                              <1> 
 18766                              <1> sysquit:
 18767                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18768                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 18769                              <1> 	;
 18770                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
 18771                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
 18772                              <1> 	; tty exists. If one does the interrupt character in the tty
 18773                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
 18774                              <1> 	; 'sysret' is just called.	
 18775                              <1> 	;
 18776                              <1> 	; Calling sequence:
 18777                              <1> 	;	sysquit; arg
 18778                              <1> 	; Argument:
 18779                              <1> 	;	arg - if 0, this call diables quit signals from the
 18780                              <1> 	;		typewriter (ASCII FS)
 18781                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
 18782                              <1> 	;		cease and a core image to be produced.
 18783                              <1> 	;		 i.e force an exit.
 18784                              <1> 	;	    - if arg is an addres in the program,
 18785                              <1> 	;		a quit causes control to sent to that
 18786                              <1> 	;		location.	
 18787                              <1> 	; Inputs: -
 18788                              <1> 	; Outputs: -
 18789                              <1> 	; ...............................................................
 18790                              <1> 	;	
 18791                              <1> 	; Retro UNIX 8086 v1 modification: 
 18792                              <1> 	;       'sysquit' system call sets u.quit to value of BX
 18793                              <1> 	;	then branches into 'sysret'.
 18794                              <1> 	;
 18795 0000530F 66891D[C6740000]    <1> 	mov	[u.quit], bx
 18796 00005316 E981EDFFFF          <1> 	jmp	sysret
 18797                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
 18798                              <1> 	;1:
 18799                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
 18800                              <1> 			      ; / to r1
 18801                              <1> 		; beq sysret4 / return to user
 18802                              <1> 		; clrb 6(r1) / clear the interrupt character 
 18803                              <1> 			   ; / in the tty buffer
 18804                              <1> 		; br sysret4 / return to user
 18805                              <1> 
 18806                              <1> syssetuid: ; / set process id
 18807                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18808                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18809                              <1> 	;
 18810                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
 18811                              <1> 	; to the process id in (u.r0). Both the effective user and 
 18812                              <1> 	; u.uid and the real user u.ruid are set to this. 
 18813                              <1> 	; Only the super user can make this call.	
 18814                              <1> 	;
 18815                              <1> 	; Calling sequence:
 18816                              <1> 	;	syssetuid
 18817                              <1> 	; Arguments: -
 18818                              <1> 	;
 18819                              <1> 	; Inputs: (u.r0) - contains the process id.
 18820                              <1> 	; Outputs: -
 18821                              <1> 	; ...............................................................
 18822                              <1> 	;	
 18823                              <1> 	; Retro UNIX 8086 v1 modification: 
 18824                              <1> 	;       BL contains the (new) user ID of the current process
 18825                              <1> 
 18826                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
 18827 0000531B 3A1D[CD740000]      <1> 	cmp	bl, [u.ruid] 
 18828                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
 18829                              <1> 			       ; / id number
 18830 00005321 741E                <1> 	je	short setuid1
 18831                              <1> 		; beq 1f / yes
 18832 00005323 803D[CC740000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 18833                              <1> 		; tstb u.uid / no, is current user the super user?
 18834                              <1> 	;ja	error
 18835                              <1> 		; bne error4 / no, error
 18836 0000532A 760F                <1> 	jna	short setuid0
 18837 0000532C C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
 18838 00005334 0000                <1>
 18839                              <1> 				;  'permission denied !' error
 18840 00005336 E941EDFFFF          <1> 	jmp	error
 18841                              <1> setuid0:
 18842 0000533B 881D[CD740000]      <1> 	mov	[u.ruid], bl
 18843                              <1> setuid1: ; 1:
 18844 00005341 881D[CC740000]      <1> 	mov	[u.uid], bl ; 02/08/2013
 18845                              <1> 		; movb r1,u.uid / put process id in u.uid
 18846                              <1> 		; movb r1,u.ruid / put process id in u.ruid
 18847 00005347 E950EDFFFF          <1> 	jmp	sysret
 18848                              <1> 		; br sysret4 / system return
 18849                              <1> 
 18850                              <1> sysgetuid: ; < get user id >
 18851                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18852                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 18853                              <1> 	;
 18854                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
 18855                              <1> 	; The real user ID identifies the person who is logged in,
 18856                              <1> 	; in contradistinction to the effective user ID, which
 18857                              <1> 	; determines his access permission at each moment. It is thus
 18858                              <1> 	; useful to programs which operate using the 'set user ID'
 18859                              <1> 	; mode, to find out who invoked them.	
 18860                              <1> 	;
 18861                              <1> 	; Calling sequence:
 18862                              <1> 	;	syssetuid
 18863                              <1> 	; Arguments: -
 18864                              <1> 	;
 18865                              <1> 	; Inputs: -
 18866                              <1> 	; Outputs: (u.r0) - contains the real user's id.
 18867                              <1> 	; ...............................................................
 18868                              <1> 	;	
 18869                              <1> 	; Retro UNIX 8086 v1 modification: 
 18870                              <1> 	;       AL contains the real user ID at return.
 18871                              <1> 	;
 18872 0000534C 0FB605[CD740000]    <1> 	movzx 	eax, byte [u.ruid]
 18873 00005353 A3[80740000]        <1> 	mov	[u.r0], eax
 18874                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
 18875 00005358 E93FEDFFFF          <1> 	jmp	sysret
 18876                              <1> 		; br sysret4 / systerm return, sysret
 18877                              <1> 
 18878                              <1> anyi: 
 18879                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18880                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
 18881                              <1> 	;
 18882                              <1> 	; 'anyi' is called if a file deleted while open.
 18883                              <1> 	; "anyi" checks to see if someone else has opened this file.
 18884                              <1> 	;
 18885                              <1> 	; INPUTS ->
 18886                              <1> 	;    r1 - contains an i-number
 18887                              <1> 	;    fsp - start of table containing open files
 18888                              <1> 	;
 18889                              <1> 	; OUTPUTS ->
 18890                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
 18891                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
 18892                              <1> 	;    if file not found - bit in i-node map is cleared
 18893                              <1> 	;    			 (i-node is freed)
 18894                              <1> 	;               all blocks related to i-node are freed
 18895                              <1> 	;	        all flags in i-node are cleared
 18896                              <1> 	; ((AX = R1)) input
 18897                              <1> 	;
 18898                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 18899                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 18900                              <1> 	;
 18901                              <1> 		; / r1 contains an i-number
 18902 0000535D BB[56720000]        <1> 	mov	ebx, fsp
 18903                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
 18904                              <1> anyi_1: ; 1:
 18905 00005362 663B03              <1> 	cmp	ax, [ebx]
 18906                              <1> 		; cmp r1,(r2) / do i-numbers match?
 18907 00005365 7433                <1> 	je	short anyi_3
 18908                              <1> 		; beq 1f / yes, 1f
 18909 00005367 66F7D8              <1> 	neg	ax
 18910                              <1> 		; neg r1 / no complement r1
 18911 0000536A 663B03              <1> 	cmp	ax, [ebx]
 18912                              <1> 		; cmp r1,(r2) / do they match now?
 18913 0000536D 742B                <1> 	je	short anyi_3
 18914                              <1> 		; beq 1f / yes, transfer
 18915                              <1> 		; / i-numbers do not match
 18916 0000536F 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
 18917                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
 18918                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
 18919 00005372 81FB[4A740000]      <1> 	cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
 18920                              <1> 		; cmp r2,$fsp+[nfiles*8] 
 18921                              <1> 				; / are we at last entry in the table
 18922 00005378 72E8                <1> 	jb	short anyi_1
 18923                              <1> 		; blt 1b / no, check next entries i-number
 18924                              <1> 	;cmp	ax, 32768
 18925 0000537A 80FC80              <1> 	cmp	ah, 80h ; negative number check
 18926                              <1> 		; tst r1 / yes, no match
 18927                              <1> 		; bge .+4
 18928 0000537D 7203                <1> 	jb	short anyi_2
 18929 0000537F 66F7D8              <1> 	neg	ax
 18930                              <1> 		; neg r1 / make i-number positive
 18931                              <1> anyi_2:	
 18932 00005382 E84D050000          <1> 	call	imap
 18933                              <1> 		; jsr r0,imap / get address of allocation bit 
 18934                              <1> 			    ; / in the i-map in r2
 18935                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
 18936                              <1>         ;; eBX (R2) has address of the byte with allocation bit
 18937                              <1>  	; not	dx
 18938 00005387 F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
 18939                              <1>         ;and	[ebx], dx
 18940 00005389 2013                <1> 	and 	[ebx], dl 
 18941                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
 18942 0000538B E8CD040000          <1> 	call	itrunc
 18943                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
 18944 00005390 66C705[56710000]00- <1>  	mov 	word [i.flgs], 0
 18945 00005398 00                  <1>
 18946                              <1> 		; clr i.flgs / clear all flags in the i-node
 18947 00005399 C3                  <1> 	retn
 18948                              <1> 		;rts	r0 / return
 18949                              <1> anyi_3: ; 1: / i-numbers match
 18950 0000539A FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
 18951                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
 18952                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
 18953 0000539D C3                  <1> 	retn
 18954                              <1> 		; rts r0
 18955                                  %include 'u3.s'        ; 10/05/2015
 18956                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS3.INC
 18957                              <1> ; Last Modification: 15/09/2015
 18958                              <1> ; ----------------------------------------------------------------------------
 18959                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 18960                              <1> ; (v0.1 - Beginning: 11/07/2012)
 18961                              <1> ;
 18962                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 18963                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 18964                              <1> ; <Bell Laboratories (17/3/1972)>
 18965                              <1> ; <Preliminary Release of UNIX Implementation Document>
 18966                              <1> ;
 18967                              <1> ; Retro UNIX 8086 v1 - U3.ASM (08/03/2014) //// UNIX v1 -> u3.s
 18968                              <1> ;
 18969                              <1> ; ****************************************************************************
 18970                              <1> 
 18971                              <1> tswitch: ; Retro UNIX 386 v1
 18972                              <1> tswap:
 18973                              <1> 	; 01/09/2015
 18974                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 18975                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 18976                              <1> 	; time out swap, called when a user times out.
 18977                              <1> 	; the user is put on the low priority queue.
 18978                              <1> 	; This is done by making a link from the last user
 18979                              <1> 	; on the low priority queue to him via a call to 'putlu'.
 18980                              <1> 	; then he is swapped out.
 18981                              <1> 	;
 18982                              <1> 	; Retro UNIX 386 v1 modification ->
 18983                              <1> 	;       swap (software task switch) is performed by changing
 18984                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 18985                              <1> 	;	as in Retro UNIX 8086 v1.
 18986                              <1> 	;
 18987                              <1> 	; RETRO UNIX 8086 v1 modification ->
 18988                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 18989                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 18990                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 18991                              <1> 	;	compatibles was using 1MB segmented memory 
 18992                              <1> 	;	in 8086/8088 times.
 18993                              <1> 	;
 18994                              <1> 	; INPUTS ->
 18995                              <1> 	;    u.uno - users process number
 18996                              <1> 	;    runq+4 - lowest priority queue
 18997                              <1> 	; OUTPUTS ->
 18998                              <1> 	;    r0 - users process number
 18999                              <1> 	;    r2 - lowest priority queue address
 19000                              <1> 	;
 19001                              <1> 	; ((AX = R0, BX = R2)) output
 19002                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
 19003                              <1> 	;
 19004 0000539E A0[CF740000]        <1> 	mov 	al, [u.uno]
 19005                              <1> 	       	; movb u.uno,r1 / move users process number to r1
 19006                              <1> 		; mov  $runq+4,r2 
 19007                              <1> 			; / move lowest priority queue address to r2
 19008 000053A3 E8CE000000          <1>         call 	putlu
 19009                              <1> 		; jsr r0,putlu / create link from last user on Q to 
 19010                              <1> 		             ; / u.uno's user
 19011                              <1> 
 19012                              <1> switch: ; Retro UNIX 386 v1
 19013                              <1> swap:
 19014                              <1> 	; 02/09/2015
 19015                              <1> 	; 01/09/2015
 19016                              <1> 	; 31/08/2015
 19017                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19018                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19019                              <1> 	; 'swap' is routine that controls the swapping of processes
 19020                              <1> 	; in and out of core.
 19021                              <1> 	;
 19022                              <1> 	; Retro UNIX 386 v1 modification ->
 19023                              <1> 	;       swap (software task switch) is performed by changing
 19024                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 19025                              <1> 	;	as in Retro UNIX 8086 v1.
 19026                              <1> 	;
 19027                              <1> 	; RETRO UNIX 8086 v1 modification ->
 19028                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19029                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19030                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19031                              <1> 	;	compatibles was using 1MB segmented memory 
 19032                              <1> 	;	in 8086/8088 times.
 19033                              <1> 	;
 19034                              <1> 	; INPUTS ->
 19035                              <1> 	;    runq table - contains processes to run.
 19036                              <1> 	;    p.link - contains next process in line to be run.
 19037                              <1> 	;    u.uno - process number of process in core	
 19038                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
 19039                              <1> 	; OUTPUTS ->
 19040                              <1> 	;    (original unix v1 -> present process to its disk block)
 19041                              <1> 	;    (original unix v1 -> new process into core -> 
 19042                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
 19043                              <1> 	;	   for new process)
 19044                              <1> 	;    u.quant = 3 (Time quantum for a process)
 19045                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
 19046                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
 19047                              <1> 	;	 for now, it will swap the process if there is not
 19048                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
 19049                              <1> 	;	 or will count down from 3 to 0 even if there is a
 19050                              <1> 	;        keyboard event locking due to repetitive key strokes.
 19051                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
 19052                              <1> 	;
 19053                              <1> 	;    u.pri -points to highest priority run Q.
 19054                              <1> 	;    r2 - points to the run queue.
 19055                              <1> 	;    r1 - contains new process number
 19056                              <1> 	;    r0 - points to place in routine or process that called
 19057                              <1> 	;	  swap all user parameters
 19058                              <1> 	;				
 19059                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
 19060                              <1> 	;
 19061                              <1> swap_0:
 19062                              <1> 		;mov $300,*$ps / processor priority = 6
 19063 000053A8 BE[72740000]        <1> 	mov	esi, runq
 19064                              <1> 		; mov $runq,r2 / r2 points to runq table
 19065                              <1> swap_1: ; 1: / search runq table for highest priority process
 19066 000053AD 668B06              <1> 	mov	ax, [esi]
 19067 000053B0 6621C0              <1> 	and 	ax, ax
 19068                              <1>        		; tst (r2)+ / are there any processes to run 
 19069                              <1> 			  ; / in this Q entry
 19070 000053B3 7507                <1> 	jnz	short swap_2
 19071                              <1>        		; bne 1f / yes, process 1f
 19072                              <1> 		; cmp r2,$runq+6 / if zero compare address 
 19073                              <1> 			       ; / to end of table
 19074                              <1> 		; bne 1b / if not at end, go back
 19075 000053B5 E8E1000000          <1> 	call	idle
 19076                              <1> 		; jsr r0,idle; s.idlet+2 / wait for interrupt; 
 19077                              <1> 				       ; / all queues are empty
 19078 000053BA EBF1                <1> 	jmp	short swap_1
 19079                              <1> 		; br swap
 19080                              <1> swap_2: ; 1:
 19081 000053BC 0FB6D8              <1> 	movzx	ebx, al ; 02/09/2015
 19082                              <1> 		; tst -(r2) / restore pointer to right Q entry
 19083                              <1>  		; mov r2,u.pri / set present user to this run queue
 19084                              <1> 	        ; movb (r2)+,r1 / move 1st process in queue to r1
 19085 000053BF 38E0                <1> 	cmp	al, ah
 19086                              <1> 		; cmpb r1,(r2)+ / is there only 1 process 
 19087                              <1> 			      ; / in this Q to be run
 19088 000053C1 740A                <1> 	je	short swap_3
 19089                              <1>        		; beq 1f / yes
 19090                              <1> 		; tst -(r2) / no, pt r2 back to this Q entry
 19091                              <1> 	;movzx	ebx, al
 19092 000053C3 8AA3[F5710000]      <1> 	mov	ah, [ebx+p.link-1] 
 19093 000053C9 8826                <1>        	mov	[esi], ah
 19094                              <1> 		; movb p.link-1(r1),(r2) / move next process 
 19095                              <1> 				       ; / in line into run queue
 19096 000053CB EB06                <1> 	jmp	short swap_4
 19097                              <1>        		; br 2f
 19098                              <1> swap_3: ; 1:
 19099 000053CD 6631D2              <1> 	xor	dx, dx
 19100 000053D0 668916              <1> 	mov	[esi], dx
 19101                              <1> 		; clr -(r2) / zero the entry; no processes on the Q
 19102                              <1> swap_4: ; / write out core to appropriate disk area and read 
 19103                              <1>       ; / in new process if required
 19104                              <1>        		; clr *$ps / clear processor status
 19105 000053D3 8A25[CF740000]      <1> 	mov 	ah, [u.uno]
 19106 000053D9 38C4                <1> 	cmp	ah, al
 19107                              <1> 		; cmpb r1,u.uno / is this process the same as 
 19108                              <1> 			      ; / the process in core?
 19109 000053DB 743B                <1>        	je	short swap_8
 19110                              <1>        		; beq 2f / yes, don't have to swap
 19111                              <1>        		; mov r0,-(sp) / no, write out core; save r0 
 19112                              <1> 			   ; / (address in routine that called swap)
 19113                              <1> 		; mov r1,-(sp) / put r1 (new process #) on the stack
 19114                              <1> 	; 01/09/2015
 19115                              <1> 	;mov	[u.usp], esp
 19116                              <1>        		; mov sp,u.usp / save stack pointer
 19117                              <1> 		; mov $sstack,sp / move swap stack pointer 
 19118                              <1> 			       ; / to the stack pointer
 19119 000053DD 08E4                <1> 	or	ah, ah
 19120                              <1>        		; tstb u.uno / is the process # = 0
 19121 000053DF 740D                <1>        	jz	short swap_6 ; 'sysexit'
 19122                              <1> 		; beq  1f / yes, kill process by overwriting
 19123                              <1> 	; 02/09/2015
 19124 000053E1 8925[7C740000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
 19125                              <1> 	;
 19126 000053E7 E834000000          <1> 	call	wswap
 19127                              <1> 		;jsr r0,wswap / write out core to disk
 19128                              <1> 	 ; 31/08/2015
 19129                              <1> 	;movzx	ebx, al ; New (running) process number
 19130 000053EC EB1C                <1> 	jmp 	short swap_7
 19131                              <1> swap_6:
 19132                              <1> 	; 31/08/2015
 19133                              <1> 	; Deallocate memory pages belong to the process
 19134                              <1> 	; which is being terminated
 19135                              <1> 	; 14/05/2015 ('sysexit')
 19136                              <1>  	; Deallocate memory pages of the process
 19137                              <1> 	; (Retro UNIX 386 v1 modification !)
 19138                              <1> 	;
 19139                              <1> 	; movzx ebx, al
 19140 000053EE 53                  <1> 	push	ebx
 19141 000053EF A1[D9740000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
 19142 000053F4 8B1D[DD740000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
 19143 000053FA E871DDFFFF          <1> 	call	deallocate_page_dir
 19144 000053FF A1[D0740000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
 19145 00005404 E806DEFFFF          <1> 	call	deallocate_page
 19146 00005409 5B                  <1> 	pop	ebx
 19147                              <1> swap_7: ;1: 
 19148                              <1> 	; 02/09/2015
 19149                              <1> 	; 31/08/2015
 19150                              <1> 	; 14/05/2015
 19151 0000540A C0E302              <1> 	shl	bl, 2 ; * 4 
 19152 0000540D 8B83[12720000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
 19153                              <1> 	;cli
 19154 00005413 E831000000          <1> 	call	rswap
 19155                              <1>  		; mov (sp)+,r1 / restore r1 to new process number
 19156                              <1> 		; jsr r0,rswap / read new process into core
 19157                              <1>        		; jsr r0,unpack / unpack the users stack from next
 19158                              <1> 			      ; / to his program to its normal
 19159                              <1> 	; 01/09/2015
 19160                              <1> 	;mov	esp, [u.usp]	
 19161                              <1> 		; mov u.usp,sp / location; restore stack pointer to
 19162                              <1> 			     ; / new process stack
 19163                              <1> 		; mov (sp)+,r0 / put address of where the process 
 19164                              <1> 			     ; / that just got swapped in, left off.,
 19165                              <1> 			     ; / i.e., transfer control to new process
 19166                              <1> 	;sti
 19167                              <1> swap_8: ;2:
 19168                              <1> 	; RETRO UNIX 8086 v1 modification !
 19169 00005418 C605[C2740000]04    <1> 	mov	byte [u.quant], time_count 
 19170                              <1> 		; movb    $30.,uquant / initialize process time quantum
 19171 0000541F C3                  <1> 	retn
 19172                              <1> 		; rts r0 / return
 19173                              <1> 
 19174                              <1> wswap:  ; < swap out, swap to disk >
 19175                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 19176                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19177                              <1> 	; 'wswap' writes out the process that is in core onto its 
 19178                              <1> 	; appropriate disk area.
 19179                              <1> 	;
 19180                              <1> 	; Retro UNIX 386 v1 modification ->
 19181                              <1> 	;       User (u) structure content and the user's register content
 19182                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
 19183                              <1> 	;	saving 'u' structure and user registers for task switching).
 19184                              <1> 	;	u.usp - points to kernel stack address which contains
 19185                              <1> 	;		user's registers while entering system call.  
 19186                              <1> 	;	u.sp  - points to kernel stack address 
 19187                              <1> 	;		to return from system call -for IRET-.
 19188                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 19189                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 19190                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 19191                              <1> 	;
 19192                              <1> 	; Retro UNIX 8086 v1 modification ->
 19193                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19194                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19195                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19196                              <1> 	;	compatibles was using 1MB segmented memory 
 19197                              <1> 	;	in 8086/8088 times.
 19198                              <1> 	;
 19199                              <1> 	; INPUTS ->
 19200                              <1> 	;    u.break - points to end of program
 19201                              <1> 	;    u.usp - stack pointer at the moment of swap
 19202                              <1> 	;    core - beginning of process program		
 19203                              <1> 	;    ecore - end of core 	
 19204                              <1> 	;    user - start of user parameter area		
 19205                              <1> 	;    u.uno - user process number	
 19206                              <1> 	;    p.dska - holds block number of process	
 19207                              <1> 	; OUTPUTS ->
 19208                              <1> 	;    swp I/O queue
 19209                              <1> 	;    p.break - negative word count of process 
 19210                              <1> 	;    r1 - process disk address	
 19211                              <1> 	;    r2 - negative word count
 19212                              <1> 	;
 19213                              <1> 	; RETRO UNIX 8086 v1 input/output:
 19214                              <1> 	;
 19215                              <1> 	; INPUTS ->
 19216                              <1> 	;    u.uno - process number (to be swapped out)
 19217                              <1> 	; OUTPUTS ->
 19218                              <1> 	;    none
 19219                              <1> 	;
 19220                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
 19221                              <1> 	;
 19222 00005420 8B3D[D0740000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
 19223 00005426 B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 19224 0000542B BE[78740000]        <1> 	mov	esi, user ; active user (u) structure	
 19225 00005430 F3A5                <1> 	rep	movsd
 19226                              <1> 	;
 19227 00005432 8B35[7C740000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
 19228                              <1> 			     ;      points to user registers)
 19229 00005438 8B0D[78740000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 19230                              <1> 			     ; (for IRET)
 19231                              <1> 			     ; [u.sp] -> EIP (user)
 19232                              <1> 			     ; [u.sp+4]-> CS (user)
 19233                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 19234                              <1> 			     ; [u.sp+12] -> ESP (user)
 19235                              <1> 			     ; [u.sp+16] -> SS (user)	
 19236 0000543E 29F1                <1> 	sub	ecx, esi     ; required space for user registers
 19237 00005440 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 19238                              <1> 			     ; (for IRET) 	
 19239 00005443 C1E902              <1> 	shr	ecx, 2	     		
 19240 00005446 F3A5                <1> 	rep	movsd
 19241 00005448 C3                  <1> 	retn
 19242                              <1> 
 19243                              <1> 	; Original UNIX v1 'wswap' routine:
 19244                              <1> 	; wswap:
 19245                              <1> 		; mov *$30,u.emt / determines handling of emts
 19246                              <1>         	; mov *$10,u.ilgins / determines handling of 
 19247                              <1> 				; / illegal instructions
 19248                              <1> 		; mov u.break,r2 / put process program break address in r2
 19249                              <1> 		; inc r2 / add 1 to it 
 19250                              <1> 		; bic $1,r2 / make it even
 19251                              <1> 		; mov r2,u.break / set break to an even location
 19252                              <1> 		; mov u.usp,r3 / put users stack pointer 
 19253                              <1> 			     ; / at moment of swap in r3
 19254                              <1> 		; cmp r2,$core / is u.break less than $core
 19255                              <1> 		; blos 2f / yes
 19256                              <1> 		; cmp r2,r3 / no, is (u.break) greater than stack ptr.
 19257                              <1>        		; bhis 2f / yes
 19258                              <1> 	; 1:
 19259                              <1>        		; mov (r3)+,(r2)+ / no, pack stack next to users program
 19260                              <1> 		; cmp r3,$ecore / has stack reached end of core
 19261                              <1> 		; bne 1b / no, keep packing
 19262                              <1> 	 	; br 1f / yes
 19263                              <1> 	; 2:
 19264                              <1>        		; mov $ecore,r2 / put end of core in r2 
 19265                              <1> 	; 1:
 19266                              <1>        		; sub  $user,r2 / get number of bytes to write out 
 19267                              <1> 			   ; / (user up to end of stack gets written out)
 19268                              <1> 		; neg r2 / make it negative
 19269                              <1> 		; asr r2 / change bytes to words (divide by 2)
 19270                              <1> 		; mov r2,swp+4 / word count
 19271                              <1> 		; movb u.uno,r1 / move user process number to r1
 19272                              <1> 		; asl r1 / x2 for index
 19273                              <1>       		; mov r2,p.break-2(r1) / put negative of word count 
 19274                              <1> 				     ; / into the p.break table
 19275                              <1>        		; mov p.dska-2(r1),r1 / move disk address of swap area 
 19276                              <1> 				    ; /	for process to r1
 19277                              <1>        		; mov r1,swp+2 / put processes dska address in swp+2 
 19278                              <1> 			     ; / (block number)
 19279                              <1> 		; bis $1000,swp / set it up to write (set bit 9)
 19280                              <1>        		; jsr r0,ppoke / write process out on swap area of disk
 19281                              <1> 	; 1:
 19282                              <1>        		; tstb swp+1 / is lt done writing?
 19283                              <1>        		; bne 1b / no, wait
 19284                              <1> 		; rts r0 / yes, return to swap
 19285                              <1> 
 19286                              <1> rswap:  ; < swap in, swap from disk >
 19287                              <1> 	; 15/09/2015
 19288                              <1> 	; 28/08/2015
 19289                              <1> 	; 14/05/2015
 19290                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 19291                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19292                              <1> 	; 'rswap' reads a process whose number is in r1, 
 19293                              <1> 	; from disk into core.
 19294                              <1> 	;
 19295                              <1> 	; Retro UNIX 386 v1 modification ->
 19296                              <1> 	;       User (u) structure content and the user's register content
 19297                              <1> 	;	will be restored from process's/user's UPAGE (a page for
 19298                              <1> 	;	saving 'u' structure and user registers for task switching).
 19299                              <1> 	;	u.usp - points to kernel stack address which contains
 19300                              <1> 	;		user's registers while entering system call.  
 19301                              <1> 	;	u.sp  - points to kernel stack address 
 19302                              <1> 	;		to return from system call -for IRET-.
 19303                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 19304                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 19305                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 19306                              <1> 	;
 19307                              <1> 	; RETRO UNIX 8086 v1 modification ->
 19308                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19309                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19310                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19311                              <1> 	;	compatibles was using 1MB segmented memory 
 19312                              <1> 	;	in 8086/8088 times.
 19313                              <1> 	;
 19314                              <1> 	; INPUTS ->
 19315                              <1> 	;    r1 - process number of process to be read in
 19316                              <1> 	;    p.break - negative of word count of process 
 19317                              <1> 	;    p.dska - disk address of the process		
 19318                              <1> 	;    u.emt - determines handling of emt's 	
 19319                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 19320                              <1> 	; OUTPUTS ->
 19321                              <1> 	;    8 = (u.ilgins)
 19322                              <1> 	;    24 = (u.emt)
 19323                              <1> 	;    swp - bit 10 is set to indicate read 
 19324                              <1> 	;		(bit 15=0 when reading is done)	
 19325                              <1> 	;    swp+2 - disk block address
 19326                              <1> 	;    swp+4 - negative word count 	
 19327                              <1> 	;      ((swp+6 - address of user structure)) 
 19328                              <1> 	;
 19329                              <1> 	; RETRO UNIX 8086 v1 input/output:
 19330                              <1> 	;
 19331                              <1> 	; INPUTS ->
 19332                              <1> 	;    AL	- new process number (to be swapped in)	 
 19333                              <1> 	; OUTPUTS ->
 19334                              <1> 	;    none
 19335                              <1> 	;
 19336                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
 19337                              <1> 	;
 19338                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
 19339 00005449 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
 19340 0000544B B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 19341 00005450 BF[78740000]        <1> 	mov	edi, user ; active user (u) structure	
 19342 00005455 F3A5                <1> 	rep	movsd
 19343 00005457 58                  <1> 	pop	eax ; 15/09/2015, 'rswap' return address 
 19344 00005458 8B3D[7C740000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
 19345                              <1> 			     ;      points to user registers)
 19346 0000545E 8B0D[78740000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 19347                              <1> 			     ; (for IRET)
 19348                              <1> 			     ; [u.sp] -> EIP (user)
 19349                              <1> 			     ; [u.sp+4]-> CS (user)
 19350                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 19351                              <1> 			     ; [u.sp+12] -> ESP (user)
 19352                              <1> 			     ; [u.sp+16] -> SS (user)		
 19353                              <1> 	; 28/08/2015
 19354 00005464 29F9                <1> 	sub	ecx, edi     ; required space for user registers
 19355 00005466 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 19356                              <1> 			     ; (for IRET) 	
 19357 00005469 C1E902              <1> 	shr	ecx, 2	       		
 19358 0000546C F3A5                <1> 	rep	movsd
 19359 0000546E 8B25[7C740000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
 19360 00005474 50                  <1> 	push	eax ; 15/09/2015 'rswap' return address
 19361 00005475 C3                  <1> 	retn
 19362                              <1> 
 19363                              <1> 	; Original UNIX v1 'rswap'  and 'unpack' routines:
 19364                              <1> 	;rswap:
 19365                              <1>        		; asl r1 / process number x2 for index
 19366                              <1>        		; mov p.break-2(r1), swp+4 / word count
 19367                              <1>        		; mov p.dska-2(r1),swp+2 / disk address
 19368                              <1>        		; bis $2000,swp / read
 19369                              <1>        		; jsr r0,ppoke / read it in 
 19370                              <1> 	; 1:
 19371                              <1>        		; tstb swp+1 / done
 19372                              <1>        		; bne 1b / no, wait for bit 15 to clear (inhibit bit)
 19373                              <1>        		; mov u.emt,*$30 / yes move these
 19374                              <1>        		; mov u.ilgins,*$10 / back
 19375                              <1>        		; rts r0 / return
 19376                              <1> 
 19377                              <1> 	;unpack: ; / move stack back to its normal place
 19378                              <1> 		; mov u.break,r2 / r2 points to end of user program
 19379                              <1>        		; cmp r2,$core / at beginning of user program yet?
 19380                              <1> 		; blos 2f / yes, return
 19381                              <1> 		; cmp r2,u.usp / is break_above the stack pointer 
 19382                              <1> 			     ; / before swapping
 19383                              <1> 		; bhis 2f / yes, return
 19384                              <1> 		; mov $ecore,r3 / r3 points to end of core
 19385                              <1> 		; add r3,r2
 19386                              <1> 		; sub u.usp,r2 / end of users stack is in r2
 19387                              <1> 	; 1:
 19388                              <1> 		; mov -(r2),-(r3) / move stack back to its normal place
 19389                              <1> 		; cmp r2,u.break / in core
 19390                              <1> 		; bne 1b
 19391                              <1> 	; 2:
 19392                              <1>        		; rts r0
 19393                              <1> 
 19394                              <1> putlu: 
 19395                              <1> 	; 12/09/2015
 19396                              <1> 	; 02/09/2015
 19397                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19398                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 19399                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
 19400                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
 19401                              <1> 	; the last process on the queue to process in r1 by putting
 19402                              <1> 	; the process number in r1 into the last process's link.
 19403                              <1> 	;
 19404                              <1> 	; INPUTS ->
 19405                              <1> 	;    r1 - user process number
 19406                              <1> 	;    r2 - points to lowest priority queue 
 19407                              <1> 	;    p.dska - disk address of the process		
 19408                              <1> 	;    u.emt - determines handling of emt's 	
 19409                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 19410                              <1> 	; OUTPUTS ->
 19411                              <1> 	;    r3 - process number of last process on the queue upon
 19412                              <1> 	;	  entering putlu
 19413                              <1> 	;    p.link-1 + r3 - process number in r1
 19414                              <1> 	;    r2 - points to lowest priority queue
 19415                              <1> 	;
 19416                              <1> 	; ((Modified registers: EDX, EBX)) 
 19417                              <1> 	;
 19418                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
 19419                              <1> 
 19420                              <1> 	; eBX = r2
 19421                              <1> 	; eAX = r1 (AL=r1b)
 19422                              <1> 
 19423 00005476 BB[72740000]        <1> 	mov	ebx, runq
 19424 0000547B 0FB613              <1> 	movzx  	edx, byte [ebx]
 19425 0000547E 43                  <1> 	inc	ebx
 19426 0000547F 20D2                <1> 	and	dl, dl
 19427                              <1> 		; tstb (r2)+ / is queue empty?
 19428 00005481 740A                <1>        	jz	short putlu_1
 19429                              <1> 		; beq 1f / yes, branch
 19430 00005483 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
 19431                              <1> 		; movb (r2),r3 / no, save the "last user" process number
 19432                              <1> 			     ; / in r3
 19433 00005485 8882[F5710000]      <1>        	mov	[edx+p.link-1], al
 19434                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
 19435                              <1> 			     ; / "last users" link
 19436 0000548B EB03                <1> 	jmp	short putlu_2
 19437                              <1> 		; br 2f /
 19438                              <1> putlu_1: ; 1:
 19439 0000548D 8843FF              <1> 	mov	[ebx-1], al
 19440                              <1>        		; movb r1,-1(r2) / user is only user; 
 19441                              <1> 			    ; / put process no. at beginning and at end
 19442                              <1> putlu_2: ; 2: 
 19443 00005490 8803                <1> 	mov	[ebx], al
 19444                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
 19445                              <1> 			     ; / on the queue
 19446 00005492 88C2                <1> 	mov	dl, al
 19447 00005494 88B2[F5710000]      <1>         mov     [edx+p.link-1], dh ; 0
 19448                              <1> 		; dec r2 / restore r2
 19449 0000549A C3                  <1>         retn
 19450                              <1> 		; rts r0
 19451                              <1> 
 19452                              <1> ;copyz:
 19453                              <1> ;       mov     r1,-(sp) / put r1 on stack
 19454                              <1> ;       mov     r2,-(sp) / put r2 on stack
 19455                              <1> ;       mov     (r0)+,r1
 19456                              <1> ;       mov     (r0)+,r2
 19457                              <1> ;1:
 19458                              <1> ;       clr     (r1)+ / clear all locations between r1 and r2
 19459                              <1> ;       cmp     r1,r2 
 19460                              <1> ;       blo     1b
 19461                              <1> ;       mov     (sp)+,r2 / restore r2
 19462                              <1> ;       mov     (sp)+,r1 / restore r1
 19463                              <1> ;       rts     r0 
 19464                              <1> 
 19465                              <1> idle:
 19466                              <1> 	; 01/09/2015
 19467                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19468                              <1> 	; 10/04/2013 - 23/10/2013 (Retro UNIX 8086 v1)
 19469                              <1> 	; (idle & wait loop)
 19470                              <1> 	; Retro Unix 8086 v1 modification on original UNIX v1
 19471                              <1> 	; idle procedure!
 19472                              <1>       	;
 19473                              <1>   	; 01/09/2015
 19474 0000549B FB                  <1> 	sti
 19475                              <1>       	; 29/07/2013
 19476 0000549C F4                  <1>       	hlt
 19477 0000549D 90                  <1>       	nop ; 10/10/2013
 19478 0000549E 90                  <1>       	nop
 19479 0000549F 90                  <1>       	nop
 19480                              <1>       	; 23/10/2013
 19481 000054A0 90                  <1>       	nop
 19482 000054A1 90                  <1>       	nop
 19483 000054A2 90                  <1>       	nop
 19484 000054A3 90                  <1>       	nop
 19485 000054A4 C3                  <1>       	retn      
 19486                              <1> 
 19487                              <1> 	;mov *$ps,-(sp) / save ps on stack
 19488                              <1> 	;clr *$ps / clear ps
 19489                              <1> 	;mov clockp,-(sp) / save clockp on stack
 19490                              <1> 	;mov (r0)+,clockp / arg to idle in clockp
 19491                              <1> 	;1 / wait for interrupt
 19492                              <1> 	;mov (sp)+,clockp / restore clockp, ps
 19493                              <1> 	;mov (sp)+,*$ps
 19494                              <1> 	;rts r0
 19495                              <1> 
 19496                              <1> clear:
 19497                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19498                              <1> 	; 09/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 19499                              <1> 	; 'clear' zero's out of a block (whose block number is in r1)
 19500                              <1> 	; on the current device (cdev)
 19501                              <1> 	;	
 19502                              <1> 	; INPUTS ->
 19503                              <1> 	;    r1 - block number of block to be zeroed
 19504                              <1> 	;    cdev - current device number 
 19505                              <1> 	; OUTPUTS ->
 19506                              <1> 	;    a zeroed I/O buffer onto the current device
 19507                              <1> 	;    r1 - points to last entry in the I/O buffer
 19508                              <1> 	;
 19509                              <1> 	; ((AX = R1)) input/output
 19510                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 14/11/2012, UNIXCOPY.ASM)
 19511                              <1>         ;    ((Modified registers: EDX, ECX, EBX, ESI, EDI, EBP))  
 19512                              <1> 
 19513 000054A5 E8AB0D0000          <1> 	call 	wslot
 19514                              <1> 		; jsr r0,wslot / get an I/O buffer set bits 9 and 15 in first
 19515                              <1>                    ; / word of I/O queue r5 points to first data word in buffer
 19516 000054AA 89DF                <1> 	mov	edi, ebx ; r5
 19517 000054AC 89C2                <1> 	mov	edx, eax
 19518 000054AE B980000000          <1> 	mov	ecx, 128
 19519                              <1> 		; mov $256.,r3
 19520 000054B3 31C0                <1> 	xor	eax, eax
 19521 000054B5 F3AB                <1> 	rep	stosd
 19522 000054B7 89D0                <1> 	mov	eax, edx
 19523                              <1> ; 1: 
 19524                              <1>        		; clr (r5)+ / zero data word in buffer
 19525                              <1>        		; dec r3
 19526                              <1>        		; bgt 1b / branch until all data words in buffer are zero
 19527 000054B9 E8B30D0000          <1> 	call	dskwr
 19528                              <1> 		; jsr r0,dskwr / write zeroed buffer area out onto physical
 19529                              <1>                              ; / block specified in r1
 19530                              <1> 	; eAX (r1) = block number
 19531 000054BE C3                  <1> 	retn
 19532                              <1> 		; rts r0
 19533                                  %include 'u4.s'        ; 15/04/2015
 19534                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS4.INC
 19535                              <1> ; Last Modification: 14/10/2015
 19536                              <1> ; ----------------------------------------------------------------------------
 19537                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 19538                              <1> ; (v0.1 - Beginning: 11/07/2012)
 19539                              <1> ;
 19540                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 19541                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 19542                              <1> ; <Bell Laboratories (17/3/1972)>
 19543                              <1> ; <Preliminary Release of UNIX Implementation Document>
 19544                              <1> ;
 19545                              <1> ; Retro UNIX 8086 v1 - U4.ASM (04/07/2014) //// UNIX v1 -> u4.s
 19546                              <1> ;
 19547                              <1> ; ****************************************************************************
 19548                              <1> 
 19549                              <1> ;setisp:
 19550                              <1>        ;mov     r1,-(sp)
 19551                              <1>        ;mov     r2,-(sp)
 19552                              <1>        ;mov     r3,-(sp)
 19553                              <1>        ;mov     clockp,-(sp)
 19554                              <1>        ;mov     $s.syst+2,clockp
 19555                              <1>        ;jmp     (r0)
 19556                              <1> 
 19557                              <1> clock: ; / interrupt from 60 cycle clock
 19558                              <1> 	
 19559                              <1> 	; 14/10/2015
 19560                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 19561                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
 19562                              <1> 
 19563                              <1>        ;mov     r0,-(sp) / save r0
 19564                              <1>        ;tst     *$lks / restart clock?
 19565                              <1>        ;mov     $s.time+2,r0 / increment the time of day
 19566                              <1>        ;inc     (r0)
 19567                              <1>        ;bne     1f
 19568                              <1>        ;inc     -(r0)
 19569                              <1> ;1:
 19570                              <1>        ;mov     clockp,r0 / increment appropriate time category
 19571                              <1>        ;inc     (r0)
 19572                              <1>        ;bne     1f
 19573                              <1>        ;inc     -(r0)
 19574                              <1> ;1:
 19575                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 19576                              <1> 
 19577 000054BF 803D[C2740000]00    <1> 	cmp	byte [u.quant], 0
 19578 000054C6 772C                <1> 	ja	short clk_1
 19579                              <1> 	;
 19580 000054C8 803D[77740000]FF    <1>         cmp     byte [sysflg], 0FFh ; user or system space ?
 19581 000054CF 7529                <1> 	jne	short clk_2 ; system space (sysflg <> 0FFh)
 19582 000054D1 803D[CF740000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ?
 19583 000054D8 761A                <1> 	jna	short clk_1 ; yes, do not swap out
 19584 000054DA 66833D[C4740000]00  <1> 	cmp	word [u.intr], 0
 19585 000054E2 7616                <1> 	jna	short clk_2
 19586                              <1> clk_0:
 19587                              <1> 	; 14/10/2015
 19588 000054E4 FE05[77740000]      <1> 	inc	byte [sysflg] 	; Now, we are in system space
 19589 000054EA 58                  <1> 	pop	eax ; return address to the timer interrupt
 19590                              <1> 	;
 19591 000054EB B020                <1> 	MOV	AL,EOI			; GET END OF INTERRUPT MASK
 19592                              <1> 	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
 19593 000054ED E620                <1> 	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
 19594                              <1> 	;
 19595 000054EF E904ECFFFF          <1> 	jmp     sysrelease ; 'sys release' by clock/timer
 19596                              <1> clk_1:
 19597 000054F4 FE0D[C2740000]      <1> 	dec	byte [u.quant]
 19598                              <1> clk_2:
 19599 000054FA C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
 19600                              <1> 
 19601                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
 19602                              <1> 
 19603                              <1>        ;mov     $uquant,r0 / decrement user time quantum
 19604                              <1>        ;decb    (r0)
 19605                              <1>        ;bge     1f / if less than 0
 19606                              <1>        ;clrb    (r0) / make it 0
 19607                              <1> ;1: / decrement time out counts return now if priority was not 0
 19608                              <1>        ;cmp     4(sp),$200 / ps greater than or equal to 200
 19609                              <1>        ;bge     2f / yes, check time outs
 19610                              <1>        ;tstb    (r0) / no, user timed out?
 19611                              <1>        ;bne     1f / no
 19612                              <1>        ;cmpb    sysflg,$-1 / yes, are we outside the system?
 19613                              <1>        ;bne     1f / no, 1f
 19614                              <1>        ;mov     (sp)+,r0 / yes, put users r0 in r0
 19615                              <1>        ;sys     0 / sysrele
 19616                              <1>        ;rti
 19617                              <1> ;2: / priority is high so just decrement time out counts
 19618                              <1>        ;mov     $toutt,r0 / r0 points to beginning of time out table
 19619                              <1> ;2:
 19620                              <1>        ;tstb    (r0) / is the time out?
 19621                              <1>        ;beq     3f / yes, 3f (get next entry)
 19622                              <1>        ;decb    (r0) / no, decrement the time
 19623                              <1>        ;bne     3f / isit zero now?
 19624                              <1>        ;incb    (r0) / yes, increment the time
 19625                              <1> ;3:
 19626                              <1>        ;inc     r0 / next entry
 19627                              <1>        ;cmp     r0,$touts / end of toutt table?
 19628                              <1>        ;blo     2b / no, check this entry
 19629                              <1>        ;mov     (sp)+,r0 / yes, restore r0
 19630                              <1>        ;rti / return from interrupt
 19631                              <1> ;1: / decrement time out counts; if 0 call subroutine
 19632                              <1>        ;mov     (sp)+,r0 / restore r0
 19633                              <1>        ;mov     $240,*$ps / set processor priority to 5
 19634                              <1>        ;jsr     r0,setisp / save registers
 19635                              <1>        ;mov     $touts-toutt-1,r0 / set up r0 as index to decrement thru
 19636                              <1>                                ;  / the table
 19637                              <1> ;1:
 19638                              <1>        ;tstb    toutt(r0) / is the time out for this entry
 19639                              <1>        ;beq     2f / yes
 19640                              <1>        ;decb    toutt(r0) / no, decrement the time
 19641                              <1>        ;bne     2f / is the time 0, now
 19642                              <1>        ;asl     r0 / yes, 2 x r0 to get word index for tout entry
 19643                              <1>        ;jsr     r0,*touts(r0) / go to appropriate routine specified in this
 19644                              <1>        ;asr     r0 / touts entry; set r0 back to toutt index
 19645                              <1> ;2:
 19646                              <1>        ;dec     r0 / set up r0 for next entry
 19647                              <1>        ;bge     1b / finished? , no, go back
 19648                              <1>        ;br      retisp / yes, restore registers and do a rti
 19649                              <1> 
 19650                              <1> ;retisp:
 19651                              <1>        ;mov     (sp)+,clockp / pop values before interrupt off the stack
 19652                              <1>        ;mov     (sp)+,r3
 19653                              <1>        ;mov     (sp)+,r2
 19654                              <1>        ;mov     (sp)+,r1
 19655                              <1>        ;mov     (sp)+,r0
 19656                              <1>        ;rti     / return from interrupt
 19657                              <1> 
 19658                              <1> 
 19659                              <1> wakeup: ; / wakeup processes waiting for an event 
 19660                              <1> 	; / by linking them to the queue
 19661                              <1> 	;
 19662                              <1> 	; 15/09/2015
 19663                              <1> 	; 29/06/2015
 19664                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 19665                              <1> 	;
 19666                              <1> 	; 15/05/2013 - 02/06/2014
 19667                              <1> 	; Retro UNIX 8086 v1 modification !
 19668                              <1> 	; (Process/task switching routine by using
 19669                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.)
 19670                              <1> 	;
 19671                              <1> 	; In original UNIX v1, 'wakeup' is called to wake the process
 19672                              <1> 	; sleeping in the specified wait channel by creating a link 
 19673                              <1> 	; to it from the last user process on the run queue.
 19674                              <1> 	; If there is no process to wake up, nothing happens.
 19675                              <1> 	;
 19676                              <1> 	; In Retro UNIX 8086 v1, Int 09h keyboard interrupt will set
 19677                              <1> 	; 'switching' status of the current process (owns current tty)
 19678                              <1> 	; (via alt + function keys) to a process which has highest
 19679                              <1> 	; priority (on run queue) on the requested tty (0 to 7, except
 19680                              <1> 	; 8 and 9 which are tty identifiers of COM1, COM2 serial ports)
 19681                              <1> 	; as it's console tty. (NOTE: 'p.ttyc' is used to set console
 19682                              <1> 	; tty for tty switching by keyboard.)	 
 19683                              <1> 	; 
 19684                              <1> 	; INPUT -> 
 19685                              <1> 	;	   AL = wait channel (r3) ('tty number' for now)
 19686                              <1> 	;	   ;;EBX = Run queue (r2) offset
 19687                              <1> 	;
 19688                              <1> 	; ((modified registers: EAX, EBX))
 19689                              <1> 	;
 19690 000054FB 0FB6D8              <1> 	movzx	ebx, al ; 29/06/2015
 19691 000054FE 81C3[08710000]      <1> 	add	ebx, wlist
 19692 00005504 8A03                <1> 	mov	al, [ebx] ; waiting list (waiting process number)
 19693 00005506 20C0                <1> 	and	al, al
 19694 00005508 7424                <1> 	jz	short wa0 ; nothing to wakeup
 19695                              <1> 	;
 19696 0000550A 30E4                <1> 	xor	ah, ah
 19697 0000550C 8825[C2740000]      <1> 	mov 	[u.quant], ah ; 0 ; time quantum = 0	
 19698 00005512 8823                <1> 	mov	[ebx], ah ; 0 ; zero wait channel entry
 19699                              <1> 	; 15/09/2015
 19700 00005514 0FB6D8              <1> 	movzx	ebx, al
 19701 00005517 88A3[E5710000]      <1> 	mov	[ebx+p.waitc-1], ah ; 0
 19702 0000551D FEC4                <1> 	inc	ah
 19703 0000551F 88A3[05720000]      <1> 	mov	byte [ebx+p.stat-1], ah ; 1 ; SRUN
 19704                              <1> 	;
 19705 00005525 57                  <1> 	push	edi
 19706 00005526 52                  <1> 	push	edx
 19707 00005527 E84AFFFFFF          <1> 	call	putlu
 19708 0000552C 5A                  <1> 	pop	edx
 19709 0000552D 5F                  <1> 	pop	edi
 19710                              <1> wa0:
 19711 0000552E C3                  <1> 	retn
 19712                              <1> 
 19713                              <1> sleep: 
 19714                              <1> 	; 15/09/2015
 19715                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 19716                              <1> 	;
 19717                              <1> 	; 09/05/2013 - 20/03/2014
 19718                              <1> 	;
 19719                              <1> 	; Retro UNIX 8086 v1 modification !
 19720                              <1> 	; (Process/task switching and quit routine by using
 19721                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 19722                              <1> 	;
 19723                              <1> 	; In original UNIX v1, 'sleep' is called to wait for
 19724                              <1> 	; tty and tape output or input becomes available
 19725                              <1> 	; and process is put on waiting channel and swapped out,
 19726                              <1> 	; then -when the tty or tape is ready to write or read-
 19727                              <1> 	; 'wakeup' gets process back to active swapped-in status.)
 19728                              <1> 	;
 19729                              <1> 	; In Retro UNIX 8086 v1, Int 1Bh ctrl+brk interrupt and
 19730                              <1> 	; Int 09h keyboard interrupt will set 'quit' or 'switching'		
 19731                              <1> 	; status of the current process also INT 1Ch will count down
 19732                              <1> 	; 'uquant' value and INT 09h will redirect scancode of keystroke
 19733                              <1> 	; to tty buffer of the current process and kernel will get
 19734                              <1> 	; user input by using tty buffer of the current process
 19735                              <1> 	; (instead of standard INT 16h interrupt).
 19736                              <1> 	; TTY output will be redirected to related video page of text mode
 19737                              <1> 	; (INT 10h will be called with different video page depending
 19738                              <1> 	; on tty assignment of the active process: 0 to 7 for
 19739                              <1> 	; pseudo screens.)
 19740                              <1> 	;
 19741                              <1> 	; In Retro UNIX 8086 v1, 'sleep' will be called to wait for
 19742                              <1> 	; a keystroke from keyboard or wait for reading or writing
 19743                              <1> 	; characters/data on serial port(s).
 19744                              <1> 	;
 19745                              <1> 	; Character/Terminal input/output through COM1 and COM2 will be
 19746                              <1> 	; performed by related routines in addition to pseudo TTY routines.
 19747                              <1> 	; 
 19748                              <1> 	; R1 = AH = wait channel (0-9 for TTYs) ; 05/10/2013 (22/09/2013)
 19749                              <1> 	;
 19750                              <1> 	;; 05/10/2013
 19751                              <1>         ;10/12/2013
 19752                              <1> 	;cmp   byte [u.uno], 1
 19753                              <1>         ;ja    short sleep0
 19754                              <1> 	;retn
 19755                              <1> 
 19756                              <1> 	; 20/03/2014
 19757                              <1> 	;mov	bx, [runq]
 19758                              <1> 	;cmp	bl, bh
 19759                              <1> 	;jne	short sleep0	
 19760                              <1> 	; 25/02/2014
 19761                              <1> 	;cmp word ptr [runq], 0
 19762                              <1> 	;ja short sleep0	
 19763                              <1> 	;retn
 19764                              <1> sleep0:
 19765                              <1> 	;
 19766 0000552F E854000000          <1> 	call	isintr
 19767 00005534 0F8562EBFFFF        <1> 	jnz	sysret
 19768                              <1> 		; / wait for event
 19769                              <1>        		; jsr r0,isintr / check to see if interrupt 
 19770                              <1> 			      ; / or quit from user
 19771                              <1>                		; br 2f / something happened
 19772                              <1> 			      ; / yes, his interrupt so return
 19773                              <1>                      	      ;	/ to user
 19774                              <1> 
 19775                              <1> 	; 30/06/2015
 19776 0000553A 0FB6DC              <1>     	movzx	ebx, ah ; 30/06/2015
 19777 0000553D 81C3[08710000]      <1> 	add	ebx, wlist
 19778 00005543 8A03                <1> 	mov	al, [ebx]
 19779 00005545 20C0                <1> 	and	al, al
 19780 00005547 7407                <1> 	jz	short sleep1
 19781 00005549 53                  <1> 	push	ebx
 19782 0000554A E827FFFFFF          <1> 	call	putlu
 19783 0000554F 5B                  <1> 	pop	ebx
 19784                              <1> sleep1:
 19785 00005550 A0[CF740000]        <1> 	mov	al, [u.uno]    
 19786 00005555 8803                <1>   	mov	[ebx], al 	; put the process number
 19787                              <1> 				; in the wait channel
 19788                              <1> 		; mov (r0)+,r1 / put number of wait channel in r1
 19789                              <1> 		; movb wlist(r1),-(sp) / put old process number in there,
 19790                              <1> 				     ; / on the stack
 19791                              <1>        		; movb u.uno,wlist(r1) / put process number of process
 19792                              <1> 				     ; / to put to sleep in there
 19793                              <1>         ; 15/09/2015
 19794 00005557 0FB6D8              <1> 	movzx	ebx, al
 19795 0000555A C683[05720000]04    <1>         mov     byte [ebx+p.stat-1], 4 ; SSLEEP
 19796 00005561 FEC4                <1> 	inc	ah
 19797 00005563 88A3[E5710000]      <1> 	mov	[ebx+p.waitc-1], ah ; wait channel + 1
 19798                              <1> 	;
 19799 00005569 66FF35[66740000]    <1> 	push    word [cdev]
 19800                              <1> 		; mov cdev,-(sp) / nothing happened in isintr so
 19801 00005570 E833FEFFFF          <1> 	call	swap
 19802                              <1>        		; jsr r0,swap / swap out process that needs to sleep
 19803 00005575 668F05[66740000]    <1>         pop     word [cdev]
 19804                              <1> 		; mov (sp)+,cdev / restore device
 19805 0000557C E807000000          <1> 	call	isintr
 19806                              <1> 	; 22/09/2013
 19807 00005581 0F8515EBFFFF        <1> 	jnz	sysret         
 19808                              <1> 		; jsr r0,isintr / check for interrupt of new process
 19809                              <1>                		; br 2f / yes, return to new user
 19810                              <1> 		; movb (sp)+,r1 / no, r1 = old process number that was 
 19811                              <1> 				; / originally on the wait channel
 19812                              <1>        		; beq 1f / if 0 branch
 19813                              <1>   		; mov $runq+4,r2 / r2 points to lowest priority queue
 19814                              <1>        		; mov $300,*$ps / processor priority = 6
 19815                              <1> 		; jsr r0,putlu / create link to old process number
 19816                              <1>        		; clr *$ps / clear the status; process priority = 0
 19817                              <1>      ;1:
 19818 00005587 C3                  <1> 	retn
 19819                              <1> 		; rts r0 / return
 19820                              <1>      ;2:
 19821                              <1>         ;;jmp	sysret
 19822                              <1> 		; jmp sysret / return to user
 19823                              <1> 
 19824                              <1> isintr:
 19825                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 19826                              <1> 	;
 19827                              <1> 	; 09/05/2013 - 30/05/2014
 19828                              <1> 	;
 19829                              <1> 	; Retro UNIX 8086 v1 modification !
 19830                              <1> 	; (Process/task switching and quit routine by using
 19831                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 19832                              <1> 	;
 19833                              <1> 	; Retro UNIX 8086 v1 modification:
 19834                              <1> 	; 'isintr' checks if user interrupt request is enabled
 19835                              <1> 	;  and there is a 'quit' request by user;
 19836                              <1> 	;  otherwise, 'isintr' will return with zf=1 that means
 19837                              <1> 	;  "nothing to do". (20/10/2013)
 19838                              <1> 	;
 19839                              <1> 	; 20/10/2013
 19840 00005588 66833D[B0740000]00  <1> 	cmp 	word [u.ttyp], 0 ; has process got a tty ?
 19841 00005590 7622                <1> 	jna	short isintr2 ; retn
 19842                              <1> 	; 03/09/2013
 19843                              <1> 	; (nothing to do)
 19844                              <1> 	;retn
 19845                              <1> 	; 22/09/2013
 19846 00005592 66833D[C4740000]00  <1> 	cmp	word [u.intr], 0
 19847 0000559A 7618                <1> 	jna	short isintr2 ; retn
 19848                              <1> 	; 30/05/2014
 19849 0000559C 6650                <1> 	push	ax 
 19850 0000559E 66A1[C6740000]      <1> 	mov	ax, [u.quit]
 19851 000055A4 6609C0              <1> 	or	ax, ax ; 0 ?
 19852 000055A7 7409                <1> 	jz	short isintr1 ; zf = 1
 19853 000055A9 6683F8FE            <1> 	cmp	ax, 0FFFEh  ; 'ctrl + brk' check
 19854 000055AD 7703                <1> 	ja	short isintr1 ; 0FFFFh, zf = 0
 19855 000055AF 6631C0              <1> 	xor	ax, ax ; zf = 1
 19856                              <1> isintr1:
 19857 000055B2 6658                <1> 	pop	ax
 19858                              <1> isintr2: ; 22/09/2013
 19859                              <1> 	; zf=1 -> nothing to do
 19860 000055B4 C3                  <1> 	retn
 19861                              <1> 
 19862                              <1> 	; UNIX v1 original 'isintr' routine... 
 19863                              <1>        	;mov     r1,-(sp) / put number of wait channel on the stack
 19864                              <1>        	;mov     r2,-(sp) / save r2
 19865                              <1>        	;mov     u.ttyp,r1 / r1 = pointer to buffer of process control
 19866                              <1>         ;                 / typewriter
 19867                              <1>        	;beq     1f / if 0, do nothing except skip return
 19868                              <1>        	;movb    6(r1),r1 / put interrupt char in the tty buffer in r1
 19869                              <1>        	;beq     1f / if its 0 do nothing except skip return
 19870                              <1>        	;cmp     r1,$177 / is interrupt char = delete?
 19871                              <1>        	;bne     3f / no, so it must be a quit (fs)
 19872                              <1>        	;tst     u.intr / yes, value of u.intr determines handling
 19873                              <1>         ;              / of interrupts
 19874                              <1>        	;bne     2f / if not 0, 2f. If zero do nothing.
 19875                              <1>      ;1:
 19876                              <1>        	;tst     (r0)+ / bump r0 past system return (skip)
 19877                              <1>      ;4:
 19878                              <1>        	;mov     (sp)+,r2 / restore r1 and r2
 19879                              <1>        	;mov     (sp)+,r1
 19880                              <1>        	;rts     r0
 19881                              <1>      ;3: / interrupt char = quit (fs)
 19882                              <1>        	;tst     u.quit / value of u.quit determines handling of quits
 19883                              <1>        	;beq     1b / u.quit = 0 means do nothing
 19884                              <1>      ;2: / get here because either u.intr <> 0 or u.qult <> O
 19885                              <1>        	;mov     $tty+6,r1 / move pointer to tty block into r1
 19886                              <1>      ;1: / find process control tty entry in tty block
 19887                              <1>        	;cmp     (r1),u.ttyp / is this the process control tty buffer?
 19888                              <1>        	;beq     1f / block found go to 1f
 19889                              <1>        	;add     $8,r1 / look at next tty block
 19890                              <1>        	;cmp     r1,$tty+[ntty*8]+6 / are we at end of tty blocks
 19891                              <1>        	;blo     1b / no
 19892                              <1>        	;br      4b / no process control tty found so go to 4b
 19893                              <1>      ;1:
 19894                              <1>        	;mov     $240,*$ps / set processor priority to 5
 19895                              <1>        	;movb    -3(r1),0f / load getc call argument; character llst
 19896                              <1>         ;                  / identifier
 19897                              <1>        	;inc     0f / increment
 19898                              <1>      ;1:
 19899                              <1>        	;jsr     r0,getc; 0:.. / erase output char list for control
 19900                              <1>         ;        br 4b / process tty. This prevents a line of stuff
 19901                              <1>         ;             / being typed out after you hit the interrupt
 19902                              <1>         ;             / key
 19903                              <1>        	;br      1b
 19904                                  %include 'u5.s'        ; 03/06/2015
 19905                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS5.INC
 19906                              <1> ; Last Modification: 14/11/2015
 19907                              <1> ; ----------------------------------------------------------------------------
 19908                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 19909                              <1> ; (v0.1 - Beginning: 11/07/2012)
 19910                              <1> ;
 19911                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 19912                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 19913                              <1> ; <Bell Laboratories (17/3/1972)>
 19914                              <1> ; <Preliminary Release of UNIX Implementation Document>
 19915                              <1> ;
 19916                              <1> ; Retro UNIX 8086 v1 - U5.ASM (07/08/2013) //// UNIX v1 -> u5.s
 19917                              <1> ;
 19918                              <1> ; ****************************************************************************
 19919                              <1> 
 19920                              <1> mget:
 19921                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 19922                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 19923                              <1> 	;
 19924                              <1> 	; Get existing or (allocate) a new disk block for file
 19925                              <1> 	; 
 19926                              <1> 	; INPUTS ->
 19927                              <1> 	;    u.fofp (file offset pointer)
 19928                              <1> 	;    inode 
 19929                              <1> 	;    u.off (file offset)
 19930                              <1> 	; OUTPUTS ->
 19931                              <1> 	;    r1 (physical block number)
 19932                              <1> 	;    r2, r3, r5 (internal)
 19933                              <1> 	;
 19934                              <1> 	; ((AX = R1)) output
 19935                              <1> 	;    (Retro UNIX Prototype : 05/03/2013 - 14/11/2012, UNIXCOPY.ASM)
 19936                              <1>         ;    ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 19937                              <1> 
 19938                              <1> 		; mov *u.fofp,mq / file offset in mq
 19939                              <1> 		; clr ac / later to be high sig
 19940                              <1> 		; mov $-8,lsh   / divide ac/mq by 256.
 19941                              <1> 		; mov mq,r2
 19942                              <1> 		; bit $10000,i.flgs / lg/sm is this a large or small file
 19943                              <1> 		; bne 4f / branch for large file
 19944                              <1> mget_0:	
 19945 000055B5 8B35[90740000]      <1>         mov     esi, [u.fofp]
 19946 000055BB 0FB65E01            <1>         movzx   ebx, byte [esi+1]
 19947                              <1>         ; BX = r2
 19948 000055BF 66F705[56710000]00- <1>         test 	word [i.flgs], 4096 ; 1000h
 19949 000055C7 10                  <1>
 19950                              <1> 			  	     ; is this a large or small file
 19951 000055C8 756F                <1> 	jnz 	short mget_5 ; 4f ; large file
 19952                              <1> 
 19953 000055CA F6C3F0              <1>         test    bl, 0F0h ; !0Fh                    
 19954                              <1> 		; bit $!17,r2
 19955 000055CD 7526                <1> 	jnz 	short mget_2
 19956                              <1> 		; bne 3f / branch if r2 greater than or equal to 16
 19957 000055CF 80E30E              <1>         and     bl, 0Eh  
 19958                              <1> 		; bic $!16,r2 / clear all bits but bits 1,2,3
 19959 000055D2 0FB783[5C710000]    <1> 	movzx 	eax, word [ebx+i.dskp] ; AX = R1, physical block number
 19960                              <1> 		; mov i.dskp(r2),r1 / r1 has physical block number
 19961 000055D9 6609C0              <1> 	or 	ax, ax
 19962 000055DC 7516                <1> 	jnz 	short mget_1 
 19963                              <1> 		; bne 2f / if physical block num is zero then need a new block
 19964                              <1> 		       ; / for file
 19965 000055DE E8AB000000          <1> 	call 	alloc
 19966                              <1> 		; jsr r0,alloc / allocate a new block
 19967                              <1>          ; eAX (r1) = Physical block number
 19968 000055E3 668983[5C710000]    <1> 	mov 	[ebx+i.dskp], ax
 19969                              <1> 		; mov r1,i.dskp(r2) / physical block number stored in i-node
 19970 000055EA E84C020000          <1> 	call 	setimod	
 19971                              <1> 		; jsr r0,setimod / set inode modified byte (imod)
 19972 000055EF E8B1FEFFFF          <1> 	call	clear
 19973                              <1> 		; jsr r0,clear / zero out disk/drum block just allocated
 19974                              <1> mget_1: ; 2:
 19975                              <1>         ; eAX (r1) = Physical block number
 19976 000055F4 C3                  <1> 	retn 
 19977                              <1> 		; rts r0
 19978                              <1> mget_2: ; 3: / adding on block which changes small file to a large file
 19979 000055F5 E894000000          <1> 	call 	alloc
 19980                              <1> 		; jsr r0,alloc / allocate a new block for this file;
 19981                              <1> 	                     ; / block number in r1
 19982                              <1>         ; eAX (r1) = Physical block number
 19983 000055FA E8560C0000          <1> 	call 	wslot
 19984                              <1> 		; jsr r0,wslot / set up I/O buffer for write, r5 points to 
 19985                              <1> 			     ; / first data word in buffer
 19986                              <1>         ; eAX (r1) = Physical block number
 19987 000055FF B908000000          <1> 	mov 	ecx, 8  ; R3, transfer old physical block pointers
 19988                              <1> 		   ; into new indirect block area for the new
 19989                              <1> 		   ; large file		
 19990 00005604 89DF                <1> 	mov 	edi, ebx ; r5
 19991 00005606 BE[5C710000]        <1> 	mov 	esi, i.dskp 
 19992                              <1> 		; mov $8.,r3 / next 6 instructions transfer old physical 
 19993                              <1> 			   ; / block pointers
 19994                              <1> 		; mov $i.dskp,r2 / into new indirect block for the new 
 19995                              <1> 			  ; / large file
 19996 0000560B 6631C0              <1> 	xor 	ax, ax ; mov ax, 0
 19997                              <1> mget_3: ;1:
 19998 0000560E 66A5                <1> 	movsw
 19999                              <1> 		; mov (r2),(r5)+
 20000 00005610 668946FE            <1> 	mov 	[esi-2], ax
 20001                              <1> 		; clr (r2)+
 20002 00005614 E2F8                <1> 	loop	mget_3 ; 1b
 20003                              <1> 		; dec r3
 20004                              <1> 		; bgt 1b
 20005                              <1> 
 20006 00005616 B1F8                <1> 	mov 	cl, 256-8
 20007                              <1> 		; mov $256.-8.,r3 / clear rest of data buffer
 20008                              <1> mget_4:	; 1
 20009 00005618 F366AB              <1> 	rep 	stosw
 20010                              <1> 		; clr (r5)+
 20011                              <1> 		; dec r3
 20012                              <1> 		; bgt 1b
 20013                              <1> 	; 24/03/2013
 20014                              <1>         ; AX (r1) = Physical block number
 20015 0000561B E8510C0000          <1> 	call	dskwr
 20016                              <1> 		; jsr r0,dskwr / write new indirect block on disk
 20017                              <1>         ; eAX (r1) = Physical block number
 20018 00005620 66A3[5C710000]      <1> 	mov 	[i.dskp], ax
 20019                              <1> 		; mov r1,i.dskp / put pointer to indirect block in i-node
 20020 00005626 66810D[56710000]00- <1> 	or 	word [i.flgs], 4096 ; 1000h
 20021 0000562E 10                  <1>
 20022                              <1> 		; bis $10000,i.flgs / set large file bit 
 20023                              <1> 				  ; / in i.flgs word of i-node
 20024 0000562F E807020000          <1> 	call	setimod
 20025                              <1> 		; jsr r0,setimod / set i-node modified flag
 20026 00005634 E97CFFFFFF          <1>         jmp     mget_0 
 20027                              <1> 		; br mget
 20028                              <1> 
 20029                              <1> mget_5:  ; 4 ; large file
 20030                              <1> 		; mov $-8,lsh / divide byte number by 256.
 20031                              <1> 		; bic $!776,r2 / zero all bits but 1,2,3,4,5,6,7,8; gives offset
 20032                              <1> 			    ; / in indirect block
 20033                              <1> 		; mov r2,-(sp) / save on stack (*)
 20034                              <1> 		; mov mq,r2 / calculate offset in i-node for pointer to proper
 20035                              <1>        		          ; / indirect block
 20036                              <1> 		; bic $!16,r2
 20037 00005639 80E3FE              <1>         and     bl, 0FEh ; bh = 0
 20038 0000563C 53                  <1>         push    ebx  ; i-node pointer offset in indirect block  (*) 
 20039                              <1>         ; 01/03/2013 Max. possible BX (offset) value is 127 (65535/512)
 20040                              <1> 	; 	     for this file system (offset 128 to 255 not in use)
 20041                              <1> 	; There is always 1 indirect block for this file system
 20042 0000563D 0FB705[5C710000]    <1> 	movzx 	eax, word [i.dskp] ; i.dskp[0]
 20043                              <1> 		; mov i.dskp(r2),r1
 20044 00005644 6609C0              <1> 	or 	ax, ax ; R1
 20045 00005647 7515                <1> 	jnz 	short mget_6 ; 2f
 20046                              <1> 		; bne 2f / if no indirect block exists
 20047 00005649 E840000000          <1> 	call 	alloc
 20048                              <1> 		; jsr r0,alloc / allocate a new block
 20049 0000564E 66A3[5C710000]      <1> 	mov 	[i.dskp], ax  ; 03/03/2013
 20050                              <1> 		; mov r1,i.dskp(r2) / put block number of new block in i-node
 20051 00005654 E8E2010000          <1> 	call 	setimod
 20052                              <1> 		; jsr r0,setimod / set i-node modified byte
 20053                              <1> 	; eAX = new block number
 20054 00005659 E847FEFFFF          <1> 	call 	clear
 20055                              <1> 		; jsr r0,clear / clear new block
 20056                              <1> mget_6: ;2
 20057                              <1> 	; 05/03/2013
 20058                              <1> 	; eAX = r1, physical block number (of indirect block)
 20059 0000565E E8920B0000          <1> 	call 	dskrd ; read indirect block
 20060                              <1> 		; jsr r0,dskrd / read in indirect block
 20061 00005663 5A                  <1> 	pop 	edx  ; R2, get offset (*)
 20062                              <1> 		; mov (sp)+,r2 / get offset
 20063                              <1> 	; eAX = r1, physical block number (of indirect block)
 20064 00005664 50                  <1> 	push 	eax ; ** ; 24/03/2013
 20065                              <1> 		; mov r1,-(sp) / save block number of indirect block on stack
 20066                              <1> 	; eBX (r5) = pointer to buffer (indirect block)
 20067 00005665 01D3                <1> 	add 	ebx, edx ; / r5 points to first word in indirect block, r2
 20068                              <1> 		; add r5,r2 / r5 points to first word in indirect block, r2
 20069                              <1> 	                  ; / points to location of inter
 20070 00005667 0FB703              <1> 	movzx 	eax, word [ebx] ; put physical block no of block
 20071                              <1> 			      ; in file sought in R1 (AX)
 20072                              <1> 		; mov (r2),r1 / put physical block no of block in file
 20073                              <1> 	               	    ; / sought in r1
 20074 0000566A 6609C0              <1> 	or 	ax, ax
 20075 0000566D 751D                <1>         jnz 	short mget_7 ; 2f
 20076                              <1> 		; bne 2f / if no block exists 
 20077 0000566F E81A000000          <1> 	call 	alloc
 20078                              <1> 		; jsr r0,alloc / allocate a new block
 20079 00005674 668903              <1> 	mov 	[ebx], ax ; R1
 20080                              <1> 		; mov r1,(r2) / put new block number into proper location in
 20081                              <1> 	                    ; / indirect block
 20082 00005677 5A                  <1> 	pop	edx ; ** ; 24/03/2013
 20083                              <1> 		; mov (sp)+,r1 / get block number of indirect block
 20084 00005678 52                  <1> 	push 	edx ; ** ; 31/07/2013
 20085 00005679 50                  <1> 	push	eax ; * ; 24/03/2013, 31/07/2013 (new block number)
 20086 0000567A 89D0                <1> 	mov	eax, edx ; 24/03/2013
 20087                              <1> 		; mov (r2),-(sp) / save block number of new block
 20088                              <1> 	; eAX (r1) = physical block number (of indirect block)
 20089 0000567C E8D40B0000          <1> 	call 	wslot
 20090                              <1> 		; jsr r0,wslot
 20091                              <1>         ; eAX (r1) = physical block number
 20092                              <1> 	; eBX (r5) = pointer to buffer (indirect block)
 20093 00005681 E8EB0B0000          <1> 	call 	dskwr
 20094                              <1> 	; eAX = r1 = physical block number (of indirect block)
 20095                              <1> 		; jsr r0,dskwr / write newly modified indirect block 
 20096                              <1> 			     ; / back out on disk
 20097 00005686 58                  <1> 	pop	eax ; *  ; 31/07/2013
 20098                              <1> 		; mov (sp),r1 / restore block number of new block	
 20099                              <1> 	; eAX (r1) = physical block number of new block
 20100 00005687 E819FEFFFF          <1> 	call 	clear
 20101                              <1> 		; jsr r0,clear / clear new block	
 20102                              <1> mget_7: ; 2
 20103 0000568C 5A                  <1> 	pop 	edx ; **
 20104                              <1> 		; tst (sp)+ / bump stack pointer
 20105                              <1> 	; eAX (r1) = Block number of new block
 20106 0000568D C3                  <1> 	retn
 20107                              <1> 		; rts r0
 20108                              <1> 
 20109                              <1> alloc:
 20110                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20111                              <1> 	; 01/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20112                              <1> 	;
 20113                              <1> 	; get a free block and 
 20114                              <1> 	; set the corresponding bit in the free storage map
 20115                              <1> 	; 
 20116                              <1> 	; INPUTS ->
 20117                              <1> 	;    cdev (current device)
 20118                              <1> 	;    r2 
 20119                              <1> 	;    r3
 20120                              <1> 	; OUTPUTS ->
 20121                              <1> 	;    r1 (physical block number of block assigned)
 20122                              <1> 	;    smod, mmod, systm (super block), mount (mountable super block)	
 20123                              <1> 	;
 20124                              <1> 	; ((AX = R1)) output
 20125                              <1> 	;    (Retro UNIX Prototype : 14/11/2012 - 21/07/2012, UNIXCOPY.ASM)
 20126                              <1>         ;    ((Modified registers: DX, CX))  
 20127                              <1> 
 20128                              <1> 		;mov r2,-(sp) / save r2, r3 on stack
 20129                              <1> 		;mov r3,-(sp)
 20130                              <1> 	;push 	ecx
 20131 0000568E 53                  <1> 	push 	ebx ; R2
 20132                              <1> 	;push 	edx ; R3
 20133 0000568F BB[307D0000]        <1> 	mov 	ebx, systm ; SuperBlock 
 20134                              <1> 		; mov $systm,r2 / start of inode and free storage map for drum
 20135 00005694 803D[66740000]00    <1> 	cmp 	byte [cdev], 0
 20136                              <1> 		; tst cdev
 20137 0000569B 7605                <1> 	jna	short alloc_1
 20138                              <1> 		; beq 1f / drum is device
 20139 0000569D BB[387F0000]        <1> 	mov	ebx, mount
 20140                              <1> 		; mov $mount,r2 / disk or tape is device, start of inode and
 20141                              <1> 			      ; / free storage map
 20142                              <1> alloc_1: ; 1
 20143 000056A2 668B0B              <1>         mov	cx, [ebx]
 20144                              <1> 		; mov (r2)+,r1 / first word contains number of bytes in free
 20145                              <1> 			     ; / storage map
 20146 000056A5 66C1E103            <1> 	shl	cx, 3
 20147                              <1> 		; asl r1 / multiply r1 by eight gives 
 20148                              <1> 		; number of blocks in device
 20149                              <1> 		; asl r1
 20150                              <1> 		; asl r1
 20151                              <1> 	;; push cx ;; 01/08/2013
 20152                              <1> 		; mov r1,-(sp) / save # of blocks in device on stack
 20153 000056A9 31C0                <1> 	xor 	eax, eax ; 0
 20154                              <1> 		; clr r1 / r1 contains bit count of free storage map
 20155                              <1> alloc_2: ; 1
 20156 000056AB 43                  <1> 	inc 	ebx ; 18/8/2012
 20157 000056AC 43                  <1> 	inc 	ebx ; 
 20158 000056AD 668B13              <1> 	mov 	dx, [ebx]
 20159                              <1> 		; mov (r2)+,r3 / word of free storage map in r3 
 20160 000056B0 6609D2              <1> 	or 	dx, dx
 20161 000056B3 750E                <1> 	jnz 	short alloc_3 ; 1f
 20162                              <1> 		; bne 1f / branch if any free blocks in this word	
 20163 000056B5 6683C010            <1> 	add 	ax, 16
 20164                              <1> 		; add $16.,r1
 20165 000056B9 6639C8              <1> 	cmp 	ax, cx    
 20166                              <1> 		; cmp r1 ,(sp) / have we examined all free storage bytes
 20167 000056BC 72ED                <1> 	jb 	short alloc_2
 20168                              <1> 		; blo 1b
 20169                              <1> 	; 14/11/2015
 20170                              <1> 	; Note: If the super block buffer has wrong content (zero bytes)
 20171                              <1> 	;	because of a (DMA or another) r/w error, 
 20172                              <1> 	;	we will be here, at 'jmp panic' code address,
 20173                              <1> 	;	even if the (disk) file system space is not full !!!
 20174                              <1> 	;	(cx = 0)	
 20175                              <1> 	;
 20176 000056BE E94FE2FFFF          <1> 	jmp     panic 
 20177                              <1> 		; jmp panic / found no free storage
 20178                              <1> alloc_3: ; 1
 20179 000056C3 66D1EA              <1> 	shr	dx, 1
 20180                              <1> 		; asr r3 / find a free block
 20181 000056C6 7204                <1> 	jc	short alloc_4 ; 1f
 20182                              <1> 		; bcs 1f / branch when free block found; bit for block k
 20183                              <1> 		       ; / is in byte k/8 / in bit k (mod 8)
 20184 000056C8 6640                <1> 	inc	ax
 20185                              <1> 		; inc r1 / increment bit count in bit k (mod8)
 20186 000056CA EBF7                <1> 	jmp 	short alloc_3
 20187                              <1> 		; br 1b
 20188                              <1> alloc_4: ; 1:
 20189                              <1> 	;; pop cx ;; 01/08/2013
 20190                              <1> 		; tst (sp)+ / bump sp
 20191                              <1> 	; 02/04/2013 
 20192 000056CC E829000000          <1> 	call	free3
 20193                              <1> 		; jsr r0,3f / have found a free block
 20194                              <1> 	; 21/8/2012
 20195 000056D1 66F7D2              <1> 	not 	dx ; masking bit is '0' and others are '1'
 20196 000056D4 662113              <1> 	and	[ebx], dx   ;; 0 -> allocated 
 20197                              <1> 		; bic r3,(r2) / set bit for this block 
 20198                              <1> 		            ; / i.e. assign block
 20199                              <1> 		; br 2f
 20200 000056D7 EB09                <1> 	jmp 	short alloc_5
 20201                              <1> 
 20202                              <1> free:
 20203                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20204                              <1> 	; 07/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20205                              <1> 	;
 20206                              <1> 	; calculates byte address and bit position for given block number
 20207                              <1> 	; then sets the corresponding bit in the free storage map
 20208                              <1> 	; 
 20209                              <1> 	; INPUTS ->
 20210                              <1> 	;    r1 - block number for a block structured device
 20211                              <1> 	;    cdev - current device 
 20212                              <1> 	; OUTPUTS ->
 20213                              <1> 	;    free storage map is updated
 20214                              <1> 	;    smod is incremented if cdev is root device (fixed disk)
 20215                              <1> 	;    mmod is incremented if cdev is a removable disk 	
 20216                              <1> 	;
 20217                              <1> 	;  (Retro UNIX Prototype : 01/12/2012, UNIXCOPY.ASM)
 20218                              <1>         ;  ((Modified registers: DX, CX))  
 20219                              <1> 
 20220                              <1> 		;mov r2,-(sp) / save r2, r3
 20221                              <1> 		;mov r3,-(sp)
 20222                              <1> 	;push 	ecx
 20223 000056D9 53                  <1> 	push 	ebx ; R2
 20224                              <1> 	;push 	edx ; R3 
 20225                              <1> 
 20226 000056DA E81B000000          <1>         call    free3
 20227                              <1> 	     	; jsr r0,3f  / set up bit mask and word no. 
 20228                              <1> 				 ; / in free storage map for block
 20229 000056DF 660913              <1> 	or 	[ebx], dx  
 20230                              <1> 	  	; bis r3, (r2) / set free storage block bit;
 20231                              <1> 			    ;  / indicates free block	
 20232                              <1> 	; 0 -> allocated, 1 -> free
 20233                              <1> 
 20234                              <1> alloc_5:
 20235                              <1> 	; 07/04/2013
 20236                              <1> free_1: ; 2:
 20237                              <1> 	; pop 	edx
 20238                              <1> 		; mov (sp)+,r3 / restore r2, r3
 20239 000056E2 5B                  <1> 	pop	ebx
 20240                              <1> 		; mov (sp)+,r2
 20241                              <1> 	; pop	ecx
 20242 000056E3 803D[66740000]00    <1> 	cmp 	byte [cdev], 0
 20243                              <1> 		; tst cdev / cdev = 0, block structured, drum; 
 20244                              <1> 			 ; / cdev = 1, mountable device
 20245 000056EA 7707                <1> 	ja	short alloc_6 ; 1f
 20246                              <1> 		; bne 1f
 20247                              <1> 	;mov	byte [smod], 1
 20248 000056EC FE05[75740000]      <1> 	inc 	byte [smod]
 20249                              <1> 		; incb smod / set super block modified for drum
 20250                              <1> 	; eAX (r1) = block number
 20251 000056F2 C3                  <1> 	retn
 20252                              <1> 		; rts r0
 20253                              <1> free_2:
 20254                              <1> alloc_6: ; 1:
 20255                              <1> 	;mov 	byte [mmod], 1
 20256 000056F3 FE05[76740000]      <1> 	inc 	byte [mmod]
 20257                              <1> 		; incb	mmod 
 20258                              <1> 		  ; / set super block modified for mountable device
 20259                              <1> 	; eAX (r1) = block number
 20260 000056F9 C3                  <1> 	retn	
 20261                              <1> 		; rts r0
 20262                              <1> free3:
 20263                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20264                              <1> 	; 02/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20265                              <1> 	;
 20266                              <1> 	; free3 is called from 'alloc' and 'free' procedures
 20267                              <1> 	; 
 20268                              <1> alloc_free_3: ; 3
 20269 000056FA 66BA0100            <1> 	mov 	dx, 1
 20270 000056FE 88C1                <1> 	mov 	cl, al
 20271                              <1> 		; mov r1,r2 / block number, k, = 1		
 20272 00005700 80E10F              <1> 	and 	cl, 0Fh  ; 0Fh <-- (k) mod 16
 20273                              <1> 		; bic $!7,r2 / clear all bits but 0,1,2; r2 = (k) mod (8)
 20274 00005703 7403                <1> 	jz 	short free4
 20275                              <1> 		; bisb 2f(r2),r3 / use mask to set bit in r3 corresponding to
 20276                              <1> 			       ; / (k) mod 8
 20277 00005705 66D3E2              <1> 	shl 	dx, cl
 20278                              <1> free4:
 20279 00005708 0FB7D8              <1> 	movzx 	ebx, ax
 20280                              <1> 		; mov r1,r2 / divide block number by 16
 20281 0000570B 66C1EB04            <1> 	shr 	bx, 4
 20282                              <1> 		; asr r2
 20283                              <1> 		; asr r2
 20284                              <1> 		; asr r2
 20285                              <1> 		; asr r2
 20286                              <1> 		; bcc 1f / branch if bit 3 in r1 was 0 i.e., 
 20287                              <1> 		       ; / bit for block is in lower half of word
 20288                              <1> 		; swab r3 / swap bytes in r3; bit in upper half of word in free
 20289                              <1> 		        ; / storage map
 20290                              <1> alloc_free_4: ; 1
 20291 0000570F 66D1E3              <1> 	shl 	bx, 1
 20292                              <1> 		; asl r2 / multiply block number by 2; r2 = k/8
 20293 00005712 81C3[327D0000]      <1> 	add 	ebx, systm+2 ; SuperBlock+2
 20294                              <1> 		; add $systm+2,r2 / address of word of free storage map for drum
 20295                              <1> 	    		        ; / with block bit in it 	
 20296 00005718 803D[66740000]00    <1> 	cmp	byte [cdev], 0
 20297                              <1> 		; tst cdev
 20298 0000571F 7606                <1> 	jna	short alloc_free_5
 20299                              <1> 		; beq 1f / cdev = 0 indicates device is drum
 20300 00005721 81C308020000        <1> 	add	ebx, mount - systm
 20301                              <1> 		; add $mount-systm,r2 / address of word of free storage map for
 20302                              <1> 				    ; / mountable device with bit of block to be
 20303                              <1> 				    ; / freed
 20304                              <1> alloc_free_5: ; 1 
 20305 00005727 C3                  <1> 	retn
 20306                              <1> 		; rts r0 / return to 'free'
 20307                              <1> 	      ; 2
 20308                              <1> 	        ; .byte	1,2,4,10,20,40,100,200 / masks for bits 0,...,7
 20309                              <1> 	
 20310                              <1> iget:
 20311                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20312                              <1> 	; 07/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 20313                              <1> 	;
 20314                              <1> 	; get a new i-node whose i-number in r1 and whose device is in cdev
 20315                              <1> 	;
 20316                              <1> 	; ('iget' returns current i-number in r1, if input value of r1 is 0)
 20317                              <1> 	; 
 20318                              <1> 	; INPUTS ->
 20319                              <1> 	;    ii - current i-number, rootdir
 20320                              <1> 	;    cdev - new i-node device
 20321                              <1> 	;    idev - current i-node device
 20322                              <1> 	;    imod - current i-node modified flag
 20323                              <1> 	;    mnti - cross device file i-number
 20324                              <1> 	;    r1 - i-numbe rof new i-node
 20325                              <1> 	;    mntd - mountable device number		
 20326                              <1> 	; 	 
 20327                              <1> 	; OUTPUTS ->
 20328                              <1> 	;    cdev, idev, imod, ii, r1
 20329                              <1> 	;
 20330                              <1> 	; ((AX = R1)) input/output
 20331                              <1> 	;
 20332                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 20333                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 20334                              <1> 
 20335 00005728 8A15[66740000]      <1> 	mov	dl, [cdev] ; 18/07/2013
 20336 0000572E 8A35[64740000]      <1> 	mov	dh, [idev] ; 07/08/2013
 20337                              <1> 	;
 20338 00005734 663B05[62740000]    <1> 	cmp 	ax, [ii]
 20339                              <1> 		; cmp r1,ii / r1 = i-number of current file
 20340 0000573B 7504                <1> 	jne 	short iget_1
 20341                              <1> 		; bne 1f
 20342 0000573D 38F2                <1> 	cmp	dl, dh
 20343                              <1> 		; cmp idev,cdev
 20344                              <1> 			  ; / is device number of i-node = current device
 20345 0000573F 7476                <1>         je      short iget_5
 20346                              <1> 		; beq 2f
 20347                              <1> iget_1: ; 1:
 20348 00005741 30DB                <1> 	xor	bl, bl
 20349 00005743 381D[74740000]      <1> 	cmp	[imod], bl ; 0	
 20350                              <1> 		; tstb imod / has i-node of current file
 20351                              <1> 			  ; / been modified i.e., imod set
 20352 00005749 762D                <1> 	jna	short iget_2
 20353                              <1> 		; beq 1f
 20354 0000574B 881D[74740000]      <1> 	mov	[imod], bl ; 0
 20355                              <1> 		;  clrb	imod / if it has, 
 20356                              <1> 			   ; / we must write the new i-node out on disk
 20357 00005751 6650                <1> 	push	ax
 20358                              <1> 		; mov r1,-(sp)
 20359                              <1> 	;mov	dl, [cdev]
 20360 00005753 6652                <1> 	push	dx
 20361                              <1> 		; mov cdev,-(sp)
 20362 00005755 66A1[62740000]      <1> 	mov	ax, [ii]
 20363                              <1> 		; mov ii,r1
 20364                              <1> 	;mov	dh, [idev]
 20365 0000575B 8835[66740000]      <1> 	mov	[cdev], dh
 20366                              <1> 		; mov idev,cdev
 20367 00005761 FEC3                <1> 	inc	bl ; 1
 20368                              <1> 	; 31/07/2013
 20369 00005763 881D[04750000]      <1> 	mov     [rw], bl ; 1 == write 
 20370                              <1> 	;;28/07/2013 rw -> u.rw
 20371                              <1>         ;;mov   [u.rw], bl ; 1 == write
 20372 00005769 E84A000000          <1> 	call	icalc
 20373                              <1> 		; jsr r0,icalc; 1
 20374 0000576E 665A                <1> 	pop	dx
 20375 00005770 8815[66740000]      <1> 	mov	[cdev], dl
 20376                              <1> 		; mov (sp)+,cdev
 20377 00005776 6658                <1> 	pop	ax
 20378                              <1> 		; mov (sp)+,r1
 20379                              <1> iget_2: ; 1:
 20380 00005778 6621C0              <1> 	and	ax, ax
 20381                              <1> 		; tst r1 / is new i-number non zero
 20382 0000577B 7434                <1> 	jz	short iget_4 ; 2f
 20383                              <1> 		; beq 2f / branch if r1=0
 20384                              <1> 
 20385                              <1> 	; mov 	dl, [cdev]
 20386 0000577D 08D2                <1> 	or	dl, dl
 20387                              <1> 		; tst cdev / is the current device number non zero
 20388                              <1> 			 ; / (i.e., device =/ drum)
 20389 0000577F 7517                <1> 	jnz	short iget_3 ;  1f
 20390                              <1> 		; bne 1f / branch 1f cdev =/ 0  ;; (cdev != 0)
 20391 00005781 663B05[6C740000]    <1> 	cmp	ax, [mnti]			
 20392                              <1> 		; cmp r1,mnti / mnti is the i-number of the cross device
 20393                              <1> 			    ; / file (root directory of mounted device)
 20394 00005788 750E                <1> 	jne	short iget_3 ; 1f
 20395                              <1> 		; bne 1f
 20396                              <1>         ;mov    bl, [mntd]
 20397 0000578A FEC2                <1> 	inc	dl ; mov dl, 1 ; 17/07/2013
 20398 0000578C 8815[66740000]      <1>         mov	[cdev], dl ; 17/07/2013 - 09/07/2013
 20399                              <1> 		; mov mntd,cdev / make mounted device the current device
 20400 00005792 66A1[70740000]      <1> 	mov	ax, [rootdir]
 20401                              <1> 		; mov rootdir,r1
 20402                              <1> iget_3: ; 1:
 20403 00005798 66A3[62740000]      <1> 	mov	[ii], ax
 20404                              <1> 		; mov r1,ii
 20405 0000579E 8815[64740000]      <1> 	mov	[idev], dl ; cdev
 20406                              <1> 		; mov cdev,idev
 20407 000057A4 30DB                <1> 	xor	bl, bl
 20408                              <1>         ; 31/07/2013
 20409 000057A6 881D[04750000]      <1> 	mov     [rw], bl ; 0 == read 
 20410                              <1> 	;;28/07/2013 rw -> u.rw       
 20411                              <1>         ;;mov   [u.rw], bl ; 0 = read
 20412 000057AC E807000000          <1> 	call	icalc
 20413                              <1> 		; jsr r0,icalc; 0 / read in i-node ii
 20414                              <1> iget_4: ; 2:
 20415 000057B1 66A1[62740000]      <1> 	mov	ax, [ii]
 20416                              <1> 		; mov ii,r1
 20417                              <1> iget_5:
 20418 000057B7 C3                  <1> 	retn
 20419                              <1> 		; rts r0
 20420                              <1> 
 20421                              <1> icalc:
 20422                              <1> 	; 02/07/2015
 20423                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20424                              <1> 	; 07/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 20425                              <1> 	;
 20426                              <1> 	; calculate physical block number from i-number then
 20427                              <1> 	; read or write that block
 20428                              <1> 	;
 20429                              <1> 	; 'icalc' is called from 'iget'
 20430                              <1> 	;
 20431                              <1> 	; for original unix v1:
 20432                              <1> 	; / i-node i is located in block (i+31.)/16. and begins 32.*
 20433                              <1>        	; / (i+31.) mod 16. bytes from its start
 20434                              <1> 	;
 20435                              <1> 	; for retro unix 8086 v1:
 20436                              <1> 	;  i-node is located in block (i+47)/16 and
 20437                              <1> 	;  begins 32*(i+47) mod 16 bytes from its start
 20438                              <1> 	;
 20439                              <1> 	; INPUTS ->
 20440                              <1> 	;    r1 - i-number of i-node
 20441                              <1> 	; 	 
 20442                              <1> 	; OUTPUTS ->
 20443                              <1> 	;    inode r/w
 20444                              <1> 	;
 20445                              <1> 	; ((AX = R1)) input
 20446                              <1> 	;
 20447                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 20448                              <1>         ;  ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))  
 20449                              <1> 	;
 20450 000057B8 0FB7D0              <1> 	movzx	edx, ax	
 20451 000057BB 6683C22F            <1> 	add	dx, 47
 20452 000057BF 89D0                <1> 	mov	eax, edx
 20453                              <1> 	;add	ax, 47	; add 47 to inode number
 20454                              <1> 		;  add	$31.,r1 / add 31. to i-number
 20455 000057C1 50                  <1> 	push	eax
 20456                              <1> 		; mov r1,-(sp) / save i+31. on stack
 20457 000057C2 66C1E804            <1> 	shr 	ax, 4
 20458                              <1> 		; asr r1 / divide by 16.
 20459                              <1> 		; asr r1
 20460                              <1> 		; asr r1
 20461                              <1> 		; asr r1 / r1 contains block number of block
 20462                              <1> 		       ; / in which i-node exists
 20463 000057C6 E82A0A0000          <1> 	call	dskrd
 20464                              <1> 		; jsr r0,dskrd / read in block containing i-node i.
 20465                              <1> 	; 31/07/2013
 20466 000057CB 803D[04750000]00    <1>         cmp     byte [rw], 0 ; Retro Unix 8086 v1 feature !
 20467                              <1> 	;; 28/07/2013 rw -> u.rw
 20468                              <1>         ;;cmp     byte [u.rw], 0 ; Retro Unix 8086 v1 feature !
 20469                              <1> 		; tst (r0)
 20470 000057D2 7605                <1> 	jna	short icalc_1
 20471                              <1> 		; beq 1f / branch to wslot when argument
 20472                              <1> 		       ; / in icalc call = 1
 20473                              <1> 	; eAX = r1  = block number
 20474 000057D4 E87C0A0000          <1> 	call	wslot
 20475                              <1> 		; jsr r0,wslot / set up data buffer for write
 20476                              <1> 			     ; / (will be same buffer as dskrd got)
 20477                              <1> 	; eBX = r5 points to first word in data area for this block
 20478                              <1> icalc_1: ; 1:
 20479 000057D9 5A                  <1> 	pop	edx 
 20480 000057DA 83E20F              <1> 	and 	edx, 0Fh ; (i+47) mod 16
 20481                              <1> 		; bic $!17,(sp) / zero all but last 4 bits; 
 20482                              <1> 			      ; / gives (i+31.) mod 16
 20483 000057DD C1E205              <1> 	shl 	edx, 5
 20484                              <1> 	; eDX = 32 * ((i+47) mod 16)
 20485 000057E0 89DE                <1> 	mov	esi, ebx  ; ebx points 1st word of the buffer
 20486 000057E2 01D6                <1> 	add	esi, edx  ; edx is inode offset in the buffer
 20487                              <1>           	; eSI (r5) points to first word in i-node i.	
 20488                              <1> 		; mov (sp)+,mq / calculate offset in data buffer; 
 20489                              <1> 			     ; / 32.*(i+31.)mod16
 20490                              <1> 		; mov $5,lsh / for i-node i.
 20491                              <1> 		; add mq,r5 / r5 points to first word in i-node i.
 20492 000057E4 BF[56710000]        <1> 	mov	edi, inode
 20493                              <1> 		; mov $inode,r1 / inode is address of first word 
 20494                              <1> 			      ; / of current i-node
 20495 000057E9 B908000000          <1> 	mov 	ecx, 8 ; 02/07/2015(32 bit modification)
 20496                              <1> 		; mov $16.,r3
 20497                              <1>        ; 31/07/2013
 20498 000057EE 382D[04750000]      <1>   	cmp     [rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 20499                              <1>        ;;28/07/2013 rw -> u.rw                 
 20500                              <1>        ;;cmp    [u.rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 20501                              <1> 		; tst (r0)+ / branch to 2f when argument in icalc call = 0
 20502 000057F4 760A                <1> 	jna	short icalc_3
 20503                              <1> 		; beq 2f / r0 now contains proper return address 
 20504                              <1> 		       ; / for rts r0
 20505                              <1> icalc_2: ; 1:
 20506 000057F6 87F7                <1> 	xchg 	esi, edi
 20507                              <1> 	; overwrite old i-node (in buffer to be written)
 20508 000057F8 F3A5                <1> 	rep 	movsd
 20509                              <1> 		; mov (r1)+,(r5)+ / over write old i-node
 20510                              <1> 		; dec r3
 20511                              <1> 		; bgt 1b
 20512 000057FA E8720A0000          <1> 	call	dskwr
 20513                              <1> 		; jsr r0,dskwr / write inode out on device
 20514 000057FF C3                  <1> 	retn
 20515                              <1> 		; rts r0
 20516                              <1> icalc_3: ; 2:
 20517                              <1> 	; copy new i-node into inode area of (core) memory
 20518 00005800 F3A5                <1> 	rep 	movsd
 20519                              <1> 		; mov (r5)+,(r1)+ / read new i-node into 
 20520                              <1> 		                ; / "inode" area of core
 20521                              <1> 		; dec r3
 20522                              <1> 		; bgt 2b
 20523 00005802 C3                  <1> 	retn
 20524                              <1> 		; rts r0
 20525                              <1> 
 20526                              <1> access:
 20527                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20528                              <1> 	; 24/04/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 20529                              <1> 	;
 20530                              <1> 	; check whether user is owner of file or user has read or write
 20531                              <1> 	; permission (based on i.flgs).
 20532                              <1> 	;
 20533                              <1> 	; INPUTS ->
 20534                              <1> 	;    r1 - i-number of file
 20535                              <1> 	;    u.uid
 20536                              <1> 	; arg0 -> (owner flag mask)	 		
 20537                              <1> 	;     Retro UNIX 8086 v1 feature -> owner flag mask in DL (DX) 	 
 20538                              <1> 	; OUTPUTS ->
 20539                              <1> 	;    inode (or jump to error)
 20540                              <1> 	;
 20541                              <1> 	; ((AX = R1)) input/output
 20542                              <1> 	;
 20543                              <1>         ;  ((Modified registers: eCX, eBX, eDX, eSI, eDI, eBP))  
 20544                              <1> 	;
 20545 00005803 6652                <1> 	push	dx  ; save flags (DL)
 20546 00005805 E81EFFFFFF          <1> 	call	iget
 20547                              <1> 		; jsr r0,iget / read in i-node for current directory
 20548                              <1> 			    ; / (i-number passed in r1)
 20549 0000580A 8A0D[56710000]      <1> 	mov	cl, [i.flgs]
 20550                              <1> 		; mov i.flgs,r2
 20551 00005810 665A                <1> 	pop	dx  ; restore flags (DL)
 20552 00005812 8A35[CC740000]      <1> 	mov	dh, [u.uid]
 20553 00005818 3A35[59710000]      <1> 	cmp	dh, [i.uid]
 20554                              <1> 		; cmpb i.uid,u.uid / is user same as owner of file
 20555 0000581E 7503                <1> 	jne	short access_1
 20556                              <1> 		; bne 1f / no, then branch
 20557 00005820 C0E902              <1> 	shr	cl, 2
 20558                              <1> 		; asrb r2 / shift owner read write bits into non owner
 20559                              <1> 		        ; / read/write bits
 20560                              <1> 		; asrb r2
 20561                              <1> access_1: ; 1:
 20562 00005823 20D1                <1> 	and	cl, dl
 20563                              <1> 		; bit r2,(r0)+ / test read-write flags against argument
 20564                              <1> 			     ; / in access call
 20565 00005825 7513                <1> 	jnz	short access_2
 20566                              <1> 		; bne 1f
 20567 00005827 08F6                <1> 	or	dh, dh	; super user  (root) ?
 20568                              <1> 		; tstb u.uid
 20569 00005829 740F                <1> 	jz	short access_2 ; yes, super user
 20570                              <1> 	;jnz	error
 20571                              <1> 		; beq 1f
 20572                              <1> 		; jmp error
 20573 0000582B C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS 
 20574 00005833 0000                <1>
 20575                              <1> 			; 'permission denied !' error
 20576 00005835 E942E8FFFF          <1> 	jmp	error
 20577                              <1> 
 20578                              <1> access_2: ; 1:
 20579                              <1> 	; DL = flags
 20580 0000583A C3                  <1> 	retn
 20581                              <1> 		; rts r0
 20582                              <1> 
 20583                              <1> setimod:
 20584                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20585                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 20586                              <1> 	;
 20587                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
 20588                              <1> 	; the inode has been modified. Also puts the time of modification
 20589                              <1> 	; into the inode.
 20590                              <1> 	;
 20591                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
 20592                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
 20593                              <1> 	;
 20594                              <1> 	
 20595                              <1> 	; push 	edx
 20596 0000583B 50                  <1> 	push	eax
 20597                              <1> 
 20598 0000583C C605[74740000]01    <1> 	mov 	byte [imod], 1
 20599                              <1> 		; movb $1,imod / set current i-node modified bytes
 20600                              <1> 	; Erdogan Tan 14-7-2012
 20601 00005843 E86FE3FFFF          <1> 	call 	epoch
 20602                              <1> 		 ; mov s.time,i.mtim 
 20603                              <1> 			    ; / put present time into file modified time
 20604                              <1> 		 ; mov s.time+2,i.mtim+2
 20605                              <1> 
 20606 00005848 A3[70710000]        <1> 	mov 	[i.mtim], eax
 20607                              <1> 	
 20608                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
 20609                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
 20610 0000584D 833D[6C710000]00    <1> 	cmp	dword [i.ctim], 0
 20611 00005854 7505                <1> 	jnz	short setimod_ok
 20612                              <1> 
 20613 00005856 A3[6C710000]        <1> 	mov 	[i.ctim], eax
 20614                              <1> 
 20615                              <1> setimod_ok: ; 31/07/2013
 20616 0000585B 58                  <1> 	pop	eax
 20617                              <1> 	;pop	edx
 20618                              <1> 	
 20619 0000585C C3                  <1> 	retn
 20620                              <1> 		; rts r0
 20621                              <1> 
 20622                              <1> itrunc:
 20623                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20624                              <1> 	; 23/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20625                              <1> 	;
 20626                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
 20627                              <1> 	;  to zero length.
 20628                              <1> 	;
 20629                              <1> 	; INPUTS ->
 20630                              <1> 	;    r1 - i-number of i-node
 20631                              <1> 	;    i.dskp - pointer to contents or indirect block in an i-node
 20632                              <1> 	;    i.flgs - large file flag		
 20633                              <1> 	;    i.size - size of file	
 20634                              <1> 	; 	 
 20635                              <1> 	; OUTPUTS ->
 20636                              <1> 	;    i.flgs - large file flag is cleared
 20637                              <1> 	;    i.size - set to 0	
 20638                              <1> 	;    i.dskp .. i.dskp+16 - entire list is cleared
 20639                              <1> 	;    setimod - set to indicate i-node has been modified
 20640                              <1> 	;    r1 - i-number of i-node  					
 20641                              <1> 	;
 20642                              <1> 	; ((AX = R1)) input/output
 20643                              <1> 	;
 20644                              <1> 	;  (Retro UNIX Prototype : 01/12/2012 - 10/03/2013, UNIXCOPY.ASM)
 20645                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 20646                              <1> 
 20647 0000585D E8C6FEFFFF          <1> 	call	iget
 20648                              <1> 		; jsr r0,iget
 20649 00005862 BE[5C710000]        <1> 	mov	esi, i.dskp
 20650                              <1> 		; mov $i.dskp,r2 / address of block pointers in r2
 20651 00005867 31C0                <1> 	xor	eax, eax
 20652                              <1> itrunc_1: ; 1:
 20653 00005869 66AD                <1> 	lodsw
 20654                              <1> 		; mov (r2)+,r1 / move physical block number into r1
 20655 0000586B 6609C0              <1> 	or 	ax, ax
 20656 0000586E 743B                <1> 	jz	short itrunc_5
 20657                              <1> 		; beq 5f
 20658 00005870 56                  <1> 	push	esi
 20659                              <1> 		; mov r2,-(sp)
 20660 00005871 66F705[56710000]00- <1> 	test    word [i.flgs], 1000h    
 20661 00005879 10                  <1>
 20662                              <1> 		; bit $10000,i.flgs / test large file bit?
 20663 0000587A 7429                <1> 	jz	short itrunc_4
 20664                              <1> 		; beq 4f / if clear, branch
 20665 0000587C 50                  <1> 	push	eax
 20666                              <1> 		; mov r1,-(sp) / save block number of indirect block
 20667 0000587D E873090000          <1> 	call	dskrd
 20668                              <1> 		; jsr r0,dskrd / read in block, 1st data word 
 20669                              <1> 			     ; / pointed to by r5
 20670                              <1> 	; eBX = r5 = Buffer data address (the 1st word)
 20671 00005882 B900010000          <1> 	mov	ecx, 256
 20672                              <1> 		; mov $256.,r3 / move word count into r3
 20673 00005887 89DE                <1> 	mov	esi, ebx
 20674                              <1> itrunc_2: ; 2:
 20675 00005889 66AD                <1> 	lodsw
 20676                              <1> 		; mov (r5)+,r1 / put 1st data word in r1; 
 20677                              <1> 			     ; / physical block number
 20678 0000588B 6621C0              <1> 	and	ax, ax
 20679 0000588E 7409                <1> 	jz	short itrunc_3
 20680                              <1> 		; beq 3f / branch if zero
 20681                              <1> 	;push	ecx
 20682 00005890 6651                <1> 	push	cx
 20683                              <1> 		; mov r3,-(sp) / save r3, r5 on stack
 20684                              <1> 	;push	esi
 20685                              <1> 		; mov r5,-(sp)
 20686 00005892 E842FEFFFF          <1> 	call	free
 20687                              <1> 		; jsr r0,free / free block in free storage map
 20688                              <1> 	;pop	esi
 20689                              <1> 		; mov(sp)+,r5
 20690 00005897 6659                <1> 	pop	cx
 20691                              <1> 	;pop	ecx
 20692                              <1> 		; mov (sp)+,r3
 20693                              <1> itrunc_3: ; 3:
 20694 00005899 E2EE                <1> 	loop	itrunc_2
 20695                              <1> 		; dec r3 / decrement word count
 20696                              <1> 		; bgt 2b / branch if positive
 20697 0000589B 58                  <1> 	pop	eax
 20698                              <1> 		; mov (sp)+,r1 / put physical block number of 
 20699                              <1> 			     ; / indirect block
 20700                              <1> 	; 01/08/2013
 20701 0000589C 668125[56710000]FF- <1>         and     word [i.flgs], 0EFFFh ; 1110111111111111b
 20702 000058A4 EF                  <1>
 20703                              <1> itrunc_4: ; 4:
 20704 000058A5 E82FFEFFFF          <1> 	call	free
 20705                              <1> 		; jsr r0,free / free indirect block
 20706 000058AA 5E                  <1> 	pop	esi
 20707                              <1> 		; mov (sp)+,r2
 20708                              <1> itrunc_5: ; 5:
 20709 000058AB 81FE[6C710000]      <1> 	cmp	esi, i.dskp+16
 20710                              <1> 		; cmp r2,$i.dskp+16.
 20711 000058B1 72B6                <1> 	jb	short itrunc_1	
 20712                              <1> 		; bne 1b / branch until all i.dskp entries check
 20713                              <1> 	; 01/08/2013
 20714                              <1> 	;and     word [i.flgs], 0EFFFh ; 1110111111111111b
 20715                              <1> 		; bic $10000,i.flgs / clear large file bit
 20716 000058B3 BF[5C710000]        <1> 	mov	edi, i.dskp
 20717 000058B8 66B90800            <1> 	mov	cx, 8
 20718 000058BC 6631C0              <1> 	xor 	ax, ax
 20719 000058BF 66A3[5A710000]      <1> 	mov	[i.size], ax ; 0
 20720                              <1> 		; clr i.size / zero file size
 20721 000058C5 F366AB              <1> 	rep	stosw
 20722                              <1> 		; jsr r0,copyz; i.dskp; i.dskp+16. 
 20723                              <1> 			   ; / zero block pointers
 20724 000058C8 E86EFFFFFF          <1> 	call	setimod
 20725                              <1> 		; jsr r0,setimod / set i-node modified flag
 20726 000058CD 66A1[62740000]      <1> 	mov	ax, [ii]
 20727                              <1> 		; mov ii,r1
 20728 000058D3 C3                  <1> 	retn
 20729                              <1> 		; rts r0
 20730                              <1> 
 20731                              <1> imap:
 20732                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20733                              <1> 	; 26/04/2013 (Retro UNIX 8086 v1)
 20734                              <1> 	;
 20735                              <1> 	; 'imap' finds the byte in core (superblock) containing
 20736                              <1> 	; allocation bit for an i-node whose number in r1.
 20737                              <1> 	;
 20738                              <1> 	; INPUTS ->
 20739                              <1> 	;    r1 - contains an i-number
 20740                              <1> 	;    fsp - start of table containing open files
 20741                              <1> 	;
 20742                              <1> 	; OUTPUTS ->
 20743                              <1> 	;    r2 - byte address of byte with the allocation bit
 20744                              <1> 	;    mq - a mask to locate the bit position.	
 20745                              <1> 	;	  (a 1 is in calculated bit posisiton)
 20746                              <1> 	;
 20747                              <1> 	; ((AX = R1)) input/output
 20748                              <1> 	; ((DL/DX = MQ)) output
 20749                              <1> 	; ((BX = R2)) output
 20750                              <1> 	;
 20751                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 20752                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI))  
 20753                              <1> 	;
 20754                              <1> 		; / get the byte that has the allocation bit for 
 20755                              <1> 		; / the i-number contained in r1
 20756                              <1> 	;mov	dx, 1
 20757 000058D4 B201                <1> 	mov	dl, 1
 20758                              <1> 		; mov $1,mq / put 1 in the mq
 20759 000058D6 0FB7D8              <1> 	movzx	ebx, ax
 20760                              <1> 		; mov r1,r2 / r2 now has i-number whose byte
 20761                              <1>  		          ; / in the map we must find
 20762 000058D9 6683EB29            <1> 	sub	bx, 41
 20763                              <1> 		; sub $41.,r2 / r2 has i-41
 20764 000058DD 88D9                <1> 	mov	cl, bl
 20765                              <1> 		; mov r2,r3 / r3 has i-41
 20766 000058DF 80E107              <1> 	and	cl, 7
 20767                              <1> 		; bic $!7,r3 / r3 has (i-41) mod 8 to get 
 20768                              <1> 			   ; / the bit position
 20769 000058E2 7402                <1> 	jz	short imap1
 20770                              <1> 	;shl	dx, cl
 20771 000058E4 D2E2                <1> 	shl	dl, cl
 20772                              <1> 		; mov r3,lsh / move the 1 over (i-41) mod 8 positions
 20773                              <1> imap1:			   ; / to the left to mask the correct bit
 20774 000058E6 66C1EB03            <1> 	shr	bx, 3
 20775                              <1> 		; asr r2
 20776                              <1> 		; asr r2
 20777                              <1> 		; asr r2 / r2 has (i-41) base 8 of the byte number
 20778                              <1> 		       ; / from the start of the map
 20779                              <1> 		; mov r2,-(sp) / put (i-41) base 8 on the stack
 20780 000058EA BE[307D0000]        <1> 	mov	esi, systm
 20781                              <1> 		; mov $systm,r2 / r2 points to the in-core image of
 20782                              <1> 				; / the super block for drum
 20783                              <1> 	;cmp	word [cdev], 0
 20784 000058EF 803D[66740000]00    <1> 	cmp	byte [cdev], 0
 20785                              <1> 		; tst cdev / is the device the disk
 20786 000058F6 7606                <1> 	jna	short imap2
 20787                              <1> 		; beq 1f / yes
 20788 000058F8 81C608020000        <1> 	add	esi, mount - systm
 20789                              <1> 		; add $mount-systm,r2 / for mounted device,
 20790                              <1> 			; / r2 points to 1st word of its super block
 20791                              <1> imap2: ; 1:
 20792 000058FE 66031E              <1> 	add	bx, [esi] ;; add free map size to si
 20793                              <1> 		; add (r2)+,(sp) / get byte address of allocation bit
 20794 00005901 6683C304            <1> 	add	bx, 4
 20795 00005905 01F3                <1> 	add	ebx, esi
 20796                              <1>         	; add (sp)+,r2 / ?
 20797                              <1> 	;add	ebx, 4 ;; inode map offset in superblock
 20798                              <1> 		      ;; (2 + free map size + 2)
 20799                              <1> 		; add $2,r2 / ?
 20800                              <1>  	; DL/DX (MQ) has a 1 in the calculated bit position
 20801                              <1>         ; BX (R2) has byte address of the byte with allocation bit
 20802 00005907 C3                  <1> 	retn
 20803                              <1> 		; rts r0
 20804                                  %include 'u6.s'        ; 31/05/2015
 20805                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS6.INC
 20806                              <1> ; Last Modification: 18/11/2015
 20807                              <1> ; ----------------------------------------------------------------------------
 20808                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 20809                              <1> ; (v0.1 - Beginning: 11/07/2012)
 20810                              <1> ;
 20811                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 20812                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 20813                              <1> ; <Bell Laboratories (17/3/1972)>
 20814                              <1> ; <Preliminary Release of UNIX Implementation Document>
 20815                              <1> ;
 20816                              <1> ; Retro UNIX 8086 v1 - U6.ASM (23/07/2014) //// UNIX v1 -> u6.s
 20817                              <1> ;
 20818                              <1> ; ****************************************************************************
 20819                              <1> 
 20820                              <1> readi:
 20821                              <1> 	; 20/05/2015
 20822                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 20823                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 20824                              <1> 	;
 20825                              <1> 	; Reads from an inode whose number in R1
 20826                              <1> 	; 
 20827                              <1> 	; INPUTS ->
 20828                              <1> 	;    r1 - inode number
 20829                              <1> 	;    u.count - byte count user desires
 20830                              <1> 	;    u.base - points to user buffer
 20831                              <1> 	;    u.fofp - points to word with current file offset
 20832                              <1> 	; OUTPUTS ->
 20833                              <1> 	;    u.count - cleared
 20834                              <1> 	;    u.nread - accumulates total bytes passed back
 20835                              <1> 	;
 20836                              <1> 	; ((AX = R1)) input/output
 20837                              <1> 	;    (Retro UNIX Prototype : 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
 20838                              <1>         ;    ((Modified registers: edx, ebx, ecx, esi, esi, ebp))  
 20839                              <1> 
 20840 00005908 31D2                <1> 	xor	edx, edx ; 0
 20841 0000590A 8915[A8740000]      <1> 	mov 	[u.nread], edx ; 0
 20842                              <1> 		 ; clr u.nread / accumulates number of bytes transmitted
 20843 00005910 668915[E5740000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
 20844 00005917 3915[A4740000]      <1> 	cmp 	[u.count], edx ; 0
 20845                              <1> 	         ; tst u.count / is number of bytes to be read greater than 0
 20846 0000591D 7701                <1> 	ja 	short readi_1 ; 1f
 20847                              <1> 		 ; bgt 1f / yes, branch
 20848 0000591F C3                  <1> 	retn
 20849                              <1> 		 ; rts r0 / no, nothing to read; return to caller
 20850                              <1> readi_1: ; 1:
 20851                              <1> 	         ; mov r1,-(sp) / save i-number on stack
 20852 00005920 6683F828            <1> 	cmp	ax, 40
 20853                              <1> 		 ; cmp r1,$40. / want to read a special file 
 20854                              <1> 		 ;             / (i-nodes 1,...,40 are for special files)
 20855 00005924 0F87D3000000        <1>         ja      dskr 
 20856                              <1> 		 ; ble 1f / yes, branch
 20857                              <1> 		 ; jmp dskr / no, jmp to dskr; 
 20858                              <1> 		 ;         / read file with i-node number (r1)
 20859                              <1> 		 ;    / starting at byte ((u.fofp)), read in u.count bytes
 20860                              <1> 	; (20/05/2015)
 20861 0000592A 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 20862                              <1> 	; 1:
 20863 0000592B 0FB6D8              <1> 	movzx	ebx, al
 20864 0000592E 66C1E302            <1> 	shl	bx, 2
 20865                              <1> 		 ; asl r1 / multiply inode number by 2
 20866 00005932 81C3[36590000]      <1> 	add	ebx, readi_2 - 4
 20867 00005938 FF23                <1> 	jmp	dword [ebx]	
 20868                              <1> 		 ; jmp *1f-2(r1)
 20869                              <1> readi_2: ; 1:
 20870 0000593A [86590000]          <1> 	dd	rtty ; tty, AX = 1 (runix)
 20871                              <1> 		 ;rtty / tty; r1=2
 20872                              <1> 		 ;rppt / ppt; r1=4
 20873 0000593E [D9590000]          <1> 	dd	rmem ; mem, AX = 2 (runix)
 20874                              <1> 		 ;rmem / mem; r1=6
 20875                              <1> 		 ;rrf0 / rf0
 20876                              <1> 		 ;rrk0 / rk0
 20877                              <1> 		 ;rtap / tap0
 20878                              <1> 		 ;rtap / tap1
 20879                              <1> 		 ;rtap / tap2
 20880                              <1> 		 ;rtap / tap3
 20881                              <1> 		 ;rtap / tap4
 20882                              <1> 		 ;rtap / tap5
 20883                              <1> 		 ;rtap / tap6
 20884                              <1> 		 ;rtap / tap7
 20885 00005942 [9B600000]          <1> 	dd	rfd ; fd0, AX = 3 (runix only)
 20886 00005946 [9B600000]          <1> 	dd	rfd ; fd1, AX = 4 (runix only)
 20887 0000594A [9B600000]          <1> 	dd	rhd ; hd0, AX = 5 (runix only)
 20888 0000594E [9B600000]          <1> 	dd	rhd ; hd1, AX = 6 (runix only)	
 20889 00005952 [9B600000]          <1> 	dd	rhd ; hd2, AX = 7 (runix only)
 20890 00005956 [9B600000]          <1> 	dd	rhd ; hd3, AX = 8 (runix only)	
 20891 0000595A [EE590000]          <1> 	dd	rlpr ; lpr, AX = 9 (invalid, write only device !?)
 20892 0000595E [D5590000]          <1> 	dd	rcvt ; tty0, AX = 10 (runix)	  
 20893                              <1> 		 ;rcvt / tty0
 20894 00005962 [D5590000]          <1> 	dd	rcvt ; tty1, AX = 11 (runix)	  
 20895                              <1> 		 ;rcvt / tty1
 20896 00005966 [D5590000]          <1> 	dd	rcvt ; tty2, AX = 12 (runix)	  
 20897                              <1> 		 ;rcvt / tty2
 20898 0000596A [D5590000]          <1> 	dd	rcvt ; tty3, AX = 13 (runix)	  
 20899                              <1> 		 ;rcvt / tty3
 20900 0000596E [D5590000]          <1> 	dd	rcvt ; tty4, AX = 14 (runix)	  
 20901                              <1> 		 ;rcvt / tty4
 20902 00005972 [D5590000]          <1> 	dd	rcvt ; tty5, AX = 15 (runix)	  
 20903                              <1> 		 ;rcvt / tty5
 20904 00005976 [D5590000]          <1> 	dd	rcvt ; tty6, AX = 16 (runix)	  
 20905                              <1> 		 ;rcvt / tty6
 20906 0000597A [D5590000]          <1> 	dd	rcvt ; tty7, AX = 17 (runix)	  
 20907                              <1> 		 ;rcvt / tty7
 20908 0000597E [D5590000]          <1> 	dd	rcvt ; COM1, AX = 18 (runix only)	  
 20909                              <1> 		 ;rcrd / crd
 20910 00005982 [D5590000]          <1> 	dd	rcvt ; COM2, AX = 19 (runix only)
 20911                              <1> 
 20912                              <1> rtty: ; / read from console tty
 20913                              <1> 	; 17/10/2015 - 16/07/2015 (Retro UNIX 8086 v1)
 20914                              <1> 	; 	     (Only 1 byte is read, by ignoring byte count!)
 20915                              <1> 	;  	     WHAT FOR: Every character from Keyboard input 
 20916                              <1> 	;	     must be written immediate on video page (screen)
 20917                              <1> 	;	     when it is required.	
 20918                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 20919                              <1> 	; 11/03/2013 - 19/06/2014 (Retro UNIX 8086 v1)
 20920                              <1> 	;
 20921                              <1> 	; Console tty buffer is PC keyboard buffer
 20922                              <1> 	; and keyboard-keystroke handling is different than original
 20923                              <1> 	; unix (PDP-11) here. TTY/Keyboard procedures here are changed
 20924                              <1> 	; according to IBM PC compatible ROM BIOS keyboard functions. 
 20925                              <1> 	;
 20926                              <1> 	; 06/12/2013
 20927 00005986 0FB61D[CF740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 20928 0000598D 8A83[D5710000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 20929                              <1> rttys:
 20930                              <1> 		; mov tty+[8*ntty]-8+6,r5 / r5 is the address of the 4th word of
 20931                              <1> 	               ; / of the control and status block
 20932                              <1> 		; tst 2(r5) / for the console tty; this word points to the console
 20933                              <1> 		       ; / tty buffer
 20934                              <1> 	; 28/07/2013
 20935 00005993 A2[D4740000]        <1> 	mov 	[u.ttyn], al
 20936                              <1> 	; 13/01/2014
 20937 00005998 FEC0                <1> 	inc	al
 20938 0000599A A2[B0740000]        <1> 	mov	[u.ttyp], al ; tty number + 1
 20939                              <1> rtty_nc: ; 01/02/2014
 20940                              <1> 	; 29/09/2013
 20941 0000599F B90A000000          <1> 	mov	ecx, 10
 20942                              <1> rtty_1: 	; 01/02/2014
 20943 000059A4 6651                <1> 	push 	cx ; 29/09/2013
 20944                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
 20945 000059A6 B001                <1> 	mov 	al, 1
 20946 000059A8 E8330B0000          <1> 	call 	getc
 20947 000059AD 6659                <1> 	pop 	cx ; 29/09/2013	
 20948 000059AF 7516                <1> 	jnz	short rtty_2
 20949                              <1> 		; bne 1f / 2nd word of console tty buffer contains number
 20950                              <1> 	               ; / of chars. Is this number non-zero?
 20951 000059B1 E20D                <1> 	loop	rtty_idle ; 01/02/2014
 20952                              <1> 	; 05/10/2013
 20953 000059B3 8A25[D4740000]      <1> 	mov	ah, [u.ttyn]
 20954                              <1> 	; 29/09/2013
 20955 000059B9 E871FBFFFF          <1> 	call	sleep
 20956                              <1> 		; jsr r0,canon; ttych / if 0, call 'canon' to get a line
 20957                              <1>                 ;           / (120 chars.)
 20958                              <1> 	;byte [u.ttyn] = tty number (0 to 9) 
 20959 000059BE EBDF                <1> 	jmp	short rtty_nc ; 01/02/2014
 20960                              <1> 
 20961                              <1> rtty_idle:
 20962                              <1> 	; 29/07/2013
 20963 000059C0 E8D6FAFFFF          <1> 	call 	idle
 20964 000059C5 EBDD                <1> 	jmp	short rtty_1 ; 01/02/2014
 20965                              <1> 	;1:
 20966                              <1> 		; tst 2(r5) / is the number of characters zero
 20967                              <1> 		; beq ret1 / yes, return to caller via 'ret1'
 20968                              <1> 		; movb *4(r5),r1 / no, put character in r1
 20969                              <1> 		; inc 4(r5) / 3rd word of console tty buffer points to byte which
 20970                              <1> 		          ; / contains the next char.
 20971                              <1> 		; dec 2(r5) / decrement the character count
 20972                              <1> rtty_2:
 20973 000059C7 30C0                <1> 	xor 	al, al
 20974 000059C9 E8120B0000          <1> 	call 	getc
 20975 000059CE E892000000          <1> 	call	passc
 20976                              <1> 		; jsr r0,passc / move the character to core (user)
 20977                              <1> 	;; 17/10/2015 - 16/07/2015
 20978                              <1> 	; 19/06/2014
 20979                              <1> 	;;jnz	short rtty_nc
 20980 000059D3 58                  <1> 	pop	eax  ; (20/05/2015)
 20981 000059D4 C3                  <1> 	retn 
 20982                              <1> ;ret1:
 20983                              <1> 		; jmp ret / return to caller via 'ret'
 20984                              <1> 
 20985                              <1> rcvt:   ; < receive/read character from tty >
 20986                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 20987                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 20988                              <1> 	;
 20989                              <1> 	; Retro UNIX 8086 v1 modification !
 20990                              <1> 	; 
 20991                              <1> 	; In original UNIX v1, 'rcvt' routine 
 20992                              <1> 	;		(exactly different than this one)
 20993                              <1> 	;	was in 'u9.s' file.
 20994                              <1> 	;
 20995 000059D5 2C0A                <1> 	sub 	al, 10
 20996                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 20997                              <1> 	; 16/07/2013
 20998                              <1> 	; 21/05/2013
 20999 000059D7 EBBA                <1>         jmp     short rttys
 21000                              <1>       
 21001                              <1> ;rppt: / read paper tape
 21002                              <1> ;	jsr	r0,pptic / gets next character in clist for ppt input and
 21003                              <1> ;			 / places
 21004                              <1> ;		br ret / it in r1; if there 1s no problem with reader, it
 21005                              <1> ;		       / also enables read bit in prs
 21006                              <1> ;	jsr	r0,passc / place character in users buffer area
 21007                              <1> ;	br	rppt
 21008                              <1> 
 21009                              <1> rmem: ; / transfer characters from memory to a user area of core
 21010                              <1> 	; 17/10/2015
 21011                              <1> 	; 11/06/2015
 21012                              <1> 	; 24/05/2015
 21013                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21014                              <1> 	;
 21015 000059D9 8B35[90740000]      <1> 	mov     esi, [u.fofp]
 21016                              <1> rmem_1:
 21017 000059DF 8B1E                <1>         mov     ebx, [esi]        
 21018                              <1> 	        ; mov *u.fofp,r1 / save file offset which points to the char
 21019                              <1> 		               ; / to be transferred to user
 21020 000059E1 FF06                <1>         inc     dword [esi] ; 17/10/2015
 21021                              <1> 		; inc *u.fofp / increment file offset to point to 'next' 
 21022                              <1> 			    ; / char in memory file
 21023 000059E3 8A03                <1> 	mov	al, [ebx]
 21024                              <1> 		; movb (r1),r1 / get character from memory file, 
 21025                              <1> 		             ; / put it in r1
 21026 000059E5 E87B000000          <1> 	call	passc        ; jsr r0,passc / move this character to 
 21027                              <1> 			     ;  / the next byte of the users core area
 21028                              <1> 		; br rmem / continue
 21029 000059EA 75F3                <1> 	jnz	short rmem_1
 21030                              <1> ret_:
 21031 000059EC 58                  <1> 	pop	eax ; 09/06/2015
 21032 000059ED C3                  <1> 	retn
 21033                              <1> 
 21034                              <1> rlpr:
 21035                              <1> ;1:
 21036                              <1> ;rcrd:
 21037 000059EE C705[D5740000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 21038 000059F6 0000                <1>
 21039 000059F8 E97FE6FFFF          <1> 	jmp	error
 21040                              <1> 		;jmp	error / see 'error' routine
 21041                              <1> 
 21042                              <1> dskr:
 21043                              <1> 	; 12/10/2015
 21044                              <1> 	; 21/08/2015
 21045                              <1> 	; 25/07/2015
 21046                              <1> 	; 10/07/2015
 21047                              <1> 	; 16/06/2015
 21048                              <1> 	; 31/05/2015
 21049                              <1> 	; 24/05/2015 (Retro UNIX 386 v1 - Beginning)
 21050                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 21051                              <1> dskr_0:
 21052 000059FD 50                  <1> 	push	eax
 21053                              <1> 		; mov (sp),r1 / i-number in r1
 21054                              <1> 	; AX = i-number
 21055 000059FE E825FDFFFF          <1> 	call	iget
 21056                              <1> 		; jsr r0,iget / get i-node (r1) into i-node section of core
 21057 00005A03 0FB715[5A710000]    <1>         movzx   edx, word [i.size] ; 16/06/2015
 21058                              <1> 		; mov i.size,r2 / file size in bytes in r2
 21059 00005A0A 8B1D[90740000]      <1> 	mov	ebx, [u.fofp]
 21060 00005A10 2B13                <1> 	sub	edx, [ebx]
 21061                              <1> 		; sub *u.fofp,r2 / subtract file offset
 21062                              <1>         ; 12/10/2015
 21063                              <1> 	; jna     short ret_ 
 21064                              <1> 		; blos ret
 21065 00005A12 7709                <1> 	ja	short dskr_1
 21066                              <1> 	;
 21067                              <1> dskr_retn: ; 12/10/2015
 21068 00005A14 58                  <1> 	pop	eax
 21069 00005A15 C605[E7740000]00    <1> 	mov	byte [u.kcall], 0
 21070 00005A1C C3                  <1> 	retn	
 21071                              <1> dskr_1: 
 21072 00005A1D 3B15[A4740000]      <1> 	cmp     edx, [u.count] 
 21073                              <1> 		; cmp r2,u.count / are enough bytes left in file 
 21074                              <1> 			       ; / to carry out read
 21075 00005A23 7306                <1> 	jnb	short dskr_2
 21076                              <1> 		; bhis 1f
 21077 00005A25 8915[A4740000]      <1> 	mov	[u.count], edx
 21078                              <1> 		; mov r2,u.count / no, just read to end of file
 21079                              <1> dskr_2: ; 1:
 21080                              <1> 	; AX = i-number
 21081 00005A2B E885FBFFFF          <1> 	call	mget
 21082                              <1> 		; jsr r0,mget / returns physical block number of block 
 21083                              <1> 			    ; / in file where offset points
 21084                              <1> 	; eAX = physical block number
 21085 00005A30 E8C0070000          <1> 	call	dskrd
 21086                              <1> 		; jsr r0,dskrd / read in block, r5 points to 
 21087                              <1> 			     ; / 1st word of data in buffer
 21088                              <1> 	; 09/06/2015
 21089 00005A35 803D[E7740000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
 21090 00005A3C 770F                <1> 	ja	short dskr_4	  ; zf=0 -> the caller is 'namei'
 21091 00005A3E 66833D[E5740000]00  <1> 	cmp	word [u.pcount], 0
 21092 00005A46 7705                <1> 	ja	short dskr_4
 21093                              <1> dskr_3:
 21094                              <1> 	; [u.base] = virtual address to transfer (as destination address)
 21095 00005A48 E853000000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 21096                              <1> dskr_4:
 21097                              <1> 	; eBX (r5) = system (I/O) buffer address -physical-
 21098 00005A4D E8C7020000          <1> 	call	sioreg
 21099                              <1> 		; jsr r0,sioreg
 21100 00005A52 87F7                <1> 	xchg	esi, edi
 21101                              <1> 	; eDI = file (user data) offset
 21102                              <1> 	; eSI = sector (I/O) buffer offset
 21103                              <1> 	; eCX = byte count
 21104 00005A54 F3A4                <1> 	rep	movsb
 21105                              <1> 		; movb (r2)+,(r1)+ / move data from buffer into working core
 21106                              <1> 		                 ; / starting at u.base
 21107                              <1> 		; dec r3
 21108                              <1> 		; bne 2b / branch until proper number of bytes are transferred
 21109                              <1> 	; 25/07/2015
 21110                              <1> 	; eax = remain bytes in buffer
 21111                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 21112 00005A56 09C0                <1> 	or	eax, eax
 21113 00005A58 75EE                <1> 	jnz	short dskr_3 ; (page end before system buffer end!)		
 21114                              <1> 	; 03/08/2013
 21115                              <1> 	;pop	eax
 21116 00005A5A 390D[A4740000]      <1> 	cmp	[u.count], ecx ; 0
 21117                              <1> 		; tst u.count / all bytes read off disk
 21118                              <1> 		; bne dskr
 21119                              <1> 		; br ret
 21120                              <1>         ;ja      short dskr_0
 21121                              <1> 	;mov	[u.kcall], cl ; 0 ; 09/06/2015
 21122                              <1> 	;retn
 21123                              <1> 	; 12/10/2015
 21124 00005A60 76B2                <1> 	jna	short dskr_retn
 21125 00005A62 58                  <1> 	pop	eax  ; (i-node number)
 21126 00005A63 EB98                <1> 	jmp	short dskr_0
 21127                              <1> 	
 21128                              <1> passc:
 21129                              <1> 	; 18/10/2015
 21130                              <1> 	; 10/07/2015
 21131                              <1> 	; 01/07/2015
 21132                              <1> 	; 08/06/2015
 21133                              <1> 	; 04/06/2015
 21134                              <1> 	; 20/05/2015
 21135                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21136                              <1> 	;
 21137                              <1>    	;(Retro UNIX 386 v1 - translation from user's virtual address
 21138                              <1> 	;		      to physical address
 21139 00005A65 66833D[E5740000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 21140                              <1> 			     ; 1-4095 --> use previous physical base address
 21141                              <1> 			     ; in [u.pbase]
 21142 00005A6D 7705                <1> 	ja	short passc_3
 21143                              <1> 	; 08/06/2015 - 10/07/2015
 21144 00005A6F E82C000000          <1> 	call	trans_addr_w
 21145                              <1> passc_3:
 21146                              <1> 	; 19/05/2015
 21147 00005A74 66FF0D[E5740000]    <1> 	dec	word [u.pcount]
 21148                              <1> 	;
 21149 00005A7B 8B1D[E1740000]      <1> 	mov	ebx, [u.pbase]
 21150 00005A81 8803                <1> 	mov	[ebx], al
 21151                              <1> 		; movb r1,*u.base / move a character to the next byte of the
 21152                              <1> 		               ; / users buffer
 21153 00005A83 FF05[A0740000]      <1> 	inc	dword [u.base]
 21154                              <1> 		; inc u.base / increment the pointer to point to 
 21155                              <1> 			  ; / the next byte in users buffer
 21156 00005A89 FF05[E1740000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 21157 00005A8F FF05[A8740000]      <1> 	inc	dword [u.nread]
 21158                              <1> 		; inc u.nread / increment the number of bytes read
 21159 00005A95 FF0D[A4740000]      <1> 	dec	dword [u.count]
 21160                              <1> 		; dec u.count / decrement the number of bytes to be read
 21161                              <1> 		; bne 1f / any more bytes to read?; yes, branch
 21162 00005A9B C3                  <1> 	retn
 21163                              <1> 		; mov (sp)+,r0 / no, do a non-local return to the caller of
 21164                              <1> 		             ; / 'readi' by:
 21165                              <1> 		;/ (1) pop the return address off the stack into r0
 21166                              <1> 		; mov (sp)+,r1 / (2) pop the i-number off the stack into r1
 21167                              <1> 	;1:
 21168                              <1> 		; clr	*$ps / clear processor status
 21169                              <1> 		; rts r0 / return to address currently on top of stack
 21170                              <1> 
 21171                              <1> trans_addr_r:
 21172                              <1> 	; Translate virtual address to physical address 
 21173                              <1> 	; for reading from user's memory space
 21174                              <1> 	; (Retro UNIX 386 v1 feature only !)
 21175                              <1> 	; 18/10/2015
 21176                              <1> 	; 10/07/2015
 21177                              <1> 	; 09/06/2015
 21178                              <1> 	; 08/06/2015 
 21179                              <1> 	; 04/06/2015
 21180                              <1> 	;
 21181                              <1> 	; 18/10/2015
 21182 00005A9C 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
 21183 00005A9E EB04                <1> 	jmp 	short trans_addr_rw
 21184                              <1> 
 21185                              <1> 	;push	eax
 21186                              <1> 	;push	ebx
 21187                              <1> 	;mov	ebx, [u.base]
 21188                              <1> 	;call	get_physical_addr ; get physical address
 21189                              <1> 	;;jnc	short cpass_0
 21190                              <1> 	;jnc	short passc_1
 21191                              <1> 	;mov	[u.error], eax
 21192                              <1> 	;;pop	ebx
 21193                              <1> 	;;pop	eax
 21194                              <1> 	;jmp	error
 21195                              <1> ;cpass_0:
 21196                              <1> 	; 18/10/2015
 21197                              <1> 	; 20/05/2015
 21198                              <1> 	;mov 	[u.pbase], eax ; physical address	
 21199                              <1> 	;mov	[u.pcount], cx ; remain byte count in page (1-4096)
 21200                              <1> 	;pop	ebx
 21201                              <1> 	;pop	eax
 21202                              <1> 	;retn	; 08/06/2015
 21203                              <1> 
 21204                              <1> trans_addr_w:
 21205                              <1> 	; Translate virtual address to physical address 
 21206                              <1> 	; for writing to user's memory space
 21207                              <1> 	; (Retro UNIX 386 v1 feature only !)
 21208                              <1> 	; 18/10/2015
 21209                              <1> 	; 29/07/2015
 21210                              <1> 	; 10/07/2015
 21211                              <1> 	; 09/06/2015
 21212                              <1> 	; 08/06/2015
 21213                              <1> 	; 04/06/2015 (passc)
 21214                              <1> 	;
 21215                              <1> 	; 18/10/2015
 21216 00005AA0 29D2                <1> 	sub	edx, edx
 21217 00005AA2 FEC2                <1> 	inc	dl ; 1 (write access sign)
 21218                              <1> trans_addr_rw:
 21219 00005AA4 50                  <1> 	push	eax
 21220 00005AA5 53                  <1> 	push	ebx
 21221                              <1> 	; 18/10/2015
 21222 00005AA6 52                  <1> 	push 	edx ; r/w sign (in DL)
 21223                              <1> 	;
 21224 00005AA7 8B1D[A0740000]      <1> 	mov	ebx, [u.base]
 21225 00005AAD E818DCFFFF          <1> 	call	get_physical_addr ; get physical address
 21226 00005AB2 730A                <1> 	jnc	short passc_0
 21227 00005AB4 A3[D5740000]        <1> 	mov	[u.error], eax
 21228                              <1> 	;pop	edx
 21229                              <1> 	;pop 	ebx
 21230                              <1> 	;pop	eax
 21231 00005AB9 E9BEE5FFFF          <1> 	jmp	error
 21232                              <1> passc_0:
 21233 00005ABE F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page ; 18/10/2015
 21234 00005AC1 5A                  <1> 	pop	edx ; 18/10/2015
 21235 00005AC2 751C                <1> 	jnz	short passc_1
 21236                              <1> 	; 18/10/2015
 21237 00005AC4 20D2                <1> 	and 	dl, dl
 21238 00005AC6 7418                <1> 	jz	short passc_1
 21239                              <1> 	; 20/05/2015
 21240                              <1> 	; read only (duplicated) page -must be copied to a new page-
 21241                              <1> 	; EBX = linear address
 21242 00005AC8 51                  <1> 	push 	ecx
 21243 00005AC9 E811D9FFFF          <1> 	call 	copy_page
 21244 00005ACE 59                  <1> 	pop	ecx
 21245 00005ACF 721E                <1> 	jc	short passc_2
 21246 00005AD1 50                  <1> 	push	eax ; physical address of the new/allocated page
 21247 00005AD2 E81DDBFFFF          <1> 	call	add_to_swap_queue	
 21248 00005AD7 58                  <1> 	pop	eax
 21249                              <1> 	; 18/10/2015
 21250 00005AD8 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
 21251                              <1> 	;mov 	ecx, PAGE_SIZE
 21252                              <1> 	;sub	ecx, ebx 
 21253 00005ADE 01D8                <1> 	add	eax, ebx  
 21254                              <1> passc_1: 
 21255                              <1> 	; 18/10/2015
 21256                              <1> 	; 20/05/2015
 21257 00005AE0 A3[E1740000]        <1> 	mov 	[u.pbase], eax ; physical address	
 21258 00005AE5 66890D[E5740000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
 21259 00005AEC 5B                  <1> 	pop	ebx
 21260 00005AED 58                  <1> 	pop	eax
 21261 00005AEE C3                  <1> 	retn	; 08/06/2015
 21262                              <1> passc_2:
 21263 00005AEF C705[D5740000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
 21264 00005AF7 0000                <1>
 21265                              <1> 	;pop 	ebx
 21266                              <1> 	;pop	eax
 21267 00005AF9 E97EE5FFFF          <1> 	jmp	error
 21268                              <1> 
 21269                              <1> writei:
 21270                              <1> 	; 20/05/2015
 21271                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21272                              <1> 	; 12/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 21273                              <1> 	;
 21274                              <1> 	; Write data to file with inode number in R1
 21275                              <1> 	; 
 21276                              <1> 	; INPUTS ->
 21277                              <1> 	;    r1 - inode number
 21278                              <1> 	;    u.count - byte count to be written
 21279                              <1> 	;    u.base - points to user buffer
 21280                              <1> 	;    u.fofp - points to word with current file offset
 21281                              <1> 	; OUTPUTS ->
 21282                              <1> 	;    u.count - cleared
 21283                              <1> 	;    u.nread - accumulates total bytes passed back	
 21284                              <1> 	; ((AX = R1))
 21285                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 11/11/2012, UNIXCOPY.ASM)
 21286                              <1> 	;    ((Modified registers: DX, BX, CX, SI, DI, BP)) 	
 21287                              <1> 
 21288 00005AFE 31C9                <1> 	xor	ecx, ecx
 21289 00005B00 890D[A8740000]      <1> 	mov 	[u.nread], ecx  ; 0
 21290                              <1> 		; clr u.nread / clear the number of bytes transmitted during
 21291                              <1> 		            ; / read or write calls
 21292 00005B06 66890D[E5740000]    <1> 	mov	[u.pcount], cx ; 19/05/2015
 21293 00005B0D 390D[A4740000]      <1> 	cmp 	[u.count], ecx
 21294                              <1> 	;	; tst u.count / test the byte count specified by the user
 21295 00005B13 7701                <1> 	ja 	short writei_1 ; 1f
 21296                              <1> 		; bgt 1f / any bytes to output; yes, branch
 21297 00005B15 C3                  <1> 	retn
 21298                              <1> 	;	; rts r0 / no, return - no writing to do
 21299                              <1> writei_1: ;1:
 21300                              <1> 		; mov r1 ,-(sp) / save the i-node number on the stack
 21301 00005B16 6683F828            <1> 	cmp 	ax, 40
 21302                              <1> 		; cmp r1,$40.
 21303                              <1> 		; / does the i-node number indicate a special file?
 21304 00005B1A 0F87F2000000        <1>         ja      dskw 
 21305                              <1> 		; bgt dskw / no, branch to standard file output
 21306                              <1> 	; (20/05/2015)
 21307 00005B20 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 21308 00005B21 0FB6D8              <1> 	movzx	ebx, al
 21309 00005B24 66C1E302            <1> 	shl	bx, 2
 21310                              <1> 		; asl r1 / yes, calculate the index into the special file
 21311 00005B28 81C3[2C5B0000]      <1> 	add	ebx, writei_2 - 4
 21312 00005B2E FF23                <1> 	jmp	dword [ebx]	
 21313                              <1> 		; jmp *1f-2(r1)
 21314                              <1> 		; / jump table and jump to the appropriate routine
 21315                              <1> writei_2: ;1:
 21316 00005B30 [7C5B0000]          <1> 	dd	wtty ; tty, AX = 1 (runix)
 21317                              <1> 		 ;wtty / tty; r1=2
 21318                              <1> 		 ;wppt / ppt; r1=4
 21319 00005B34 [E25B0000]          <1> 	dd	wmem ; mem, AX = 2 (runix)
 21320                              <1> 		 ;wmem / mem; r1=6
 21321                              <1> 		 ;wrf0 / rf0
 21322                              <1> 		 ;wrk0 / rk0
 21323                              <1> 		 ;wtap / tap0
 21324                              <1> 		 ;wtap / tap1
 21325                              <1> 		 ;wtap / tap2
 21326                              <1> 		 ;wtap / tap3
 21327                              <1> 		 ;wtap / tap4
 21328                              <1> 		 ;wtap / tap5
 21329                              <1> 		 ;wtap / tap6
 21330                              <1> 		 ;wtap / tap7
 21331 00005B38 [1D610000]          <1> 	dd	wfd ; fd0, AX = 3 (runix only)
 21332 00005B3C [1D610000]          <1> 	dd	wfd ; fd1, AX = 4 (runix only)
 21333 00005B40 [1D610000]          <1> 	dd	whd ; hd0, AX = 5 (runix only)
 21334 00005B44 [1D610000]          <1> 	dd	whd ; hd1, AX = 6 (runix only)	
 21335 00005B48 [1D610000]          <1> 	dd	whd ; hd2, AX = 7 (runix only)
 21336 00005B4C [1D610000]          <1> 	dd	whd ; hd3, AX = 8 (runix only)	
 21337 00005B50 [D35B0000]          <1> 	dd	wlpr ; lpr, AX = 9   (runix)
 21338 00005B54 [CD5B0000]          <1> 	dd	xmtt ; tty0, AX = 10 (runix)	  
 21339                              <1> 		 ;xmtt / tty0
 21340 00005B58 [CD5B0000]          <1> 	dd	xmtt ; tty1, AX = 11 (runix)	  
 21341                              <1> 		 ;xmtt / tty1
 21342 00005B5C [CD5B0000]          <1> 	dd	xmtt ; tty2, AX = 12 (runix)	  
 21343                              <1> 		 ;xmtt / tty2
 21344 00005B60 [CD5B0000]          <1> 	dd	xmtt ; tty3, AX = 13 (runix)	  
 21345                              <1> 		 ;xmtt / tty3
 21346 00005B64 [CD5B0000]          <1> 	dd	xmtt ; tty4, AX = 14 (runix)	  
 21347                              <1> 		 ;xmtt / tty4
 21348 00005B68 [CD5B0000]          <1> 	dd	xmtt ; tty5, AX = 15 (runix)	  
 21349                              <1> 		 ;xmtt / tty5
 21350 00005B6C [CD5B0000]          <1> 	dd	xmtt ; tty6, AX = 16 (runix)	  
 21351                              <1> 		 ;xmtt / tty6
 21352 00005B70 [CD5B0000]          <1> 	dd	xmtt ; tty7, AX = 17 (runix)	  
 21353                              <1> 		 ;xmtt / tty7
 21354 00005B74 [CD5B0000]          <1> 	dd	xmtt ; COM1, AX = 18 (runix only)	  
 21355                              <1> 		; / wlpr / lpr
 21356 00005B78 [CD5B0000]          <1> 	dd	xmtt ; COM2, AX = 19 (runix only)	
 21357                              <1> 
 21358                              <1> wtty: ; write to console tty (write to screen)
 21359                              <1> 	; 18/11/2015
 21360                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21361                              <1> 	; 12/03/2013 - 07/07/2014 (Retro UNIX 8086 v1)
 21362                              <1> 	;
 21363                              <1> 	; Console tty output is on current video page
 21364                              <1> 	; Console tty character output procedure is changed here
 21365                              <1> 	; acconding to IBM PC compatible ROM BIOS video (text mode) functions.
 21366                              <1> 	;
 21367 00005B7C 0FB61D[CF740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 21368 00005B83 8AA3[D5710000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 21369 00005B89 88E0                <1> 	mov	al, ah ; 07/07/2014
 21370                              <1> wttys:	
 21371                              <1> 	; 10/10/2013
 21372 00005B8B 8825[D4740000]      <1> 	mov 	[u.ttyn], ah
 21373                              <1> 	; 13/01/2014
 21374 00005B91 FEC0                <1> 	inc	al
 21375 00005B93 A2[B1740000]        <1> 	mov	[u.ttyp+1], al ; tty number + 1
 21376                              <1> wtty_nc: ; 15/05/2013
 21377                              <1> 	; AH = [u.ttyn] = tty number ; 28/07/2013
 21378 00005B98 E81C010000          <1> 	call	cpass
 21379                              <1> 		; jsr r0,cpass / get next character from user buffer area; if
 21380                              <1> 		             ; / none go to return address in syswrite
 21381                              <1> 		; tst r1 / is character = null
 21382                              <1> 		; beq wtty / yes, get next character
 21383                              <1> 	; 10/10/2013
 21384 00005B9D 742C                <1> 	jz	short wret
 21385                              <1> 	;1 :
 21386                              <1> 		;mov 	$240,*$ps / no, set processor priority to five
 21387                              <1> 		;cmpb	cc+1,$20. / is character count for console tty greater
 21388                              <1> 		;	          / than 20
 21389                              <1> 		;bhis	2f / yes; branch to put process to sleep
 21390                              <1> 	; 27/06/2014
 21391                              <1> wtty_1:
 21392                              <1> 	; AH = tty number
 21393                              <1> 	; AL = ASCII code of the character
 21394                              <1> 	; 15/04/2014
 21395 00005B9F 6650                <1> 	push	ax
 21396 00005BA1 E8A80A0000          <1> 	call	putc ; 14/05/2013
 21397 00005BA6 731F                <1> 	jnc	short wtty_2
 21398                              <1> 	; 18/11/2015
 21399 00005BA8 E8EEF8FFFF          <1> 	call	idle
 21400 00005BAD 668B0424            <1> 	mov	ax, [esp]
 21401 00005BB1 E8980A0000          <1> 	call	putc
 21402 00005BB6 730F                <1> 	jnc	short wtty_2 
 21403                              <1> 	; 02/06/2014
 21404 00005BB8 8A25[D4740000]      <1> 	mov	ah, [u.ttyn]
 21405 00005BBE E86CF9FFFF          <1> 	call	sleep
 21406 00005BC3 6658                <1> 	pop	ax
 21407 00005BC5 EBD8                <1> 	jmp 	short wtty_1
 21408                              <1> 		; jc 	error ; 15/05/2013 (COM1 or COM2 serial port error)
 21409                              <1> 		; jsr 	r0,putc; 1 / find place in freelist to assign to 
 21410                              <1> 			      ; / console tty and
 21411                              <1> 		; br 	2f / place character in list; if none available
 21412                              <1> 		   	  ; / branch to put process to sleep
 21413                              <1> 		; jsr	r0,startty / attempt to output character on tty
 21414                              <1> wtty_2:
 21415                              <1> 	; 15/04/2014
 21416 00005BC7 6658                <1> 	pop	ax
 21417 00005BC9 EBCD                <1> 	jmp	short wtty_nc
 21418                              <1> 		; br wtty
 21419                              <1> wret:	; 10/10/2013 (20/05/2015)
 21420 00005BCB 58                  <1> 	pop	eax
 21421 00005BCC C3                  <1> 	retn
 21422                              <1> 	;2:
 21423                              <1> 		;mov	r1,-(sp) / place character on stack
 21424                              <1> 		;jsr	r0,sleep; 1 / put process to sleep
 21425                              <1> 		;mov	(sp)+,r1 / remove character from stack
 21426                              <1> 		;br	1b / try again to place character in clist and output
 21427                              <1> 
 21428                              <1> xmtt:   ; < send/write character to tty >
 21429                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21430                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 21431                              <1> 	;
 21432                              <1> 	; Retro UNIX 8086 v1 modification !
 21433                              <1> 	; 
 21434                              <1> 	; In original UNIX v1, 'xmtt' routine 
 21435                              <1> 	;		(exactly different than this one)
 21436                              <1> 	;	was in 'u9.s' file.
 21437                              <1> 	;
 21438 00005BCD 2C0A                <1> 	sub 	al, 10
 21439                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 21440                              <1> 	 ; 10/10/2013
 21441 00005BCF 88C4                <1> 	mov	ah, al
 21442                              <1> 	; 28/07/2013
 21443 00005BD1 EBB8                <1> 	jmp	short wttys
 21444                              <1> 
 21445                              <1> ;wppt:
 21446                              <1> ;	jsr	r0,cpass / get next character from user buffer area,
 21447                              <1> ;		         / if none return to writei's calling routine
 21448                              <1> ;	jsr	r0,pptoc / output character on ppt
 21449                              <1> ;	br	wppt
 21450                              <1> wlpr:
 21451 00005BD3 C705[D5740000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 21452 00005BDB 0000                <1>
 21453 00005BDD E99AE4FFFF          <1> 	jmp 	error   ; ... Printing procedure will be located here ...
 21454                              <1> 		;/	jsr	r0,cpass
 21455                              <1> 		;/	cmp	r0,$'a
 21456                              <1> 		;/	blo	1f
 21457                              <1> 		;/	cmp	r1,$'z
 21458                              <1> 		;/	bhi	1f
 21459                              <1> 		;/	sub	$40,r1
 21460                              <1> 		;/1:
 21461                              <1> 		;/	jsr	r0,lptoc
 21462                              <1> 		;/	br	wlpr
 21463                              <1> 		; br rmem / continue
 21464                              <1> 
 21465                              <1> wmem: ; / transfer characters from a user area of core to memory file
 21466                              <1> 	; 17/10/2015
 21467                              <1> 	; 11/06/2015
 21468                              <1> 	; 24/05/2015
 21469                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21470                              <1> 	;
 21471 00005BE2 813D[1B080000]-     <1> 	cmp	dword [x_timer], clock ; multi tasking clock/timer
 21472 00005BE8 [BF540000]          <1>
 21473 00005BEC 7415                <1>         je      short wmem_acc_err
 21474                              <1> 	;
 21475 00005BEE 8B35[90740000]      <1>         mov     esi, [u.fofp] 
 21476                              <1> wmem_1:
 21477 00005BF4 E8C0000000          <1> 	call	cpass
 21478                              <1> 		; jsr r0,cpass / get next character from users area of
 21479                              <1> 			     ; / core and put it in r1
 21480                              <1>         	; mov r1,-(sp) / put character on the stack
 21481                              <1> 	; 20/09/2013
 21482 00005BF9 74D0                <1> 	jz	short wret ; wmem_2  
 21483 00005BFB 8B1E                <1>         mov     ebx, [esi]
 21484                              <1> 		; mov *u.fofp,r1 / save file offset in r1
 21485 00005BFD FF06                <1>         inc     dword [esi] ; 17/10/2015
 21486                              <1> 		; inc *u.fofp / increment file offset to point to next
 21487                              <1> 			    ; / available location in file
 21488 00005BFF 8803                <1> 	mov	[ebx], al	
 21489                              <1> 		; movb (sp)+,(r1) / pop char off stack, put in memory loc 
 21490                              <1> 			        ; / assigned to it
 21491 00005C01 EBF1                <1> 	jmp	short wmem_1
 21492                              <1> 		; br wmem / continue
 21493                              <1> 	;1:
 21494                              <1> 	;jmp	error / ?
 21495                              <1> ;wmem_2:	
 21496                              <1> ;	; 20/09/2013
 21497                              <1> ;	pop	ax
 21498                              <1> ;	retn
 21499                              <1> 
 21500                              <1> wmem_acc_err:
 21501 00005C03 C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 21502 00005C0B 0000                <1>
 21503 00005C0D E96AE4FFFF          <1> 	jmp	error
 21504                              <1> 
 21505                              <1> 
 21506                              <1> dskw: ; / write routine for non-special files
 21507                              <1> 	;
 21508                              <1> 	; 25/07/2015
 21509                              <1> 	; 16/06/2015
 21510                              <1> 	; 09/06/2015
 21511                              <1> 	; 31/05/2015 (Retro UNIX 386 v1 - Beginning)
 21512                              <1> 	; 26/04/2013 - 20/09/2013 (Retro UNIX 8086 v1)
 21513                              <1> 	;
 21514                              <1> 	; 01/08/2013 (mkdir_w check)
 21515 00005C12 6650                <1> 	push	ax ; 26/04/2013
 21516                              <1> 		; mov (sp),r1 / get an i-node number from the stack into r1
 21517                              <1> 	; AX = inode number
 21518 00005C14 E80FFBFFFF          <1> 	call	iget
 21519                              <1> 		; jsr r0,iget / write i-node out (if modified), 
 21520                              <1> 		            ; / read i-node 'r1' into i-node area of core
 21521 00005C19 8B1D[90740000]      <1>         mov     ebx, [u.fofp] 
 21522 00005C1F 8B13                <1> 	mov 	edx, [ebx]
 21523                              <1> 		; mov *u.fofp,r2 / put the file offset [(u.off) or the offset
 21524                              <1> 			       ; / in the fsp entry for this file] in r2
 21525 00005C21 0315[A4740000]      <1> 	add 	edx, [u.count]	
 21526                              <1> 		; add u.count,r2 / no. of bytes to be written
 21527                              <1> 			       ; / + file offset is put in r2
 21528                              <1> 	; 16/06/2015        
 21529 00005C27 81FAFFFF0000        <1> 	cmp	edx, 65535 ; file size limit (for UNIX v1 file system)
 21530 00005C2D 760F                <1> 	jna	short dskw_0
 21531 00005C2F C705[D5740000]1400- <1> 	mov	dword [u.error], ERR_FILE_SIZE ; 'file size error !'
 21532 00005C37 0000                <1>
 21533 00005C39 E93EE4FFFF          <1> 	jmp	error
 21534                              <1> dskw_0:	
 21535 00005C3E 663B15[5A710000]    <1> 	cmp     dx, [i.size]
 21536                              <1> 		; cmp r2,i.size / is this greater than the present size of
 21537                              <1> 		              ; / the file?
 21538 00005C45 760C                <1> 	jna	short dskw_1
 21539                              <1> 		; blos 1f / no, branch
 21540 00005C47 668915[5A710000]    <1>         mov     [i.size], dx
 21541                              <1> 	 	; mov r2,i.size / yes, increase the file size to 
 21542                              <1> 			      ; / file offset + no. of data bytes
 21543 00005C4E E8E8FBFFFF          <1> 	call	setimod
 21544                              <1> 	 	; jsr r0,setimod / set imod=1 (i.e., core inode has been
 21545                              <1> 		          ; / modified), stuff time of modification into
 21546                              <1> 	          	  ; / core image of i-node
 21547                              <1> dskw_1: ; 1:	
 21548 00005C53 E85DF9FFFF          <1> 	call	mget
 21549                              <1> 	; eAX = Block number
 21550                              <1> 		; jsr r0,mget / get the block no. in which to write 
 21551                              <1> 			    ; /	the next data byte
 21552                              <1> 	; eax = block number
 21553 00005C58 8B1D[90740000]      <1> 	mov     ebx, [u.fofp]
 21554 00005C5E 8B13                <1> 	mov	edx, [ebx]
 21555 00005C60 81E2FF010000        <1> 	and	edx, 1FFh  
 21556                              <1> 		; bit *u.fofp,$777 / test the lower 9 bits of the file offset
 21557 00005C66 750C                <1> 	jnz	short dskw_2
 21558                              <1> 		; bne 2f / if its non-zero, branch; if zero, file offset = 0,
 21559                              <1> 		       ; / 512, 1024,...(i.e., start of new block)
 21560 00005C68 813D[A4740000]0002- <1> 	cmp	dword [u.count], 512
 21561 00005C70 0000                <1>
 21562                              <1> 		; cmp u.count,$512. / if zero, is there enough data to fill
 21563                              <1> 				  ; / an entire block? (i.e., no. of
 21564 00005C72 7305                <1> 	jnb	short dskw_3
 21565                              <1> 		; bhis 3f / bytes to be written greater than 512.? 
 21566                              <1> 			; / Yes, branch. Don't have to read block
 21567                              <1> dskw_2: ; 2: / in as no past info. is to be saved (the entire block will be
 21568                              <1>    		; / overwritten).
 21569 00005C74 E87C050000          <1> 	call	dskrd
 21570                              <1> 		; jsr r0,dskrd / no, must retain old info.. 
 21571                              <1> 			     ; / Hence, read block 'r1' into an I/O buffer
 21572                              <1> dskw_3: ; 3:
 21573                              <1> 	; eAX (r1) = block/sector number
 21574 00005C79 E8D7050000          <1> 	call	wslot
 21575                              <1> 		; jsr r0,wslot / set write and inhibit bits in I/O queue, 
 21576                              <1> 			   ; / proc. status=0, r5 points to 1st word of data
 21577 00005C7E 803D[E7740000]00    <1> 	cmp	byte [u.kcall], 0
 21578 00005C85 770F                <1> 	ja	short dskw_5 ; zf=0 -> the caller is 'mkdir'
 21579                              <1> 	;
 21580 00005C87 66833D[E5740000]00  <1> 	cmp	word [u.pcount], 0
 21581 00005C8F 7705                <1> 	ja	short dskw_5
 21582                              <1> dskw_4:
 21583                              <1> 	; [u.base] = virtual address to transfer (as source address)
 21584 00005C91 E806FEFFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 21585                              <1> dskw_5:
 21586                              <1> 	; eBX (r5) = system (I/O) buffer address
 21587 00005C96 E87E000000          <1> 	call	sioreg
 21588                              <1> 		; jsr r0,sioreg / r3 = no. of bytes of data, 
 21589                              <1> 			     ; / r1 = address of data, r2 points to location
 21590                              <1> 			     ; / in buffer in which to start writing data
 21591                              <1> 	; eSI = file (user data) offset
 21592                              <1> 	; eDI = sector (I/O) buffer offset
 21593                              <1> 	; eCX = byte count
 21594                              <1> 	;
 21595 00005C9B F3A4                <1>   	rep	movsb
 21596                              <1> 		; movb (r1 )+,(r2)+ 
 21597                              <1> 		         ; / transfer a byte of data to the I/O buffer
 21598                              <1> 		; dec r3 / decrement no. of bytes to be written
 21599                              <1> 		; bne 2b / have all bytes been transferred? No, branch
 21600                              <1> 	; 25/07/2015
 21601                              <1> 	; eax = remain bytes in buffer
 21602                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 21603 00005C9D 09C0                <1> 	or	eax, eax
 21604 00005C9F 75F0                <1> 	jnz	short dskw_4 ; (page end before system buffer end!)	
 21605                              <1> dskw_6:
 21606 00005CA1 E8CB050000          <1> 	call	dskwr
 21607                              <1> 		; jsr r0,dskwr / yes, write the block and the i-node
 21608 00005CA6 833D[A4740000]00    <1>         cmp     dword [u.count], 0
 21609                              <1> 		; tst u.count / any more data to write?
 21610 00005CAD 77A4                <1> 	ja	short dskw_1
 21611                              <1> 		; bne 1b / yes, branch
 21612                              <1> 	; 03/08/2013
 21613 00005CAF C605[E7740000]00    <1> 	mov	byte [u.kcall], 0
 21614                              <1> 	; 20/09/2013 (;;)
 21615 00005CB6 6658                <1> 	pop	ax
 21616 00005CB8 C3                  <1> 	retn
 21617                              <1> 	;;jmp 	short dskw_ret 
 21618                              <1> 	        ; jmp ret / no, return to the caller via 'ret'
 21619                              <1> 
 21620                              <1> cpass: ; / get next character from user area of core and put it in r1
 21621                              <1> 	; 18/10/2015
 21622                              <1> 	; 10/10/2015
 21623                              <1> 	; 10/07/2015
 21624                              <1> 	; 02/07/2015
 21625                              <1> 	; 01/07/2015
 21626                              <1> 	; 24/06/2015
 21627                              <1> 	; 08/06/2015
 21628                              <1> 	; 04/06/2015
 21629                              <1> 	; 20/05/2015
 21630                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21631                              <1> 	;
 21632                              <1> 	; INPUTS -> 
 21633                              <1> 	;     [u.base] = virtual address in user area
 21634                              <1> 	;     [u.count] = byte count (max.)
 21635                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
 21636                              <1> 	; OUTPUTS -> 
 21637                              <1> 	;     AL = the character which is pointed by [u.base]
 21638                              <1> 	;     zf = 1 -> transfer count has been completed	
 21639                              <1>         ;
 21640                              <1> 	; ((Modified registers:  EAX, EDX, ECX))
 21641                              <1> 	;
 21642                              <1> 	;
 21643 00005CB9 833D[A4740000]00    <1> 	cmp 	dword [u.count], 0  ; 14/08/2013
 21644                              <1> 		; tst u.count / have all the characters been transferred
 21645                              <1> 			    ; / (i.e., u.count, # of chars. left
 21646 00005CC0 763F                <1> 	jna	short cpass_3
 21647                              <1> 		; beq 1f / to be transferred = 0?) yes, branch
 21648 00005CC2 FF0D[A4740000]      <1> 	dec	dword [u.count]
 21649                              <1> 		; dec u.count / no, decrement u.count
 21650                              <1>         ; 19/05/2015 
 21651                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
 21652                              <1> 	;		      to physical address
 21653 00005CC8 66833D[E5740000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 21654                              <1> 			     ; 1-4095 --> use previous physical base address
 21655                              <1> 			     ; in [u.pbase]
 21656 00005CD0 770E                <1> 	ja	short cpass_1
 21657                              <1> 	; 02/07/2015
 21658 00005CD2 833D[DD740000]00    <1>         cmp     dword [u.ppgdir], 0  ; is the caller os kernel
 21659 00005CD9 7427                <1>         je      short cpass_k       ; (sysexec, '/etc/init') ? 
 21660                              <1> 	; 08/06/2015 - 10/07/2015
 21661 00005CDB E8BCFDFFFF          <1> 	call	trans_addr_r
 21662                              <1> cpass_1:
 21663                              <1> 	; 02/07/2015
 21664                              <1> 	; 24/06/2015
 21665 00005CE0 66FF0D[E5740000]    <1> 	dec	word [u.pcount]
 21666                              <1> cpass_2: 
 21667                              <1> 	 ;10/10/2015
 21668                              <1> 	; 02/07/2015
 21669 00005CE7 8B15[E1740000]      <1> 	mov	edx, [u.pbase]
 21670 00005CED 8A02                <1> 	mov	al, [edx] ; 10/10/2015
 21671                              <1> 		; movb *u.base,r1 / take the character pointed to 
 21672                              <1> 				; / by u.base and put it in r1
 21673 00005CEF FF05[A8740000]      <1> 	inc	dword [u.nread]
 21674                              <1> 		; inc u.nread / increment no. of bytes transferred
 21675 00005CF5 FF05[A0740000]      <1> 	inc	dword [u.base]
 21676                              <1> 		; inc u.base / increment the buffer address to point to the
 21677                              <1> 			   ; / next byte
 21678 00005CFB FF05[E1740000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 21679                              <1> cpass_3:
 21680 00005D01 C3                  <1> 	retn
 21681                              <1> 		; rts	r0 / next byte
 21682                              <1> 	; 1: 
 21683                              <1> 		; mov (sp)+,r0 
 21684                              <1> 		         ; / put return address of calling routine into r0
 21685                              <1> 		; mov (sp)+,r1 / i-number in r1
 21686                              <1> 		; rts r0 / non-local return
 21687                              <1> cpass_k:
 21688                              <1> 	; 02/07/2015
 21689                              <1> 	; The caller is os kernel 
 21690                              <1> 	; (get sysexec arguments from kernel's memory space)
 21691                              <1> 	;
 21692 00005D02 8B1D[A0740000]      <1> 	mov	ebx, [u.base]
 21693 00005D08 66C705[E5740000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
 21694 00005D10 10                  <1>
 21695 00005D11 891D[E1740000]      <1> 	mov	[u.pbase], ebx
 21696 00005D17 EBCE                <1> 	jmp	short cpass_2
 21697                              <1> 	
 21698                              <1> sioreg: 
 21699                              <1> 	; 25/07/2015
 21700                              <1> 	; 18/07/2015
 21701                              <1> 	; 02/07/2015
 21702                              <1> 	; 17/06/2015
 21703                              <1> 	; 09/06/2015
 21704                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21705                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
 21706                              <1> 	;
 21707                              <1> 	; INPUTS -> 
 21708                              <1> 	;     eBX = system buffer (data) address (r5)
 21709                              <1> 	;     [u.fofp] = pointer to file offset pointer
 21710                              <1> 	;     [u.base] = virtual address of the user buffer
 21711                              <1> 	;     [u.pbase] = physical address of the user buffer
 21712                              <1> 	;     [u.count] = byte count
 21713                              <1> 	;     [u.pcount] = byte count within page frame 			
 21714                              <1> 	; OUTPUTS -> 
 21715                              <1> 	;     eSI = user data offset (r1)
 21716                              <1> 	;     eDI = system (I/O) buffer offset (r2)
 21717                              <1> 	;     eCX = byte count (r3)
 21718                              <1> 	;     EAX = remain bytes after byte count within page frame
 21719                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
 21720                              <1>         ;
 21721                              <1> 	; ((Modified registers:  EDX))
 21722                              <1>  
 21723 00005D19 8B35[90740000]      <1>         mov     esi, [u.fofp]
 21724 00005D1F 8B3E                <1>         mov     edi, [esi]
 21725                              <1> 		; mov *u.fofp,r2 / file offset (in bytes) is moved to r2
 21726 00005D21 89F9                <1> 	mov	ecx, edi
 21727                              <1> 		; mov r2,r3 / and also to r3
 21728 00005D23 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
 21729                              <1> 		; bis $177000,r3 / set bits 9,...,15 of file offset in r3
 21730 00005D29 81E7FF010000        <1> 	and	edi, 1FFh
 21731                              <1> 		; bic $!777,r2 / calculate file offset mod 512.
 21732 00005D2F 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
 21733                              <1> 		; add r5,r2 / r2 now points to 1st byte in system buffer
 21734                              <1> 			  ; / where data is to be placed
 21735                              <1>                 ; mov u.base,r1 / address of data is in r1
 21736 00005D31 F7D9                <1> 	neg	ecx
 21737                              <1> 		; neg r3 / 512 - file offset (mod512.) in r3 
 21738                              <1> 		       ; / (i.e., the no. of free bytes in the file block)
 21739 00005D33 3B0D[A4740000]      <1> 	cmp	ecx, [u.count]
 21740                              <1> 		; cmp r3,u.count / compare this with the no. of data bytes
 21741                              <1> 			       ; / to be written to the file
 21742 00005D39 7606                <1> 	jna	short sioreg_0
 21743                              <1> 		; blos	2f / if less than branch. Use the no. of free bytes
 21744                              <1> 			 ; / in the file block as the number to be written
 21745 00005D3B 8B0D[A4740000]      <1> 	mov	ecx, [u.count]
 21746                              <1> 		; mov u.count,r3 / if greater than, use the no. of data 
 21747                              <1> 			       ; / bytes as the number to be written
 21748                              <1> sioreg_0:
 21749                              <1> 	; 17/06/2015
 21750 00005D41 803D[E7740000]00    <1> 	cmp	byte [u.kcall], 0 
 21751 00005D48 7613                <1> 	jna	short sioreg_1
 21752                              <1> 	; 25/07/2015
 21753                              <1> 	 ; the caller is 'mkdir' or 'namei'
 21754 00005D4A A1[A0740000]        <1> 	mov	eax, [u.base] ; 25/07/2015
 21755 00005D4F A3[E1740000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
 21756 00005D54 66890D[E5740000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
 21757 00005D5B EB0B                <1> 	jmp	short sioreg_2
 21758                              <1> sioreg_1:
 21759                              <1> 	; 25/07/2015
 21760                              <1> 	; 18/07/2015
 21761                              <1> 	; 09/06/2015 
 21762 00005D5D 0FB715[E5740000]    <1> 	movzx	edx, word [u.pcount]
 21763                              <1> 		; ecx and [u.pcount] are always > 0, here
 21764 00005D64 39D1                <1> 	cmp	ecx, edx	
 21765 00005D66 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
 21766                              <1> sioreg_2: ; 2:
 21767 00005D68 31C0                <1> 	xor 	eax, eax ; 25/07/2015
 21768                              <1> sioreg_3:
 21769 00005D6A 010D[A8740000]      <1> 	add 	[u.nread], ecx
 21770                              <1> 		; add r3,u.nread / r3 + number of bytes xmitted 
 21771                              <1> 			         ; / during write is put into u.nread
 21772 00005D70 290D[A4740000]      <1> 	sub 	[u.count], ecx
 21773                              <1> 		; sub r3,u.count / u.count = no. of bytes that still 
 21774                              <1> 			       ; / must be written or read
 21775 00005D76 010D[A0740000]      <1> 	add 	[u.base], ecx
 21776                              <1> 		; add r3,u.base / u.base points to the 1st of the remaining
 21777                              <1> 			      ; / data bytes
 21778 00005D7C 010E                <1>         add 	[esi], ecx 
 21779                              <1> 		; add r3,*u.fofp / new file offset = number of bytes done
 21780                              <1> 			       ; / + old file offset
 21781                              <1> 	; 25/07/2015
 21782 00005D7E 8B35[E1740000]      <1> 	mov	esi, [u.pbase]
 21783 00005D84 66290D[E5740000]    <1> 	sub	[u.pcount], cx
 21784 00005D8B 010D[E1740000]      <1> 	add	[u.pbase], ecx
 21785 00005D91 C3                  <1>         retn
 21786                              <1> 		; rts r0
 21787                              <1> 		; transfer count > [u.pcount]
 21788                              <1> sioreg_4:
 21789                              <1> 	; 25/07/2015
 21790                              <1> 	; transfer count > [u.pcount] 
 21791                              <1> 	; (ecx > edx)
 21792 00005D92 89C8                <1> 	mov	eax, ecx
 21793 00005D94 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
 21794 00005D96 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
 21795 00005D98 EBD0                <1> 	jmp	short sioreg_3
 21796                                  %include 'u7.s'        ; 18/04/2015
 21797                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS7.INC
 21798                              <1> ; Last Modification: 14/11/2015
 21799                              <1> ; ----------------------------------------------------------------------------
 21800                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 21801                              <1> ; (v0.1 - Beginning: 11/07/2012)
 21802                              <1> ;
 21803                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 21804                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 21805                              <1> ; <Bell Laboratories (17/3/1972)>
 21806                              <1> ; <Preliminary Release of UNIX Implementation Document>
 21807                              <1> ;
 21808                              <1> ; Retro UNIX 8086 v1 - U7.ASM (13/07/2014) //// UNIX v1 -> u7.s
 21809                              <1> ;
 21810                              <1> ; ****************************************************************************
 21811                              <1> 
 21812                              <1> sysmount: ; / mount file system; args special; name
 21813                              <1> 	; 14/11/2015
 21814                              <1> 	; 24/10/2015
 21815                              <1> 	; 13/10/2015
 21816                              <1> 	; 10/07/2015
 21817                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 21818                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 21819                              <1> 	;
 21820                              <1> 	; 'sysmount' anounces to the system that a removable 
 21821                              <1> 	; file system has been mounted on a special file.
 21822                              <1> 	; The device number of the special file is obtained via
 21823                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
 21824                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
 21825                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
 21826                              <1> 	; to read file system into core, i.e. the first block on the
 21827                              <1> 	; mountable file system is read in. This block is super block
 21828                              <1> 	; for the file system. This call is super user restricted.	
 21829                              <1> 	;
 21830                              <1> 	; Calling sequence:
 21831                              <1> 	;	sysmount; special; name
 21832                              <1> 	; Arguments:
 21833                              <1> 	;	special - pointer to name of special file (device)
 21834                              <1> 	;	name -  pointer to name of the root directory of the
 21835                              <1> 	;		newly mounted file system. 'name' should 
 21836                              <1> 	;		always be a directory.
 21837                              <1> 	; Inputs: - 
 21838                              <1> 	; Outputs: -
 21839                              <1> 	; ...............................................................
 21840                              <1> 	;				
 21841                              <1> 	; Retro UNIX 8086 v1 modification: 
 21842                              <1> 	;       'sysmount' system call has two arguments; so,
 21843                              <1> 	;	* 1st argument, special is pointed to by BX register
 21844                              <1> 	;	* 2nd argument, name is in CX register
 21845                              <1> 	;
 21846                              <1> 	;	NOTE: Device numbers, names and related procedures are 
 21847                              <1> 	;	       already modified for IBM PC compatibility and 
 21848                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
 21849                              <1> 	
 21850                              <1> 	;call	arg2
 21851                              <1> 		; jsr r0,arg2 / get arguments special and name
 21852 00005D9A 891D[98740000]      <1> 	mov	[u.namep], ebx
 21853 00005DA0 51                  <1> 	push	ecx ; directory name
 21854 00005DA1 66833D[6C740000]00  <1> 	cmp	word [mnti], 0
 21855                              <1> 		; tst mnti / is the i-number of the cross device file
 21856                              <1> 			 ; / zero?
 21857                              <1> 	;ja	error
 21858                              <1>         	; bne errora / no, error
 21859 00005DA9 0F87E9000000        <1> 	ja	sysmnt_err0
 21860                              <1> 	;
 21861 00005DAF E8CC000000          <1> 	call	getspl
 21862                              <1> 		; jsr r0,getspl / get special files device number in r1
 21863                              <1> 	; 13/10/2015
 21864 00005DB4 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
 21865 00005DB7 F683[246E0000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
 21866 00005DBE 750F                <1> 	jnz	short sysmnt_1
 21867                              <1> sysmnt_err1:
 21868 00005DC0 C705[D5740000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
 21869 00005DC8 0000                <1>
 21870 00005DCA E9ADE2FFFF          <1> 	jmp	error
 21871                              <1> sysmnt_1:
 21872 00005DCF 8F05[98740000]      <1> 	pop	dword [u.namep]
 21873                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
 21874                              <1> 				  ; / on the device
 21875                              <1> 	; 14/11/2015
 21876 00005DD5 53                  <1> 	push	ebx ; 13/10/2015
 21877                              <1> 		; mov r1,-(sp) / save the device number
 21878                              <1>         ;
 21879 00005DD6 E85DF1FFFF          <1> 	call	namei
 21880                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 21881                              <1> 		       ; ax = 0 -> file not found 	
 21882                              <1> 	;jz	error
 21883                              <1> 	;jc	error
 21884                              <1> 		; jsr r0,namei / get the i-number of the file
 21885                              <1>                	; br errora
 21886 00005DDB 730F                <1> 	jnc	short sysmnt_2
 21887                              <1> sysmnt_err2:
 21888 00005DDD C705[D5740000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
 21889 00005DE5 0000                <1>
 21890 00005DE7 E990E2FFFF          <1> 	jmp	error
 21891                              <1> sysmnt_2:	
 21892 00005DEC 66A3[6C740000]      <1> 	mov	[mnti], ax
 21893                              <1>         	; mov r1,mnti / put it in mnti
 21894                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
 21895                              <1> sysmnt_3: ;1:
 21896                              <1>         ;cmp	byte [ebx+1], 0
 21897                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
 21898                              <1> 			   ; / dismountable device set?
 21899                              <1>         ;jna	short sysmnt_4		
 21900                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
 21901                              <1> 	;call	idle 	; (wait for hardware interrupt)
 21902                              <1> 	;jmp	short sysmnt_3
 21903                              <1> sysmnt_4:   
 21904 00005DF2 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
 21905 00005DF3 A2[69740000]        <1> 	mov	[mdev], al
 21906                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
 21907 00005DF8 8803                <1> 	mov	[ebx], al
 21908                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
 21909                              <1> 			      ; / of the I/O queue entry
 21910                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
 21911                              <1>         	; mov (sp)+,cdev / put device number in cdev
 21912 00005DFA 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
 21913                              <1> 		; bis $2000,sb1 / set the read bit
 21914                              <1> 	; Retro UNIX 386 v1 modification : 
 21915                              <1> 	;	32 bit block number at buffer header offset 4
 21916 00005DFF C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
 21917 00005E06 E8A3050000          <1> 	call 	diskio
 21918 00005E0B 731C                <1> 	jnc	short sysmnt_5
 21919 00005E0D 31C0                <1> 	xor 	eax, eax
 21920 00005E0F 66A3[6C740000]      <1> 	mov	[mnti], ax ; 0
 21921 00005E15 A2[69740000]        <1> 	mov	[mdev], al ; 0
 21922                              <1> 	;mov	[cdev], al ; 0
 21923                              <1> sysmnt_invd:
 21924                              <1> 	; 14/11/2015
 21925 00005E1A FEC8                <1> 	dec 	al
 21926 00005E1C 8903                <1> 	mov	[ebx], eax ; 000000FFh
 21927 00005E1E FEC0                <1> 	inc	al
 21928 00005E20 48                  <1> 	dec	eax
 21929 00005E21 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
 21930 00005E24 E953E2FFFF          <1> 	jmp	error
 21931                              <1> sysmnt_5:
 21932                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
 21933                              <1> 	; (Following check is needed to prevent mounting an
 21934                              <1> 	; in valid valid file system (in valid super block).
 21935                              <1> 	; 
 21936 00005E29 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
 21937 00005E2C C0E002              <1> 	shl	al, 2 ; 4*index
 21938 00005E2F 8B88[086E0000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
 21939 00005E35 C1E103              <1> 	shl 	ecx, 3
 21940 00005E38 0FB715[347F0000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
 21941 00005E3F 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
 21942                              <1> 			 ; (in sectors), if they are not equal
 21943                              <1> 			 ; the disk to be mounted is an...	
 21944 00005E41 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
 21945                              <1> 			 ; (which has not got a valid super block)
 21946                              <1> 	;
 21947 00005E43 C6430100            <1> 	mov	byte [ebx+1], 0
 21948                              <1> 	       	; jsr r0,ppoke / read in entire file system
 21949                              <1> ;sysmnt_6: ;1:
 21950                              <1> 	;;cmp	byte [sb1+1], 0
 21951                              <1> 		; tstb   sb1+1 / done reading?
 21952                              <1>    	;;jna	sysret
 21953                              <1> 	;;call	idle ; (wait for hardware interrupt)
 21954                              <1> 	;;jmp	short sysmnt_6
 21955                              <1> 		;bne 1b / no, wait
 21956                              <1>         	;br sysreta / yes
 21957 00005E47 E950E2FFFF          <1> 	jmp	sysret
 21958                              <1> 
 21959                              <1> sysumount: ; / special dismount file system
 21960                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 21961                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 21962                              <1> 	;
 21963                              <1> 	; 04/11/2013
 21964                              <1> 	; 09/07/2013
 21965                              <1> 	; 'sysumount' anounces to the system that the special file, 
 21966                              <1> 	; indicated as an argument is no longer contain a removable
 21967                              <1> 	; file system. 'getspl' gets the device number of the special
 21968                              <1> 	; file. If no file system was mounted on that device an error
 21969                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
 21970                              <1> 	; to 'sysret'.
 21971                              <1> 	;
 21972                              <1> 	; Calling sequence:
 21973                              <1> 	;	sysmount; special
 21974                              <1> 	; Arguments:
 21975                              <1> 	;	special - special file to dismount (device)
 21976                              <1> 	;
 21977                              <1> 	; Inputs: - 
 21978                              <1> 	; Outputs: -
 21979                              <1> 	; ...............................................................
 21980                              <1> 	;				
 21981                              <1> 	; Retro UNIX 8086 v1 modification: 
 21982                              <1> 	;       'sysumount' system call has one argument; so,
 21983                              <1> 	;	* Single argument, special is pointed to by BX register
 21984                              <1> 	;
 21985                              <1> 	
 21986                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
 21987                              <1> 	;call	arg
 21988                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
 21989 00005E4C 891D[98740000]      <1>         mov	[u.namep], ebx
 21990 00005E52 E829000000          <1> 	call	getspl
 21991                              <1> 		; jsr r0,getspl / get the device number in r1
 21992 00005E57 3A05[69740000]      <1> 	cmp	al, [mdev]
 21993                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
 21994 00005E5D 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
 21995                              <1> 	;jne	error
 21996                              <1>         	; bne errora / no error
 21997 00005E5F 30C0                <1> 	xor	al, al ; ah = 0
 21998                              <1> sysumnt_0: ;1:
 21999 00005E61 3805[317F0000]      <1>      	cmp 	[sb1+1], al ; 0
 22000                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
 22001                              <1> 			   ; / (inhibit bit set)?
 22002 00005E67 7607                <1> 	jna	short sysumnt_1		
 22003                              <1> 		; bne 1b / yes, wait
 22004 00005E69 E82DF6FFFF          <1> 	call	idle ; (wait for hardware interrupt)
 22005 00005E6E EBF1                <1> 	jmp	short sysumnt_0
 22006                              <1> sysumnt_1:        
 22007 00005E70 A2[69740000]        <1> 	mov	[mdev], al
 22008                              <1> 	     	; clr mntd / no, clear these
 22009 00005E75 66A3[6C740000]      <1>    	mov	[mnti], ax
 22010                              <1>         	; clr mnti
 22011 00005E7B E91CE2FFFF          <1>         jmp	sysret
 22012                              <1> 		; br sysreta / return
 22013                              <1> 
 22014                              <1> getspl: ; / get device number from a special file name
 22015 00005E80 E8B3F0FFFF          <1> 	call	namei
 22016                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 22017                              <1> 		       ; ax = 0 -> file not found 	
 22018 00005E85 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
 22019                              <1> 	;jz	error
 22020                              <1> 	;jc	error
 22021                              <1> 		; jsr r0,namei / get the i-number of the special file
 22022                              <1>                 ; br errora / no such file
 22023 00005E8B 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
 22024                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
 22025                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
 22026 00005E8F 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
 22027                              <1> 	;jc	error
 22028                              <1> 		; ble errora / less than 0?  yes, error
 22029 00005E91 6683F805            <1>         cmp	ax, 5 ;
 22030                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
 22031 00005E95 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
 22032                              <1> 	;ja	error
 22033                              <1>         	; bgt errora / yes, error
 22034                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
 22035                              <1> iopen_retn:
 22036 00005E97 C3                  <1> 	retn
 22037                              <1> 		; rts    r0 / return with device number in r1
 22038                              <1> sysmnt_err0:
 22039 00005E98 C705[D5740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 22040 00005EA0 0000                <1>
 22041 00005EA2 E9D5E1FFFF          <1> 	jmp	error
 22042                              <1> iopen:
 22043                              <1> 	; 19/05/2015
 22044                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 22045                              <1> 	; 21/05/2013 - 27/08/2013 (Retro UNIX 8086 v1)
 22046                              <1> 	;
 22047                              <1> 	; open file whose i-number is in r1
 22048                              <1> 	; 
 22049                              <1> 	; INPUTS ->
 22050                              <1> 	;    r1 - inode number
 22051                              <1> 	; OUTPUTS ->
 22052                              <1> 	;    file's inode in core	
 22053                              <1> 	;    r1 - inode number (positive)
 22054                              <1> 	;
 22055                              <1> 	; ((AX = R1))
 22056                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, edi, ebp)) 
 22057                              <1> 	;        
 22058                              <1> ; / open file whose i-number is in r1
 22059 00005EA7 F6C480              <1> 	test	ah, 80h ; Bit 15 of AX
 22060                              <1> 		;tst r1 / write or read access?
 22061 00005EAA 756A                <1>         jnz	short iopen_2
 22062                              <1> 		;blt 2f / write, go to 2f
 22063 00005EAC B202                <1> 	mov	dl, 2 ; read access
 22064 00005EAE E850F9FFFF          <1> 	call	access
 22065                              <1>         	; jsr r0,access; 2 
 22066                              <1> 	; / get inode into core with read access
 22067                              <1> 	; DL=2
 22068                              <1> iopen_0:
 22069 00005EB3 6683F828            <1>         cmp	ax, 40
 22070                              <1> 		; cmp r1,$40. / is it a special file
 22071 00005EB7 77DE                <1>         ja	short iopen_retn
 22072                              <1> 		;bgt  3f / no. 3f
 22073 00005EB9 6650                <1> 	push	ax
 22074                              <1> 		; mov r1,-(sp) / yes, figure out
 22075 00005EBB 0FB6D8              <1> 	movzx	ebx, al
 22076 00005EBE 66C1E302            <1> 	shl	bx, 2
 22077                              <1> 		; asl r1
 22078 00005EC2 81C3[C65E0000]      <1>         add     ebx, iopen_1 - 4
 22079 00005EC8 FF23                <1> 	jmp	dword [ebx]
 22080                              <1>         	; jmp *1f-2(r1) / which one and transfer to it
 22081                              <1> iopen_1: ; 1:
 22082 00005ECA [305F0000]          <1> 	dd	otty ; tty, AX = 1 (runix)
 22083                              <1>  		 ;otty / tty ; r1=2
 22084                              <1>         	 ;oppt / ppt ; r1=4
 22085 00005ECE [CD5F0000]          <1> 	dd	sret ; mem, AX = 2 (runix)
 22086                              <1> 		 ;sret / mem ; r1=6
 22087                              <1> 		 ;sret / rf0
 22088                              <1>         	 ;sret / rk0
 22089                              <1>         	 ;sret / tap0
 22090                              <1>         	 ;sret / tap1
 22091                              <1>         	 ;sret / tap2
 22092                              <1>         	 ;sret / tap3
 22093                              <1>         	 ;sret / tap4
 22094                              <1>         	 ;sret / tap5
 22095                              <1>         	 ;sret / tap6
 22096                              <1>         	 ;sret / tap7
 22097 00005ED2 [CD5F0000]          <1>         dd	sret ; fd0, AX = 3 (runix only)
 22098 00005ED6 [CD5F0000]          <1>         dd	sret ; fd1, AX = 4 (runix only)
 22099 00005EDA [CD5F0000]          <1>         dd	sret ; hd0, AX = 5 (runix only)
 22100 00005EDE [CD5F0000]          <1>         dd	sret ; hd1, AX = 6 (runix only) 
 22101 00005EE2 [CD5F0000]          <1>         dd	sret ; hd2, AX = 7 (runix only)
 22102 00005EE6 [CD5F0000]          <1>         dd	sret ; hd3, AX = 8 (runix only) 
 22103                              <1> 	;dd	error ; lpr, AX = 9 (error !)
 22104 00005EEA [CD5F0000]          <1>         dd      sret ; lpr, AX = 9 (runix)
 22105 00005EEE [3F5F0000]          <1> 	dd	ocvt ; tty0, AX = 10 (runix)	  
 22106                              <1> 		 ;ocvt / tty0
 22107 00005EF2 [3F5F0000]          <1> 	dd	ocvt ; tty1, AX = 11 (runix)	  
 22108                              <1> 		 ;ocvt / tty1
 22109 00005EF6 [3F5F0000]          <1> 	dd	ocvt ; tty2, AX = 12 (runix)	  
 22110                              <1> 		 ;ocvt / tty2
 22111 00005EFA [3F5F0000]          <1> 	dd	ocvt ; tty3, AX = 13 (runix)	  
 22112                              <1> 		 ;ocvt / tty3
 22113 00005EFE [3F5F0000]          <1> 	dd	ocvt ; tty4, AX = 14 (runix)	  
 22114                              <1> 		 ;ocvt / tty4
 22115 00005F02 [3F5F0000]          <1> 	dd	ocvt ; tty5, AX = 15 (runix)	  
 22116                              <1> 		 ;ocvt / tty5
 22117 00005F06 [3F5F0000]          <1> 	dd	ocvt ; tty6, AX = 16 (runix)	  
 22118                              <1> 		 ;ocvt / tty6
 22119 00005F0A [3F5F0000]          <1> 	dd	ocvt ; tty7, AX = 17 (runix)	  
 22120                              <1> 		 ;ocvt / tty7
 22121 00005F0E [3F5F0000]          <1> 	dd	ocvt ; COM1, AX = 18 (runix only)	  
 22122                              <1> 		 ;error / crd
 22123 00005F12 [3F5F0000]          <1> 	dd	ocvt ; COM2, AX = 19 (runix only)
 22124                              <1> 
 22125                              <1> iopen_2: ; 2: / check open write access
 22126 00005F16 66F7D8              <1> 	neg	ax
 22127                              <1> 		;neg r1 / make inode number positive
 22128 00005F19 B201                <1> 	mov	dl, 1 ; write access
 22129 00005F1B E8E3F8FFFF          <1> 	call	access
 22130                              <1> 		;jsr r0,access; 1 / get inode in core
 22131                              <1> 	; DL=1
 22132 00005F20 66F705[56710000]00- <1> 	test	word [i.flgs], 4000h ; Bit 14 : Directory flag
 22133 00005F28 40                  <1>
 22134                              <1>  		;bit $40000,i.flgs / is it a directory?
 22135 00005F29 7488                <1> 	jz	short iopen_0
 22136                              <1> 	;mov	[u.error], ERR_DIR_ACCESS
 22137                              <1> 	;jmp	error ; permission denied !
 22138 00005F2B E968FFFFFF          <1> 	jmp	sysmnt_err0
 22139                              <1> 	;;jnz	error		
 22140                              <1>        		; bne 2f / yes, transfer (error)
 22141                              <1>         ;;jmp     short iopen_0
 22142                              <1> 	;cmp	ax, 40
 22143                              <1> 		; cmp r1,$40. / no, is it a special file?
 22144                              <1>         ;ja	short iopen_2
 22145                              <1> 		 ;bgt 3f / no, return
 22146                              <1> 	;push	ax
 22147                              <1> 		;mov r1,-(sp) / yes
 22148                              <1> 	;movzx	ebx, al
 22149                              <1> 	;shl	bx, 1
 22150                              <1> 		; asl r1
 22151                              <1> 	;add	ebx, ipen_3 - 2
 22152                              <1> 	;jmp	dword [ebx]
 22153                              <1> 		; jmp *1f-2(r1) / figure out 
 22154                              <1> 			; / which special file it is and transfer
 22155                              <1> ;iopen_3: ; 1:
 22156                              <1> ;	dd 	otty ; tty, AX = 1 (runix)
 22157                              <1>  		 ;otty / tty ; r1=2
 22158                              <1>         	 ;leadr / ppt ; r1=4
 22159                              <1> ;	dd	sret ; mem, AX = 2 (runix)
 22160                              <1> 		 ;sret / mem ; r1=6
 22161                              <1> 		 ;sret / rf0
 22162                              <1>         	 ;sret / rk0
 22163                              <1>         	 ;sret / tap0
 22164                              <1>         	 ;sret / tap1
 22165                              <1>         	 ;sret / tap2
 22166                              <1>         	 ;sret / tap3
 22167                              <1>         	 ;sret / tap4
 22168                              <1>         	 ;sret / tap5
 22169                              <1>         	 ;sret / tap6
 22170                              <1>         	 ;sret / tap7
 22171                              <1> ;	dd 	sret ; fd0, AX = 3 (runix only)
 22172                              <1> ;	dd 	sret ; fd1, AX = 4 (runix only)
 22173                              <1> ;	dd 	sret ; hd0, AX = 5 (runix only)
 22174                              <1> ;	dd 	sret ; hd1, AX = 6 (runix only)	
 22175                              <1> ;	dd 	sret ; hd2, AX = 7 (runix only)
 22176                              <1> ;	dd 	sret ; hd3, AX = 8 (runix only)	
 22177                              <1> ;	dd	sret ; lpr, AX = 9  (runix)
 22178                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 22179                              <1> ;	dd	sret ; tty0, AX = 10 (runix)	  
 22180                              <1> 		 ;ocvt / tty0
 22181                              <1> ;	dd	sret ; tty1, AX = 11 (runix)	  
 22182                              <1> 		 ;ocvt / tty1
 22183                              <1> ;	dd	sret ; tty2, AX = 12 (runix)	  
 22184                              <1> 		 ;ocvt / tty2
 22185                              <1> ;	dd	sret ; tty3, AX = 13 (runix)	  
 22186                              <1> 		 ;ocvt / tty3
 22187                              <1> ;	dd	sret ; tty4, AX = 14 (runix)	  
 22188                              <1> 		 ;ocvt / tty4
 22189                              <1> ;	dd	sret ; tty5, AX = 15 (runix)	  
 22190                              <1> 		 ;ocvt / tty5
 22191                              <1> ;	dd	sret ; tty6, AX = 16 (runix)	  
 22192                              <1> 		 ;ocvt / tty6
 22193                              <1> ;	dd	sret ; tty7, AX = 17 (runix)	  
 22194                              <1> 		 ;ocvt / tty7
 22195                              <1> ;	dd	ocvt ; COM1, AX = 18 (runix only)	  
 22196                              <1> 		 ;/ ejec / lpr
 22197                              <1> ;	dd	ocvt ; COM2, AX = 19 (runix only)
 22198                              <1> 
 22199                              <1> 
 22200                              <1> otty: ;/ open console tty for reading or writing
 22201                              <1> 	; 16/11/2015
 22202                              <1> 	; 12/11/2015
 22203                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 22204                              <1> 	; 21/05/2013 - 13/07/2014 (Retro UNIX 8086 v1)
 22205                              <1> 	; 16/07/2013
 22206                              <1> 	; Retro UNIX 8086 v1 modification:
 22207                              <1> 	;  If a tty is open for read or write by
 22208                              <1> 	;     a process (u.uno), only same process can open
 22209                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 22210                              <1> 	;
 22211                              <1> 	; (INPUT: DL=2 for Read, DL=1 for Write, DL=0 for sysstty)
 22212                              <1> 	;
 22213 00005F30 0FB61D[CF740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 22214 00005F37 8A83[D5710000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 22215                              <1> 	; 13/01/2014
 22216 00005F3D EB02                <1> 	jmp	short ottyp
 22217                              <1> ocvt:
 22218 00005F3F 2C0A                <1> 	sub	al, 10
 22219                              <1> ottyp:
 22220                              <1> 	; 16/11/2015
 22221                              <1> 	; 12/11/2015
 22222                              <1> 	; 18/05/2015 (32 bit modifications)
 22223                              <1> 	; 06/12/2013 - 13/07/2014
 22224 00005F41 88C6                <1> 	mov	dh, al ; tty number
 22225 00005F43 0FB6D8              <1> 	movzx 	ebx, al ; AL = tty number (0 to 9), AH = 0
 22226 00005F46 D0E3                <1> 	shl 	bl, 1  ; aligned to word
 22227                              <1> 	;26/01/2014	
 22228 00005F48 81C3[F4700000]      <1> 	add 	ebx, ttyl
 22229 00005F4E 668B0B              <1> 	mov 	cx, [ebx]
 22230                              <1> 		   ; CL = lock value (0 or process number)
 22231                              <1> 		   ; CH = open count 
 22232 00005F51 20C9                <1> 	and 	cl, cl
 22233                              <1> 	; 13/01/2014
 22234 00005F53 7439                <1> 	jz 	short otty_ret
 22235                              <1> 	;
 22236                              <1> 	; 16/11/2015
 22237 00005F55 3A0D[CF740000]      <1> 	cmp 	cl, [u.uno]
 22238 00005F5B 745C                <1> 	je	short ottys_3
 22239                              <1> 	;
 22240 00005F5D 0FB6D9              <1> 	movzx 	ebx, cl ; the process which has locked the tty
 22241 00005F60 D0E3                <1> 	shl 	bl, 1
 22242 00005F62 668B83[74710000]    <1> 	mov 	ax, [ebx+p.pid-2]
 22243                              <1> 	;movzx 	ebx, byte [u.uno]
 22244 00005F69 8A1D[CF740000]      <1> 	mov	bl, [u.uno]
 22245 00005F6F D0E3                <1> 	shl 	bl, 1
 22246 00005F71 663B83[94710000]    <1> 	cmp 	ax, [ebx+p.ppid-2]
 22247 00005F78 743F                <1> 	je 	short ottys_3  ; 16/11/2015
 22248                              <1> 	;
 22249                              <1> 	; the tty is locked by another process
 22250                              <1> 	; except the parent process (p.ppid)
 22251                              <1>         ;
 22252 00005F7A C705[D5740000]0B00- <1> 	mov     dword [u.error], ERR_DEV_ACCESS
 22253 00005F82 0000                <1>
 22254                              <1> 			; permission denied ! error
 22255                              <1> otty_err: ; 13/01/2014
 22256 00005F84 08D2                <1> 	or 	dl, dl ; DL = 0 -> called by sysstty
 22257 00005F86 0F85F0E0FFFF        <1> 	jnz	error
 22258 00005F8C F9                  <1> 	stc
 22259 00005F8D C3                  <1> 	retn
 22260                              <1> otty_ret: 
 22261                              <1> 	; 13/01/2014
 22262 00005F8E 80FE07              <1> 	cmp 	dh, 7
 22263 00005F91 761C                <1> 	jna	short ottys_2
 22264                              <1> 	; 16/11/2015
 22265                              <1> com_port_check:
 22266 00005F93 BE[12710000]        <1> 	mov	esi, com1p
 22267 00005F98 80FE08              <1> 	cmp	dh, 8	; COM1 (tty8) ?
 22268 00005F9B 7601                <1> 	jna	short ottys_1 ; yes, it is COM1
 22269 00005F9D 46                  <1> 	inc	esi	; no, it is COM2 (tty9)
 22270                              <1> ottys_1:
 22271                              <1> 	; 12/11/2015
 22272 00005F9E 803E00              <1> 	cmp	byte [esi], 0 ; E3h (or 23h)
 22273 00005FA1 770C                <1> 	ja	short com_port_ready
 22274                              <1> 	;
 22275 00005FA3 C705[D5740000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY
 22276 00005FAB 0000                <1>
 22277                              <1> 			   ; device not ready ! error
 22278 00005FAD EBD5                <1> 	jmp	short otty_err	 
 22279                              <1> com_port_ready:
 22280                              <1> ottys_2:
 22281 00005FAF 08C9                <1> 	or	cl, cl  ; cl = lock/owner, ch = open count
 22282 00005FB1 7506                <1> 	jnz	short ottys_3
 22283 00005FB3 8A0D[CF740000]      <1> 	mov	cl, [u.uno]
 22284                              <1> ottys_3:
 22285 00005FB9 FEC5                <1> 	inc 	ch
 22286 00005FBB 66890B              <1> 	mov 	[ebx], cx ; set tty lock again
 22287                              <1> 	; 06/12/2013
 22288 00005FBE FEC6                <1> 	inc	dh ; tty number + 1
 22289 00005FC0 BB[B0740000]        <1> 	mov	ebx, u.ttyp
 22290                              <1> 	; 13/01/2014
 22291 00005FC5 F6C202              <1> 	test	dl, 2 ; open for read sign
 22292 00005FC8 7501                <1> 	jnz	short ottys_4
 22293 00005FCA 43                  <1> 	inc	ebx
 22294                              <1> ottys_4:
 22295                              <1> 	; Set 'u.ttyp' ('the recent TTY') value
 22296 00005FCB 8833                <1> 	mov 	[ebx], dh ; tty number + 1
 22297                              <1> sret:
 22298 00005FCD 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 22299 00005FCF 7402                <1> 	jz	short iclose_retn
 22300 00005FD1 6658                <1> 	pop 	ax
 22301                              <1> iclose_retn:	
 22302 00005FD3 C3                  <1> 	retn
 22303                              <1> 
 22304                              <1> 	;
 22305                              <1> 	; Original UNIX v1 'otty' routine:
 22306                              <1> 	;	
 22307                              <1> 	;mov    $100,*$tks / set interrupt enable bit (zero others) in
 22308                              <1>         ;                 / reader status reg
 22309                              <1>         ;mov    $100,*$tps / set interrupt enable bit (zero others) in
 22310                              <1>         ;                 / punch status reg
 22311                              <1>         ;mov    tty+[ntty*8]-8+6,r5 / r5 points to the header of the
 22312                              <1>         ;                          / console tty buffer
 22313                              <1>         ;incb   (r5) / increment the count of processes that opened the
 22314                              <1>         ;            / console tty
 22315                              <1>         ;tst    u.ttyp / is there a process control tty (i.e., has a tty
 22316                              <1>         ;             / buffer header
 22317                              <1>         ;bne    sret / address been loaded into u.ttyp yet)?  yes, branch
 22318                              <1>         ;mov    r5,u.ttyp / no, make the console tty the process control
 22319                              <1>         ;                 / tty
 22320                              <1>         ;br     sret / ?
 22321                              <1> ;sret:
 22322                              <1> 		;clr *$ps / set processor priority to zero
 22323                              <1> ;	pop	ax
 22324                              <1>         	;mov (sp)+,r1 / pop stack to r1
 22325                              <1> ;3:
 22326                              <1> ;	retn
 22327                              <1>         	;rts r0
 22328                              <1> 	
 22329                              <1> ;ocvt:	; < open tty >
 22330                              <1> 	; 13/01/2014
 22331                              <1> 	; 06/12/2013 (major modification: p.ttyc, u.ttyp)
 22332                              <1> 	; 24/09/2013 consistency check -> ok
 22333                              <1> 	; 16/09/2013
 22334                              <1> 	; 03/09/2013
 22335                              <1> 	; 27/08/2013
 22336                              <1> 	; 16/08/2013
 22337                              <1> 	; 16/07/2013
 22338                              <1> 	; 27/05/2013
 22339                              <1> 	; 21/05/2013
 22340                              <1> 	;
 22341                              <1> 	; Retro UNIX 8086 v1 modification !
 22342                              <1> 	; 
 22343                              <1> 	; In original UNIX v1, 'ocvt' routine 
 22344                              <1> 	;		(exactly different than this one)
 22345                              <1> 	;	was in 'u9.s' file.
 22346                              <1> 	;
 22347                              <1> 	; 16/07/2013
 22348                              <1> 	; Retro UNIX 8086 v1 modification:
 22349                              <1> 	;  If a tty is open for read or write by
 22350                              <1> 	;     a process (u.uno), only same process can open
 22351                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 22352                              <1> 	;
 22353                              <1> 	; INPUT: DL=2 for Read DL=1 for Write
 22354                              <1> 
 22355                              <1> 	; 16/09/2013
 22356                              <1> 	; sub 	al, 10
 22357                              <1> 	
 22358                              <1> 	; 06/12/2013
 22359                              <1> 	;cmp	al, 7
 22360                              <1>         ;jna     short ottyp
 22361                              <1> 	; 13/01/2014
 22362                              <1> 	;jmp	short ottyp
 22363                              <1> 
 22364                              <1> 
 22365                              <1> ;oppt: / open paper tape for reading or writing
 22366                              <1> ;        mov    $100,*$prs / set reader interrupt enable bit
 22367                              <1> ;        tstb   pptiflg / is file already open
 22368                              <1> ;        bne    2f / yes, branch
 22369                              <1> ;1:
 22370                              <1> ;        mov    $240,*$ps / no, set processor priority to 5
 22371                              <1> ;        jsr    r0,getc; 2 / remove all entries in clist
 22372                              <1> ;               br .+4 / for paper tape input and place in free list
 22373                              <1> ;        br     1b
 22374                              <1> ;        movb   $2,pptiflg / set pptiflg to indicate file just open
 22375                              <1> ;        movb   $10.,toutt+1 / place 10 in paper tape input tout entry
 22376                              <1> ;        br     sret
 22377                              <1> ;2:
 22378                              <1> ;        jmp    error / file already open
 22379                              <1> 
 22380                              <1> iclose: 
 22381                              <1> 	; 19/05/2015
 22382                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 22383                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 22384                              <1> 	;
 22385                              <1> 	; close file whose i-number is in r1
 22386                              <1> 	; 
 22387                              <1> 	; INPUTS ->
 22388                              <1> 	;    r1 - inode number
 22389                              <1> 	; OUTPUTS ->
 22390                              <1> 	;    file's inode in core	
 22391                              <1> 	;    r1 - inode number (positive)
 22392                              <1> 	;
 22393                              <1> 	; ((AX = R1))
 22394                              <1>         ;    ((Modified registers: -ebx-, edx)) 
 22395                              <1> 	;        
 22396                              <1> ;/ close file whose i-number is in r1
 22397 00005FD4 B202                <1> 	mov	dl, 2 ; 12/01/2014
 22398 00005FD6 F6C480              <1> 	test	ah, 80h ; Bit 15 of AX
 22399                              <1> 		;tst r1 / test i-number
 22400                              <1>         ;jnz	short iclose_2
 22401                              <1> 		;blt 2f / if neg., branch
 22402 00005FD9 7405                <1> 	jz	short iclose_0 ; 30/07/2013
 22403                              <1> 	; 16/07/2013 
 22404 00005FDB 66F7D8              <1> 	neg	ax ; make it positive
 22405                              <1> 	; 12/01/2014
 22406 00005FDE FECA                <1> 	dec	dl ; dl = 1 (open for write)
 22407                              <1> iclose_0:
 22408 00005FE0 6683F828            <1> 	cmp	ax, 40
 22409                              <1> 		;cmp r1,$40. / is it a special file
 22410 00005FE4 77ED                <1>         ja	short iclose_retn  ; 13/01/2014
 22411                              <1> 		;bgt 3b / no, return
 22412                              <1> 	; 12/01/2014
 22413                              <1> 	; DL=2 -> special file was opened for reading
 22414                              <1> 	; DL=1 -> special file was opened for writing
 22415 00005FE6 6650                <1> 	push	ax
 22416                              <1> 		;mov r1,-(sp) / yes, save r1 on stack
 22417 00005FE8 0FB6D8              <1> 	movzx	ebx, al
 22418 00005FEB 66C1E302            <1> 	shl	bx, 2
 22419                              <1> 		; asl r1
 22420 00005FEF 81C3[F35F0000]      <1> 	add	ebx, iclose_1 - 4
 22421 00005FF5 FF23                <1> 	jmp	dword [ebx]
 22422                              <1> 		; jmp *1f-2(r1) / compute jump address and transfer
 22423                              <1> iclose_1 :
 22424 00005FF7 [43600000]          <1> 	dd	ctty ; tty, AX = 1 (runix)
 22425 00005FFB [94600000]          <1> 	dd	cret ; mem, AX = 2 (runix)
 22426 00005FFF [94600000]          <1> 	dd	cret ; fd0, AX = 3 (runix only)
 22427 00006003 [94600000]          <1> 	dd	cret ; fd1, AX = 4 (runix only)
 22428 00006007 [94600000]          <1> 	dd	cret ; hd0, AX = 5 (runix only)
 22429 0000600B [94600000]          <1> 	dd	cret ; hd1, AX = 6 (runix only)	
 22430 0000600F [94600000]          <1> 	dd	cret ; hd2, AX = 7 (runix only)
 22431 00006013 [94600000]          <1> 	dd	cret ; hd3, AX = 8 (runix only)	
 22432 00006017 [94600000]          <1> 	dd	cret ; lpr, AX = 9 (runix)
 22433                              <1> 	;dd	error; lpr, AX = 9 (error !)
 22434                              <1> 	;;dd	offset ejec ;;lpr, AX = 9  
 22435 0000601B [52600000]          <1> 	dd	ccvt ; tty0, AX = 10 (runix)	  
 22436 0000601F [52600000]          <1> 	dd	ccvt ; tty1, AX = 11 (runix)	  
 22437 00006023 [52600000]          <1> 	dd	ccvt ; tty2, AX = 12 (runix)	  
 22438 00006027 [52600000]          <1> 	dd	ccvt ; tty3, AX = 13 (runix)	  
 22439 0000602B [52600000]          <1> 	dd	ccvt ; tty4, AX = 14 (runix)	  
 22440 0000602F [52600000]          <1> 	dd	ccvt ; tty5, AX = 15 (runix)	  
 22441 00006033 [52600000]          <1> 	dd	ccvt ; tty6, AX = 16 (runix)	  
 22442 00006037 [52600000]          <1> 	dd	ccvt ; tty7, AX = 17 (runix)	  
 22443 0000603B [52600000]          <1> 	dd	ccvt ; COM1, AX = 18 (runix only)	  
 22444 0000603F [52600000]          <1> 	dd	ccvt ; COM2, AX = 19 (runix only)
 22445                              <1> 
 22446                              <1> 	; 1:
 22447                              <1> 	;        ctty   / tty
 22448                              <1> 	;        cppt   / ppt
 22449                              <1> 	;        sret   / mem
 22450                              <1> 	;        sret   / rf0
 22451                              <1> 	;        sret   / rk0
 22452                              <1> 	;        sret   / tap0
 22453                              <1> 	;        sret   / tap1
 22454                              <1> 	;        sret   / tap2
 22455                              <1> 	;        sret   / tap3
 22456                              <1> 	;        sret   / tap4
 22457                              <1> 	;        sret   / tap5
 22458                              <1> 	;        sret   / tap6
 22459                              <1> 	;        sret   / tap7
 22460                              <1> 	;        ccvt   / tty0
 22461                              <1> 	;        ccvt   / tty1
 22462                              <1> 	;        ccvt   / tty2
 22463                              <1> 	;        ccvt   / tty3
 22464                              <1> 	;        ccvt   / tty4
 22465                              <1> 	;        ccvt   / tty5
 22466                              <1> 	;        ccvt   / tty6
 22467                              <1> 	;        ccvt   / tty7
 22468                              <1> 	;        error / crd
 22469                              <1> 
 22470                              <1> ;iclose_2: ; 2: / negative i-number
 22471                              <1> 	;neg	ax
 22472                              <1> 		;neg r1 / make it positive
 22473                              <1> 	;cmp	ax, 40
 22474                              <1> 		;cmp r1,$40. / is it a special file?
 22475                              <1>         ;ja	short @b
 22476                              <1> 		;bgt    3b / no. return
 22477                              <1> 	;push	ax
 22478                              <1> 		;mov r1,-(sp)
 22479                              <1> 	;movzx	ebx, al
 22480                              <1> 	;shl	bx, 1
 22481                              <1> 		;asl r1 / yes. compute jump address and transfer
 22482                              <1> 	;add	ebx, iclose_3 - 2
 22483                              <1> 	;jmp	dword [ebx]
 22484                              <1> 		;jmp *1f-2(r1) / figure out 
 22485                              <1> ;iclose_3:
 22486                              <1> 	;dd	ctty ; tty, AX = 1 (runix)
 22487                              <1> 	;dd	sret ; mem, AX = 2 (runix)
 22488                              <1> 	;dd	sret ; fd0, AX = 3 (runix only)
 22489                              <1> 	;dd	sret ; fd1, AX = 4 (runix only)
 22490                              <1> 	;dd	sret ; hd0, AX = 5 (runix only)
 22491                              <1> 	;dd	sret ; hd1, AX = 6 (runix only)	
 22492                              <1> 	;dd	sret ; hd2, AX = 7 (runix only)
 22493                              <1> 	;dd	sret ; hd3, AX = 8 (runix only)
 22494                              <1> 	 ;dd	sret ; lpr, AX = 9	
 22495                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 22496                              <1> 	;dd	ccvt ; tty0, AX = 10 (runix)	  
 22497                              <1> 	;dd	ccvt ; tty1, AX = 11 (runix)	  
 22498                              <1> 	;dd	ccvt ; tty2, AX = 12 (runix)	  
 22499                              <1> 	;dd	ccvt ; tty3, AX = 13 (runix)	  
 22500                              <1> 	;dd	ccvt ; tty4, AX = 14 (runix)	  
 22501                              <1> 	;dd	ccvt ; tty5, AX = 15 (runix)	  
 22502                              <1> 	;dd	ccvt ; tty6, AX = 16 (runix)	  
 22503                              <1> 	;dd	ccvt ; tty7, AX = 17 (runix)	  
 22504                              <1> 	;dd	ccvt ; COM1, AX = 18 (runix only)	  
 22505                              <1> 	;dd	ccvt ; COM2, AX = 19 (runix only) 
 22506                              <1> 	
 22507                              <1> 	;1:
 22508                              <1> 	;      	ctty   / tty
 22509                              <1> 	;       leadr  / ppt
 22510                              <1> 	;       sret   / mem
 22511                              <1> 	;       sret   / rf0
 22512                              <1> 	;       sret   / rk0
 22513                              <1> 	;       sret   / tap0
 22514                              <1> 	;       sret   / tap1
 22515                              <1> 	;       sret   / tap2
 22516                              <1> 	;       sret   / tap3
 22517                              <1> 	;       sret   / tap4
 22518                              <1> 	;       sret   / tap5
 22519                              <1> 	;       sret   / tap6
 22520                              <1> 	;       sret   / tap7
 22521                              <1> 	;       ccvt   / tty0
 22522                              <1> 	;       ccvt   / tty1
 22523                              <1> 	;       ccvt   / tty2
 22524                              <1> 	;       ccvt   / tty3
 22525                              <1> 	;       ccvt   / tty4
 22526                              <1> 	;       ccvt   / tty5
 22527                              <1> 	;       ccvt   / tty6
 22528                              <1> 	;       ccvt   / tty7
 22529                              <1> 	;/       ejec / lpr
 22530                              <1> 
 22531                              <1> ctty: ; / close console tty
 22532                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 22533                              <1> 	; 21/05/2013 - 26/01/2014 (Retro UNIX 8086 v1)
 22534                              <1> 	;
 22535                              <1> 	; Retro UNIX 8086 v1 modification !
 22536                              <1> 	; (DL = 2 -> it is open for reading)
 22537                              <1> 	; (DL = 1 -> it is open for writing)
 22538                              <1> 	; (DL = 0 -> it is open for sysstty system call)
 22539                              <1> 	;
 22540                              <1> 	; 06/12/2013
 22541 00006043 0FB61D[CF740000]    <1>         movzx   ebx, byte [u.uno] ; process number
 22542 0000604A 8A83[D5710000]      <1>         mov     al, [ebx+p.ttyc-1]
 22543                              <1> 	; 13/01/2014
 22544 00006050 EB02                <1> 	jmp	short cttyp
 22545                              <1> ccvt:
 22546 00006052 2C0A                <1> 	sub 	al, 10
 22547                              <1> cttyp:	
 22548                              <1> 	; 18/05/2015 (32 bit modifications)
 22549                              <1> 	; 16/08/2013 - 26/01/2014
 22550 00006054 0FB6D8              <1> 	movzx 	ebx, al ; tty number (0 to 9)
 22551 00006057 D0E3                <1> 	shl 	bl, 1  ; aligned to word	
 22552                              <1> 	; 26/01/2014
 22553 00006059 81C3[F4700000]      <1> 	add 	ebx, ttyl
 22554 0000605F 88C6                <1> 	mov 	dh, al ; tty number
 22555 00006061 668B03              <1> 	mov 	ax, [ebx]
 22556                              <1> 		   ; AL = lock value (0 or process number)
 22557                              <1> 		   ; AH = open count 
 22558 00006064 20E4                <1> 	and 	ah, ah
 22559 00006066 750F                <1> 	jnz	short ctty_ret
 22560 00006068 C705[D5740000]0A00- <1>         mov     dword [u.error], ERR_DEV_NOT_OPEN
 22561 00006070 0000                <1>
 22562                              <1> 			; device not open ! error
 22563                              <1> 	;jmp 	short ctty_err ; open count = 0, it is not open !
 22564 00006072 E905E0FFFF          <1> 	jmp	error
 22565                              <1> 	; 26/01/2014
 22566                              <1> ctty_ret:
 22567 00006077 FECC                <1> 	dec 	ah ; decrease open count
 22568 00006079 7502                <1> 	jnz	short ctty_1
 22569 0000607B 30C0                <1> 	xor	al, al ; unlock/free tty
 22570                              <1> ctty_1:
 22571 0000607D 668903              <1> 	mov 	[ebx], ax ; close tty instance
 22572                              <1> 	;
 22573 00006080 BB[B0740000]        <1> 	mov	ebx, u.ttyp
 22574 00006085 F6C201              <1> 	test	dl, 1 ; open for write sign
 22575 00006088 7401                <1> 	jz	short ctty_2
 22576 0000608A 43                  <1> 	inc	ebx
 22577                              <1> ctty_2:
 22578 0000608B FEC6                <1> 	inc	dh ; tty number + 1
 22579 0000608D 3A33                <1> 	cmp	dh, [ebx]
 22580 0000608F 7503                <1> 	jne	short cret
 22581                              <1> 	; Reset/Clear 'u.ttyp' ('the recent TTY') value
 22582 00006091 C60300              <1> 	mov	byte [ebx], 0
 22583                              <1> cret:
 22584 00006094 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 22585 00006096 7402                <1> 	jz	short ctty_3
 22586 00006098 6658                <1> 	pop	ax
 22587                              <1> ctty_3:
 22588 0000609A C3                  <1> 	retn
 22589                              <1> 
 22590                              <1> ;ctty_err: ; 13/01/2014
 22591                              <1> ;	or 	dl, dl ; DL = 0 -> called by sysstty
 22592                              <1> ;	jnz	error
 22593                              <1> ;	stc
 22594                              <1> ;	retn
 22595                              <1> 
 22596                              <1> 
 22597                              <1> 	; Original UNIX v1 'ctty' routine:
 22598                              <1> 	;	
 22599                              <1>         ;mov    tty+[ntty*8]-8+6,r5 
 22600                              <1> 	;		;/ point r5 to the console tty buffer
 22601                              <1>         ;decb   (r5) / dec number of processes using console tty
 22602                              <1>         ;br     sret / return via sret
 22603                              <1> 
 22604                              <1> ;ccvt:	; < close tty >
 22605                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 22606                              <1> 	;
 22607                              <1> 	; Retro UNIX 8086 v1 modification !
 22608                              <1> 	; 
 22609                              <1> 	; In original UNIX v1, 'ccvt' routine 
 22610                              <1> 	;		(exactly different than this one)
 22611                              <1> 	;	was in 'u9.s' file.
 22612                              <1> 	;
 22613                              <1> 	; DL = 2 -> it is open for reading
 22614                              <1> 	; DL = 1 -> it is open for writing
 22615                              <1> 	;
 22616                              <1> 	; 17/09/2013
 22617                              <1> 	;sub 	al, 10
 22618                              <1> 	;cmp	al, 7
 22619                              <1> 	;jna	short cttyp
 22620                              <1> 	; 13/01/2014
 22621                              <1> 	;jmp	short cttyp
 22622                              <1> 
 22623                              <1> ;cppt: / close paper tape
 22624                              <1> ;        clrb   pptiflg / set pptiflg to indicate file not open
 22625                              <1> ;1:
 22626                              <1> ;        mov    $240,*$ps /set process or priority to 5
 22627                              <1> ;        jsr    r0,getc; 2 / remove all ppt input entries from clist
 22628                              <1> ;                          / and assign to free list
 22629                              <1> ;               br sret
 22630                              <1> ;        br     1b
 22631                              <1> 
 22632                              <1> ;ejec:	
 22633                              <1> ;	jmp	error
 22634                              <1> ;/ejec:
 22635                              <1> ;/       mov    $100,*$lps / set line printer interrupt enable bit
 22636                              <1> ;/       mov    $14,r1 / 'form feed' character in r1 (new page).
 22637                              <1> ;/       jsr    r0,lptoc / space the printer to a new page
 22638                              <1> ;/       br     sret / return to caller via 'sret'
 22639                                  %include 'u8.s'        ; 11/06/2015
 22640                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS8.INC
 22641                              <1> ; Last Modification: 24/10/2015
 22642                              <1> ; ----------------------------------------------------------------------------
 22643                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 22644                              <1> ; (v0.1 - Beginning: 11/07/2012)
 22645                              <1> ;
 22646                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 22647                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 22648                              <1> ; <Bell Laboratories (17/3/1972)>
 22649                              <1> ; <Preliminary Release of UNIX Implementation Document>
 22650                              <1> ;
 22651                              <1> ; Retro UNIX 8086 v1 - U8.ASM (18/01/2014) //// UNIX v1 -> u8.s
 22652                              <1> ;
 22653                              <1> ; ****************************************************************************
 22654                              <1> 
 22655                              <1> ;; I/O Buffer - Retro UNIX 386 v1 modification
 22656                              <1> ;;     (8+512 bytes, 8 bytes header, 512 bytes data)
 22657                              <1> ;; Word 1, byte 0 = device id
 22658                              <1> ;; Word 1, byte 1 = status bits (bits 8 to 15)
 22659                              <1> ;;          bit 9 = write bit
 22660                              <1> ;;	    bit 10 = read bit	  
 22661                              <1> ;;	    bit 12 = waiting to write bit	
 22662                              <1> ;;	    bit 13 = waiting to read bit
 22663                              <1> ;;	    bit 15 = inhibit bit
 22664                              <1> ;; Word 2 (byte 2 & byte 3) = reserved (for now - 07/06/2015)
 22665                              <1> ;; Word 3 + Word 4 (byte 4,5,6,7) = physical block number 
 22666                              <1> ;;		   (In fact, it is 32 bit LBA for Retro UNIX 386 v1)
 22667                              <1> ;;
 22668                              <1> ;; I/O Buffer ((8+512 bytes in original Unix v1))
 22669                              <1> ;;	      ((4+512 bytes in Retro UNIX 8086 v1))
 22670                              <1> ;;
 22671                              <1> ;; I/O Queue Entry (of original UNIX operating system v1)
 22672                              <1> ;; Word 1, Byte 0 = device id
 22673                              <1> ;; Word 1, Byte 1 = (bits 8 to 15)
 22674                              <1> ;;          bit 9 = write bit
 22675                              <1> ;;	    bit 10 = read bit	  
 22676                              <1> ;;	    bit 12 = waiting to write bit	
 22677                              <1> ;;	    bit 13 = waiting to read bit
 22678                              <1> ;;	    bit 15 = inhibit bit
 22679                              <1> ;; Word 2 = physical block number (In fact, it is LBA for Retro UNIX 8086 v1)
 22680                              <1> ;;
 22681                              <1> ;; Original UNIX v1 ->
 22682                              <1> ;;		Word 3 = number of words in buffer (=256) 		
 22683                              <1> ;; Original UNIX v1 -> 
 22684                              <1> ;;		Word 4 = bus address (addr of first word of data buffer)
 22685                              <1> ;;
 22686                              <1> ;; Retro UNIX 8086 v1 -> Buffer Header (I/O Queue Entry) size is 4 bytes !
 22687                              <1> ;;
 22688                              <1> ;; Device IDs (of Retro Unix 8086 v1)
 22689                              <1> ;;          0 = fd0
 22690                              <1> ;;	    1 = fd1
 22691                              <1> ;;	    2 = hd0
 22692                              <1> ;;	    3 = hd1
 22693                              <1> ;;	    4 = hd2
 22694                              <1> ;;	    5 = hd3
 22695                              <1> 
 22696                              <1> ; Retro UNIX 386 v1 - 32 bit modifications (rfd, wfd, rhd, whd) - 09/06/2015
 22697                              <1> 
 22698                              <1> rfd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22699                              <1> 	; 26/04/2013
 22700                              <1>    	; 13/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 22701                              <1>    	;sub 	ax, 3 ; zero based device number (Floppy disk)
 22702                              <1>       	;jmp 	short bread ; **** returns to routine that called readi			
 22703                              <1> 
 22704                              <1> rhd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22705                              <1> 	; 26/04/2013
 22706                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 22707                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 22708                              <1>    	;jmp	short bread ; **** returns to routine that called readi	
 22709                              <1> 
 22710                              <1> bread: 
 22711                              <1> 	; 14/07/2015
 22712                              <1> 	; 10/07/2015
 22713                              <1> 	; 09/06/2015
 22714                              <1> 	; 07/06/2015 (Retro UNIX 386 v1 - Beginning)
 22715                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 22716                              <1> 	;	
 22717                              <1> 	; / read a block from a block structured device
 22718                              <1> 	;
 22719                              <1> 	; INPUTS ->
 22720                              <1> 	;    [u.fopf] points to the block number
 22721                              <1> 	;    CX = maximum block number allowed on device
 22722                              <1> 	;	 ; that was an arg to bread, in original Unix v1, but
 22723                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 22724                              <1> 	;    [u.count]	number of bytes to read in
 22725                              <1> 	; OUTPUTS ->
 22726                              <1> 	;    [u.base] starting address of data block or blocks in user area  	
 22727                              <1> 	;    [u.fopf] points to next consecutive block to be read
 22728                              <1> 	;
 22729                              <1> 	; ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))
 22730                              <1> 	;
 22731                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if read
 22732                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 22733                              <1> 	;	is increased by 1. For example: If user/program request 
 22734                              <1> 	;       to read 16 bytes in current block, 'sys read' increases
 22735                              <1> 	;  	the next block number just as 512 byte reading is done.
 22736                              <1> 	;       This wrong is done in 'bread'. So, in Retro UNIX 8086 v1, 
 22737                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 22738                              <1> 	;       enough to keep byte position/offset of the disk), this
 22739                              <1> 	;	defect will not be corrected, user/program must request
 22740                              <1> 	;	512 byte read per every 'sys read' call to block devices
 22741                              <1> 	;       for achieving correct result. In future version(s), 
 22742                              <1> 	;	this defect will be corrected by using different 
 22743                              <1> 	;       user (u) structure.  26/07/2013 - Erdogan Tan 	
 22744                              <1> 
 22745                              <1> 	   	; jsr r0,tstdeve / error on special file I/O 
 22746                              <1> 			       ; / (only works on tape)
 22747                              <1> 		; mov *u.fofp,r1 / move block number to r1
 22748                              <1> 		; mov $2.-cold,-(sp) / "2-cold" to stack
 22749                              <1> ;1:
 22750                              <1> 		; cmp r1,(r0) / is this block # greater than or equal to
 22751                              <1> 			    ; / maximum block # allowed on device
 22752                              <1> 		; jnb short @f
 22753                              <1> 		; bhis	1f / yes, 1f (error)
 22754                              <1> 		; mov r1,-(sp) / no, put block # on stack
 22755                              <1> 		; jsr r0,preread / read in the block into an I/O buffer
 22756                              <1> 		; mov (sp)+,r1 / return block # to r1
 22757                              <1> 		; inc r1 / bump block # to next consecutive block
 22758                              <1> 		; dec (sp) / "2-1-cold" on stack
 22759                              <1> 		; bgt 1b / 2-1-cold = 0?  No, go back and read in next block
 22760                              <1> ;1:
 22761                              <1> 		; tst (sp)+ / yes, pop stack to clear off cold calculation
 22762                              <1> 	;push	ecx ; **
 22763                              <1> 	;26/04/2013
 22764                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 22765 0000609B 2C03                <1> 	sub	al, 3
 22766                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 22767 0000609D A2[E8740000]        <1> 	mov	[u.brwdev], al
 22768                              <1> 	; 09/06/2015
 22769 000060A2 0FB6D8              <1> 	movzx	ebx, al
 22770 000060A5 8B8B[086E0000]      <1> 	mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 22771                              <1> bread_0:
 22772 000060AB 51                  <1> 	push	ecx ; ** ; 09/06/2015 
 22773                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 22774                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 22775 000060AC 8B1D[90740000]      <1> 	mov	ebx, [u.fofp]
 22776 000060B2 8B03                <1> 	mov	eax, [ebx]
 22777 000060B4 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 22778                              <1> 		; mov *u.fofp,r1 / restore r1 to initial value of the
 22779                              <1> 			       ; / block #
 22780 000060B7 39C8                <1> 	cmp	eax, ecx
 22781                              <1> 		; cmp r1,(r0)+ / block # greater than or equal to maximum
 22782                              <1>        	                     ; / block number allowed
 22783                              <1> 	;jnb	error 	     ; 18/04/2013
 22784                              <1> 		; bhis error10 / yes, error
 22785 000060B9 720F                <1> 	jb	short bread_1
 22786 000060BB C705[D5740000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error	
 22787 000060C3 0000                <1>
 22788 000060C5 E9B2DFFFFF          <1> 	jmp	error
 22789                              <1> bread_1:
 22790                              <1> 	; inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 22791                              <1> 		; inc *u.fofp / no, *u.fofp has next block number
 22792                              <1> 	; eAX = Block number (zero based)
 22793                              <1> 		;;jsr r0,preread / read in the block whose number is in r1
 22794                              <1> preread: ;; call preread
 22795 000060CA BF[E8740000]        <1> 	mov	edi, u.brwdev ; block device number for direct I/O
 22796 000060CF E864020000          <1> 	call	bufaloc_0 ; 26/04/2013
 22797                              <1> 	;; jc 	error
 22798                              <1> 	; eBX = Buffer (Header) Address -Physical-
 22799                              <1>         ; eAX = Block/Sector number (r1)
 22800                              <1> 	       ; jsr r0,bufaloc / get a free I/O buffer (r1 has block number)
 22801                              <1> 	; 14/03/2013
 22802 000060D4 740A                <1>         jz	short bread_2 ; Retro UNIX 8086 v1 modification
 22803                              <1>        		; br 1f / branch if block already in a I/O buffer
 22804 000060D6 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 22805                              <1>         	; bis $2000,(r5) / set read bit (bit 10 in I/O buffer)
 22806 000060DB E8B3010000          <1> 	call	poke
 22807                              <1>         	; jsr r0,poke / perform the read
 22808                              <1> 	;;jc	error ;2 0/07/2013
 22809                              <1> ; 1:
 22810                              <1>  		; clr *$ps / ps = 0
 22811                              <1>         	; rts r0
 22812                              <1> ;; return from preread
 22813                              <1> bread_2:
 22814 000060E0 66810B0040          <1> 	or	word [ebx], 4000h 
 22815                              <1> 		; bis $40000,(r5) 
 22816                              <1> 			; / set bit 14 of the 1st word of the I/O buffer
 22817                              <1> bread_3: ; 1:
 22818 000060E5 66F7030024          <1> 	test	word [ebx], 2400h
 22819                              <1> 		; bit $22000,(r5) / are 10th and 13th bits set (read bits)
 22820 000060EA 7407                <1> 	jz	short bread_4
 22821                              <1> 		; beq 1f / no
 22822                              <1> 		; cmp cdev,$1 / disk or drum?
 22823                              <1> 		; ble 2f / yes
 22824                              <1> 		; tstb uquant / is the time quantum = 0?
 22825                              <1> 		; bne 2f / no, 2f
 22826                              <1> 		; mov r5,-(sp) / yes, save r5 (buffer address)
 22827                              <1> 		; jsr r0,sleep; 31. 
 22828                              <1> 			; / put process to sleep in channel 31 (tape)
 22829                              <1> 		; mov (sp)+,r5 / restore r5
 22830                              <1> 		; br 1b / go back
 22831                              <1> ; 2: / drum or disk
 22832                              <1>         ;; mov     cx, [s.wait_]+2 ;; 29/07/2013
 22833 000060EC E8AAF3FFFF          <1> 	call	idle
 22834                              <1> 		; jsr r0,idle; s.wait+2 / wait
 22835 000060F1 EBF2                <1> 	jmp	short bread_3
 22836                              <1>        		; br 1b
 22837                              <1> bread_4: ; 1: / 10th and 13th bits not set
 22838 000060F3 668123FFBF          <1> 	and	word [ebx], 0BFFFh ; 1011111111111111b
 22839                              <1> 		; bic $40000,(r5) / clear bit 14
 22840                              <1>        		; jsr r0,tstdeve / test device for error (tape)
 22841 000060F8 83C308              <1> 	add	ebx, 8
 22842                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 22843                              <1> 	; 09/06/2015
 22844 000060FB 66833D[E5740000]00  <1> 	cmp	word [u.pcount], 0
 22845 00006103 7705                <1> 	ja	short bread_5
 22846 00006105 E896F9FFFF          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 22847                              <1> bread_5:
 22848                              <1> 	; eBX = system (I/O) buffer address
 22849 0000610A E870000000          <1> 	call	dioreg
 22850                              <1>        		; jsr r0,dioreg / do bookkeeping on u.count etc.
 22851                              <1> 	; esi =  start address of the transfer (in the buffer)
 22852                              <1> 	; edi =  [u.pbase], destination address in user's memory space
 22853                              <1> 	; ecx =  transfer count (in bytes)
 22854                              <1> 	;
 22855                              <1> ;1: / r5 points to beginning of data in I/O buffer, r2 points to beginning
 22856                              <1> ;   / of users data
 22857 0000610F F3A4                <1> 	rep	movsb
 22858                              <1> 		; movb (r5)+,(r2)+ / move data from the I/O buffer
 22859                              <1>        		; dec r3 / to the user's area in core starting at u.base
 22860                              <1>        		; bne 1b
 22861 00006111 59                  <1> 	pop	ecx ; **
 22862 00006112 833D[A4740000]00    <1> 	cmp	dword [u.count], 0
 22863                              <1> 		; tst u.count / done
 22864 00006119 7790                <1> 	ja	short bread_0 ; 09/06/2015
 22865                              <1>        		; beq 1f / yes, return
 22866                              <1> 		; tst -(r0) / no, point r0 to the argument again
 22867                              <1>        		; br bread / read some more
 22868                              <1> ; 1:
 22869 0000611B 58                  <1> 	pop	eax ; ****
 22870                              <1>        		; mov (sp)+,r0
 22871 0000611C C3                  <1>         retn		; 09/06/2015
 22872                              <1> 	;jmp     ret_ 
 22873                              <1> 		;jmp ret  / jump to routine that called readi
 22874                              <1> 
 22875                              <1> wfd:    ; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22876                              <1> 	; 26/04/2013
 22877                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 22878                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 22879                              <1>    	;jmp	short bwrite ; **** returns to routine that called writei
 22880                              <1> 				
 22881                              <1> whd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22882                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 22883                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 22884                              <1>    	;jmp 	short bwrite ; **** returns to routine that called writei ('jmp ret')
 22885                              <1> 
 22886                              <1> bwrite: 
 22887                              <1> 	; 14/07/2015
 22888                              <1> 	; 10/07/2015
 22889                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22890                              <1> 	; 14/03/2013 - 20/07/2013 (Retro UNIX 8086 v1)
 22891                              <1> 	;	
 22892                              <1> 	;; / write on block structured device
 22893                              <1> 	;
 22894                              <1> 	; INPUTS ->
 22895                              <1> 	;    [u.fopf] points to the block number
 22896                              <1> 	;    CX = maximum block number allowed on device
 22897                              <1> 	;	 ; that was an arg to bwrite, in original Unix v1, but
 22898                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 22899                              <1> 	;    [u.count]	number of bytes to user desires to write
 22900                              <1> 	; OUTPUTS ->
 22901                              <1> 	;    [u.fopf] points to next consecutive block to be written into
 22902                              <1> 	;
 22903                              <1> 	; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))
 22904                              <1> 	;
 22905                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if write
 22906                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 22907                              <1> 	;	is increased by 1. For example: If user/program request 
 22908                              <1> 	;       to write 16 bytes in current block, 'sys write' increases
 22909                              <1> 	;  	the next block number just as 512 byte writing is done.
 22910                              <1> 	;       This wrong is done in 'bwrite'. So, in Retro UNIX 8086 v1, 
 22911                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 22912                              <1> 	;       enough to keep byte position/offset of the disk), this
 22913                              <1> 	;	defect will not be corrected, user/program must request
 22914                              <1> 	;	512 byte write per every 'sys write' call to block devices
 22915                              <1> 	;       for achieving correct result. In future version(s), 
 22916                              <1> 	;	this defect will be corrected by using different 
 22917                              <1> 	;       user (u) structure.  26/07/2013 - Erdogan Tan 	
 22918                              <1> 
 22919                              <1>        		; jsr r0,tstdeve / test the device for an error
 22920                              <1> 	;push	ecx ; **
 22921                              <1> 	;26/04/2013
 22922                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 22923 0000611D 2C03                <1> 	sub	al, 3
 22924                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 22925 0000611F A2[E8740000]        <1> 	mov	[u.brwdev], al
 22926                              <1> 	; 09/06/2015
 22927 00006124 0FB6D8              <1> 	movzx	ebx, al
 22928 00006127 8B8B[086E0000]      <1> 	mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 22929                              <1> bwrite_0:
 22930 0000612D 51                  <1> 	push	ecx ; ** ; 09/06/2015
 22931                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 22932                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 22933 0000612E 8B1D[90740000]      <1> 	mov	ebx, [u.fofp]
 22934 00006134 8B03                <1> 	mov	eax, [ebx]       
 22935 00006136 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 22936                              <1> 		; mov *u.fofp,r1 / put the block number in r1
 22937 00006139 39C8                <1> 	cmp	eax, ecx
 22938                              <1> 		; cmp r1,(r0)+ / does block number exceed maximum allowable #
 22939                              <1>        	                     ; / block number allowed
 22940                              <1> 	;jnb	error	     ; 18/04/2013
 22941                              <1> 		; bhis error10 / yes, error
 22942 0000613B 720F                <1>      	jb	short bwrite_1
 22943 0000613D C705[D5740000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error	
 22944 00006145 0000                <1>
 22945 00006147 E930DFFFFF          <1> 	jmp	error
 22946                              <1> bwrite_1:
 22947                              <1> 	; inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 22948                              <1> 		; inc *u.fofp / no, increment block number
 22949                              <1> 	; 09/06/2015 - 10/07/2015
 22950 0000614C 66833D[E5740000]00  <1> 	cmp	word [u.pcount], 0
 22951 00006154 7705                <1> 	ja	short bwrite_2
 22952 00006156 E841F9FFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 22953                              <1> bwrite_2:
 22954 0000615B BF[E8740000]        <1> 	mov	edi, u.brwdev  ; block device number for direct I/O
 22955 00006160 E8C4000000          <1>        	call	bwslot ; 26/04/2013 (wslot -> bwslot)	 				
 22956                              <1> 		; jsr r0,wslot / get an I/O buffer to write into
 22957                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 22958 00006165 E815000000          <1>         call	dioreg
 22959                              <1> 		; jsr r0,dioreg / do the necessary bookkeeping
 22960                              <1> 	; esi =  destination address (in the buffer)
 22961                              <1> 	; edi =  [u.pbase], start address of transfer in user's memory space
 22962                              <1> 	; ecx =  transfer count (in bytes)
 22963                              <1> ; 1: / r2 points to the users data; r5 points to the I/O buffers data area
 22964 0000616A 87F7                <1> 	xchg 	esi, edi ; 14/07/2015
 22965 0000616C F3A4                <1> 	rep	movsb
 22966                              <1> 		; movb (r2)+,(r5)+ / ; r3, has the byte count
 22967                              <1>        		; dec r3 / area to the I/O buffer
 22968                              <1>        		; bne 1b
 22969 0000616E E8FE000000          <1> 	call	dskwr
 22970                              <1> 		; jsr r0,dskwr / write it out on the device
 22971 00006173 59                  <1> 	pop	ecx ; **
 22972 00006174 833D[A4740000]00    <1>         cmp     dword [u.count], 0
 22973                              <1> 		; tst u.count / done
 22974 0000617B 77B0                <1> 	ja	short bwrite_0 ; 09/06/2015
 22975                              <1> 		; beq 1f / yes, 1f
 22976                              <1> 		; tst -(r0) / no, point r0 to the argument of the call
 22977                              <1>        		; br bwrite / go back and write next block
 22978                              <1> ; 1:
 22979 0000617D 58                  <1> 	pop	eax ; ****
 22980                              <1>        		; mov (sp)+,r0
 22981 0000617E C3                  <1> 	retn		; 09/06/2015
 22982                              <1>         ;jmp     ret_ 
 22983                              <1> 		; jmp ret / return to routine that called writei
 22984                              <1> ;error10:
 22985                              <1> ;       jmp     error  ; / see 'error' routine
 22986                              <1> 
 22987                              <1> dioreg:
 22988                              <1> 	; 14/07/2015
 22989                              <1> 	; 10/07/2015 (UNIX v1 bugfix - [u.fofp]: byte pos., not block)
 22990                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22991                              <1> 	; 14/03/2013 (Retro UNIX 8086 v1)
 22992                              <1> 	;	
 22993                              <1> 	; bookkeeping on block transfers of data
 22994                              <1> 	;
 22995                              <1> 	; * returns value of u.pbase before it gets updated, in EDI
 22996                              <1> 	; * returns byte count (to transfer) in ECX (<=512)
 22997                              <1> 	; 10/07/2015
 22998                              <1> 	; * returns byte offset from beginning of current sector buffer
 22999                              <1> 	; (beginning of data) in ESI
 23000                              <1> 	;
 23001 0000617F 8B0D[A4740000]      <1> 	mov	ecx, [u.count]
 23002                              <1> 		; mov u.count,r3 / move char count to r3
 23003 00006185 81F900020000        <1>        	cmp 	ecx, 512
 23004                              <1> 		; cmp r3,$512. / more than 512. char?
 23005 0000618B 7605                <1> 	jna	short dioreg_0
 23006                              <1> 		; blos 1f / no, branch
 23007 0000618D B900020000          <1> 	mov	ecx, 512
 23008                              <1> 		; mov $512.,r3 / yes, just take 512.
 23009                              <1> dioreg_0:
 23010                              <1> 	; 09/06/2015
 23011 00006192 663B0D[E5740000]    <1> 	cmp	cx, [u.pcount]
 23012 00006199 7607                <1> 	jna	short dioreg_1
 23013 0000619B 668B0D[E5740000]    <1> 	mov	cx, [u.pcount]
 23014                              <1> dioreg_1:
 23015                              <1> ; 1:
 23016 000061A2 8B15[A0740000]      <1> 	mov	edx, [u.base] ; 09/06/2015 (eax -> edx)
 23017                              <1> 	        ; mov u.base,r2 / put users base in r2
 23018 000061A8 010D[A8740000]      <1> 	add	[u.nread], ecx
 23019                              <1> 		; add r3,u.nread / add the number to be read to u.nread
 23020 000061AE 290D[A4740000]      <1> 	sub	[u.count], ecx
 23021                              <1> 		; sub r3,u.count / update count
 23022 000061B4 010D[A0740000]      <1> 	add	[u.base], ecx
 23023                              <1> 		; add r3,u.base / update base
 23024                              <1> 	; 10/07/2015
 23025                              <1> 	; Retro UNIX 386 v1 - modification !
 23026                              <1> 	; (File pointer points to byte position, not block/sector no.)
 23027                              <1> 	; (It will point to next byte position instead of next block no.)
 23028 000061BA 8B35[90740000]      <1> 	mov	esi, [u.fofp] ; u.fopf points to byte position pointer  
 23029 000061C0 8B06                <1> 	mov	eax, [esi] ; esi points to current byte pos. on the disk
 23030 000061C2 010E                <1> 	add	[esi], ecx ; ecx is added to set the next byte position
 23031 000061C4 25FF010000          <1> 	and	eax, 1FFh  ; get offset from beginning of current block	
 23032 000061C9 89DE                <1> 	mov	esi, ebx   ; beginning of data in sector/block buffer
 23033 000061CB 01C6                <1> 	add	esi, eax   ; esi contains start address of the transfer
 23034                              <1> 	; 09/06/2015 - 10/07/2015
 23035 000061CD 66290D[E5740000]    <1> 	sub	[u.pcount], cx
 23036 000061D4 81E2FF0F0000        <1> 	and	edx, PAGE_OFF ; 0FFFh
 23037 000061DA 8B3D[E1740000]      <1> 	mov	edi, [u.pbase]
 23038 000061E0 81E700F0FFFF        <1> 	and	edi, ~PAGE_OFF
 23039 000061E6 01D7                <1> 	add	edi, edx
 23040 000061E8 893D[E1740000]      <1> 	mov	[u.pbase], edi
 23041 000061EE 010D[E1740000]      <1> 	add	[u.pbase], ecx ; 14/07/2015
 23042 000061F4 C3                  <1> 	retn
 23043                              <1> 		; rts r0 / return
 23044                              <1> 
 23045                              <1> dskrd:
 23046                              <1> 	; 18/08/2015
 23047                              <1> 	; 02/07/2015
 23048                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 23049                              <1> 	; 14/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 23050                              <1> 	;
 23051                              <1> 	; 'dskrd' acquires an I/O buffer, puts in the proper
 23052                              <1> 	; I/O queue entries (via bufaloc) then reads a block
 23053                              <1> 	; (number specified in r1) in the acquired buffer.)
 23054                              <1> 	; If the device is busy at the time dskrd is called,	
 23055                              <1> 	; dskrd calls idle.
 23056                              <1> 	; 
 23057                              <1> 	; INPUTS ->
 23058                              <1> 	;    r1 - block number
 23059                              <1> 	;    cdev - current device number 
 23060                              <1> 	; OUTPUTS ->
 23061                              <1> 	;    r5 - points to first data word in I/O buffer
 23062                              <1> 	;
 23063                              <1> 	; ((AX = R1)) input/output
 23064                              <1> 	; ((BX = R5)) output 
 23065                              <1> 	;
 23066                              <1>         ; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 23067                              <1> 	;
 23068 000061F5 E830010000          <1> 	call 	bufaloc
 23069                              <1> 		; jsr r0,bufaloc / shuffle off to bufaloc; 
 23070                              <1> 			       ; / get a free I/O buffer
 23071                              <1> 	;;jc	error ; 20/07/2013
 23072 000061FA 741B                <1> 	jz	short dskrd_1 ; Retro UNIX 8086 v1 modification
 23073                              <1>        		; br 1f / branch if block already in a I/O buffer
 23074                              <1> dskrd_0: ; 10/07/2015 (wslot)
 23075 000061FC 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 23076                              <1>         	; bis $2000,(r5) / set bit 10 of word 1 of 
 23077                              <1> 		               ; / I/O queue entry for buffer
 23078 00006201 E88D000000          <1> 	call	poke
 23079                              <1> 		; jsr r0,poke / just assigned in bufaloc, 
 23080                              <1> 			    ; /	bit 10=1 says read
 23081                              <1> 	; 09/06/2015
 23082 00006206 730F                <1> 	jnc	short dskrd_1
 23083                              <1> 	;
 23084 00006208 C705[D5740000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; disk read error !
 23085 00006210 0000                <1>
 23086 00006212 E965DEFFFF          <1> 	jmp	error
 23087                              <1> dskrd_1: ; 1:
 23088                              <1>        		;clr *$ps
 23089 00006217 66F7030024          <1>        	test	word [ebx], 2400h
 23090                              <1> 		; bit $22000,(r5) / if either bits 10, or 13 are 1; 
 23091                              <1> 				; / jump to idle
 23092 0000621C 7407                <1>        	jz	short dskrd_2
 23093                              <1> 		; beq 1f
 23094                              <1>         ;;mov   ecx, [s.wait_]
 23095 0000621E E878F2FFFF          <1>        	call	idle
 23096                              <1> 		; jsr r0,idle; s.wait+2
 23097 00006223 EBF2                <1> 	jmp 	short dskrd_1
 23098                              <1>        		; br 1b
 23099                              <1> dskrd_2: ; 1:
 23100 00006225 83C308              <1>         add	ebx, 8
 23101                              <1> 		; add $8,r5 / r5 points to first word of data in block 
 23102                              <1> 			  ; / just read in
 23103 00006228 C3                  <1>        	retn
 23104                              <1> 		; rts r0
 23105                              <1> 
 23106                              <1> bwslot:
 23107                              <1> 	; 10/07/2015
 23108                              <1> 	;	If the block/sector is not placed in a buffer
 23109                              <1> 	;	before 'wslot', it must be read before
 23110                              <1> 	;	it is written! (Otherwise transfer counts less
 23111                              <1> 	;	than 512 bytes will be able to destroy existing 
 23112                              <1> 	;	data on disk.)
 23113                              <1> 	;
 23114                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 23115                              <1> 	; 26/04/2013(Retro UNIX 8086 v1)
 23116                              <1> 	; Retro UNIX 8086 v1 modification !
 23117                              <1> 	; ('bwslot' will be called from 'bwrite' only!)
 23118                              <1> 	; INPUT -> eDI - points to device id (in u.brwdev)	
 23119                              <1> 	;	-> eAX = block number
 23120                              <1> 	;
 23121 00006229 E80A010000          <1> 	call	bufaloc_0
 23122 0000622E 742A                <1> 	jz	short wslot_0 ; block/sector already is in the buffer
 23123                              <1> bwslot_0:
 23124                              <1> 	; 10/07/2015
 23125 00006230 8B35[90740000]      <1> 	mov	esi, [u.fofp]
 23126 00006236 8B06                <1> 	mov	eax, [esi]
 23127 00006238 25FF010000          <1> 	and	eax, 1FFh ; offset from beginning of the sector/block
 23128 0000623D 750C                <1> 	jnz 	short bwslot_1 ; it is not a full sector write
 23129                              <1> 		       ; recent disk data must be placed in the buffer
 23130 0000623F 813D[A4740000]0002- <1> 	cmp	dword [u.count], 512
 23131 00006247 0000                <1>
 23132 00006249 730F                <1> 	jnb	short wslot_0	
 23133                              <1> bwslot_1:
 23134 0000624B E8ACFFFFFF          <1> 	call	dskrd_0
 23135 00006250 83EB08              <1> 	sub	ebx, 8 ; set ebx to the buffer header address again	
 23136 00006253 EB05                <1> 	jmp 	short wslot_0
 23137                              <1> 
 23138                              <1> wslot:
 23139                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 23140                              <1> 	; 		(32 bit modifications)
 23141                              <1> 	; 14/03/2013 - 29/07/2013(Retro UNIX 8086 v1)
 23142                              <1> 	;
 23143                              <1> 	; 'wslot' calls 'bufaloc' and obtains as a result, a pointer
 23144                              <1> 	; to the I/O queue of an I/O buffer for a block structured
 23145                              <1> 	; device. It then checks the first word of I/O queue entry.	
 23146                              <1> 	; If bits 10 and/or 13 (read bit, waiting to read bit) are set,
 23147                              <1> 	; wslot calls 'idle'. When 'idle' returns, or if bits 10 
 23148                              <1> 	; and/or 13 are not set, 'wslot' sets bits 9 and 15 of the first
 23149                              <1> 	; word of the I/O queue entry (write bit, inhibit bit).
 23150                              <1> 	;
 23151                              <1> 	; INPUTS ->
 23152                              <1>  	;    r1 - block number
 23153                              <1> 	;    cdev - current (block/disk) device number
 23154                              <1>  	;
 23155                              <1> 	; OUTPUTS ->
 23156                              <1> 	;    bufp - bits 9 and 15 are set, 
 23157                              <1> 	;           the remainder of the word left unchanged
 23158                              <1> 	;    r5 - points to first data word in I/O buffer
 23159                              <1> 	;
 23160                              <1> 	; ((AX = R1)) input/output
 23161                              <1> 	; ((BX = R5)) output 
 23162                              <1> 	;
 23163                              <1>         ; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP)) 
 23164                              <1> 
 23165 00006255 E8D0000000          <1> 	call	bufaloc
 23166                              <1> 	; 10/07/2015
 23167                              <1> 		; jsr r0,bufaloc / get a free I/O buffer; pointer to first
 23168                              <1>         	; br 1f / word in buffer in r5
 23169                              <1> 	; eBX = Buffer (Header) Address (r5) (ES=CS=DS, system/kernel segment)
 23170                              <1>         ; eAX = Block/Sector number (r1)
 23171                              <1> wslot_0: ;1:
 23172 0000625A 66F7030024          <1>      	test	word [ebx], 2400h
 23173                              <1> 		; bit $22000,(r5) / check bits 10, 13 (read, waiting to read)
 23174                              <1> 				; / of I/O queue entry
 23175 0000625F 7407                <1> 	jz	short wslot_1
 23176                              <1>                 ; beq 1f  / branch if 10, 13 zero (i.e., not reading, 
 23177                              <1> 		     ; / or not waiting to read)
 23178                              <1> 
 23179                              <1>         ;; mov     ecx, [s.wait_] ; 29/07/2013
 23180 00006261 E835F2FFFF          <1> 	call	idle
 23181                              <1> 		; jsr r0,idle; / if buffer is reading or writing to read,
 23182                              <1>        	                     ; / idle
 23183 00006266 EBF2                <1> 	jmp	short wslot_0
 23184                              <1> 		; br 1b / till finished
 23185                              <1> wslot_1: ;1:
 23186 00006268 66810B0082          <1>         or      word [ebx], 8200h
 23187                              <1>        		; bis $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
 23188                              <1>                             	 ; / (write, inhibit bits)
 23189                              <1>        		; clr     *$ps / clear processor status
 23190 0000626D 83C308              <1>         add	ebx, 8 ; 11/06/2015
 23191                              <1> 		; add $8,r5 / r5 points to first word in data area 
 23192                              <1> 			  ; / for this block
 23193 00006270 C3                  <1>        	retn
 23194                              <1> 		; rts r0
 23195                              <1> dskwr:
 23196                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 23197                              <1> 	; 14/03/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 23198                              <1> 	;
 23199                              <1> 	; 'dskwr' writes a block out on disk, via ppoke. The only
 23200                              <1> 	; thing dskwr does is clear bit 15 in the first word of I/O queue
 23201                              <1> 	; entry pointed by 'bufp'. 'wslot' which must have been called
 23202                              <1> 	; previously has supplied all the information required in the
 23203                              <1> 	; I/O queue entry.
 23204                              <1> 	;
 23205                              <1> 	; (Modified registers: eCX, eDX, eBX, eSI, eDI)
 23206                              <1> 	;
 23207                              <1> 	;
 23208 00006271 8B1D[4A740000]      <1> 	mov	ebx, [bufp]
 23209 00006277 668123FF7F          <1> 	and	word [ebx], 7FFFh ; 0111111111111111b
 23210                              <1> 		; bic $100000,*bufp / clear bit 15 of I/O queue entry at
 23211                              <1>                                   ; / bottom of queue
 23212 0000627C E812000000          <1> 	call	poke
 23213                              <1> 	; 09/06/2015
 23214 00006281 730F                <1> 	jnc	short dskwr_1
 23215 00006283 C705[D5740000]1200- <1> 	mov	dword [u.error], ERR_DRV_WRITE ; disk write error !
 23216 0000628B 0000                <1>
 23217 0000628D E9EADDFFFF          <1> 	jmp	error
 23218                              <1> dskwr_1:
 23219 00006292 C3                  <1> 	retn
 23220                              <1> 
 23221                              <1> 
 23222                              <1> ;ppoke:
 23223                              <1>        		; mov $340,*$ps
 23224                              <1>        		; jsr r0,poke
 23225                              <1>        		; clr *$ps
 23226                              <1> 		; rts r0
 23227                              <1> poke:
 23228                              <1> 	; 24/10/2015
 23229                              <1> 	; 20/08/2015
 23230                              <1> 	; 18/08/2015
 23231                              <1> 	; 02/07/2015
 23232                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 23233                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 23234                              <1> 	;
 23235                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
 23236                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
 23237                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
 23238                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
 23239                              <1> 	;
 23240                              <1> 	; Basic I/O functions for all block structured devices
 23241                              <1> 	;
 23242                              <1>         ; (Modified registers: eCX, eDX, eSI, eDI)
 23243                              <1> 	;
 23244                              <1> 	; 20/07/2013 modifications
 23245                              <1> 	;            (Retro UNIX 8086 v1 features only !)
 23246                              <1> 	; INPUTS -> 
 23247                              <1> 	;        (EBX = buffer header address)
 23248                              <1> 	; OUTPUTS ->
 23249                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
 23250                              <1> 	;	 cf=1 -> error, word [eBX] = 0FFFFh
 23251                              <1> 	;		(drive not ready or r/w error!)
 23252                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
 23253                              <1> 	;	 (dword [EBx+4] = 0FFFFFFFFh means RW/IO error)
 23254                              <1> 	;        (also it indicates invalid buffer data)
 23255                              <1> 	;
 23256 00006293 53                  <1> 	push	ebx
 23257                              <1>        		; mov r1,-(sp)
 23258                              <1>        		; mov r2,-(sp)
 23259                              <1>        		; mov r3,-(sp)
 23260 00006294 50                  <1> 	push 	eax ; Physical Block Number (r1) (mget)
 23261                              <1> 	;
 23262                              <1> 	; 09/06/2015
 23263                              <1> 	; (permit read/write after a disk  R/W error)
 23264 00006295 8A0B                <1> 	mov	cl, [ebx] ; device id (0 to 5)
 23265 00006297 B001                <1> 	mov	al, 1
 23266 00006299 D2E0                <1> 	shl	al, cl
 23267 0000629B 8405[6A740000]      <1> 	test 	al, [active] ; busy ? (error)
 23268 000062A1 7408                <1> 	jz	short poke_0
 23269 000062A3 F6D0                <1> 	not	al
 23270 000062A5 2005[6A740000]      <1> 	and	[active], al ; reset busy bit for this device only
 23271                              <1> poke_0:
 23272 000062AB BE[62740000]        <1>         mov     esi, bufp + (4*(nbuf+2)) 
 23273                              <1> 		; mov $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority
 23274                              <1> 					 ; / I/O queue pointer
 23275                              <1> poke_1: ; 1:
 23276 000062B0 83EE04              <1>         sub	esi, 4
 23277 000062B3 8B1E                <1> 	mov	ebx, [esi]
 23278                              <1> 		; mov -(r2),r1 / r1 points to an I/O queue entry
 23279 000062B5 668B03              <1> 	mov	ax, [ebx] ; 17/07/2013
 23280 000062B8 F6C406              <1>        	test	ah, 06h
 23281                              <1> 	;test	word [ebx], 600h ; 0000011000000000b
 23282                              <1> 		; bit $3000,(r1) / test bits 9 and 10 of word 1 of I/O 
 23283                              <1> 			       ; / queue entry
 23284 000062BB 745E                <1>         jz      short poke_5
 23285                              <1> 		; beq 2f / branch to 2f if both are clear
 23286                              <1> 	; 31/07/2013
 23287                              <1> 	;test	ah, 0B0h ; (*)
 23288                              <1> 	;;test	word [ebx], 0B000h ; 1011000000000000b
 23289                              <1> 		; bit $130000,(r1) / test bits 12, 13, and 15
 23290                              <1>         ;jnz     short poke_5 ; 31/07/2013 (*)
 23291                              <1> 		; bne 2f / branch if any are set
 23292                              <1> 	;movzx	ecx, byte [ebx] ; 09/06/2015 ; Device Id
 23293                              <1>     		; movb (r1),r3 / get device id
 23294 000062BD 0FB6C8              <1> 	movzx	ecx, al ; 18/08/2015
 23295                              <1> 	;mov	edi, ecx ; 26/04/2013
 23296 000062C0 31C0                <1> 	xor 	eax, eax ; 0
 23297                              <1> 	;cmp 	[edi+drv.error], al ; 0
 23298                              <1> 		; tstb deverr(r3) / test for errors on this device
 23299                              <1>        	;jna	short poke_2 
 23300                              <1> 		; beq 3f / branch if no errors
 23301                              <1> 	; 02/07/2015
 23302                              <1> 	;dec	eax
 23303                              <1> 	;mov	[ebx+4], ax ; 0FFFFFFFFh ; -1 
 23304                              <1>        		; mov $-1,2(r1) / destroy associativity
 23305                              <1> 	;shr	eax, 24
 23306                              <1> 	;mov	[ebx], eax ; 000000FFh, reset
 23307                              <1> 		; clrb 1(r1) / do not do I/O
 23308                              <1> 	;jmp     short poke_5
 23309                              <1>         ;       ; br 2f
 23310                              <1>                 ; rts r0
 23311                              <1> poke_2: ; 3:
 23312                              <1> 	; 02/07/2015
 23313 000062C2 FEC1                <1> 	inc	cl ; 0FFh -> 0
 23314 000062C4 7455                <1> 	jz	short poke_5
 23315 000062C6 FEC0                <1> 	inc	al ; mov ax, 1
 23316 000062C8 FEC9                <1> 	dec	cl
 23317 000062CA 7402                <1> 	jz	short poke_3
 23318                              <1> 	; 26/04/2013 Modification
 23319                              <1> 	;inc	al ; mov ax, 1
 23320                              <1> 	;or	cl, cl ; Retro UNIX 8086 v1 device id.
 23321                              <1> 	;jz	short poke_3 ; cl = 0
 23322 000062CC D2E0                <1> 	shl	al, cl ; shl ax, cl
 23323                              <1> poke_3:
 23324                              <1> 	;test	[active], ax
 23325 000062CE 8405[6A740000]      <1> 	test	[active], al
 23326                              <1> 		; bit $2,active / test disk busy bit
 23327 000062D4 7545                <1> 	jnz     short poke_5
 23328                              <1> 		; bne 2f / branch if bit is set
 23329                              <1> 	;or	[active], ax
 23330 000062D6 0805[6A740000]      <1> 	or	[active], al
 23331                              <1> 		; bis $2,active / set disk busy bit
 23332 000062DC 6650                <1> 	push	ax
 23333 000062DE E8CB000000          <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
 23334                              <1> 	;mov    [edi+drv.error], ah
 23335 000062E3 6658                <1> 	pop	ax
 23336 000062E5 730E                <1> 	jnc	short poke_4 ; 20/07/2013
 23337                              <1> 	;cmp 	[edi+drv.error], al ; 0	
 23338                              <1> 	;jna	short poke_4
 23339                              <1> 		; tstb deverr(r3) / test for errors on this device
 23340                              <1>        		; beq 3f / branch if no errors
 23341                              <1> 	; 02/07/2015 (32 bit modification)
 23342                              <1> 	; 20/07/2013
 23343 000062E7 C74304FFFFFFFF      <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
 23344                              <1>        		; mov $-1,2(r1) / destroy associativity
 23345 000062EE 66C703FF00          <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
 23346                              <1> 		; clrb 1(r1) / do not do I/O
 23347 000062F3 EB26                <1> 	jmp     short poke_5
 23348                              <1> poke_4:	; 20/07/2013
 23349                              <1> 	; 17/07/2013
 23350 000062F5 F6D0                <1> 	not 	al 
 23351 000062F7 2005[6A740000]      <1> 	and	[active], al ; reset, not busy
 23352                              <1> 	; eBX = system I/O buffer header (queue entry) address
 23353                              <1> seta: ; / I/O queue bookkeeping; set read/write waiting bits.
 23354 000062FD 668B03              <1> 	mov	ax, [ebx]
 23355                              <1>        		; mov (r1),r3 / move word 1 of I/O queue entry into r3
 23356 00006300 66250006            <1>         and	ax, 600h
 23357                              <1> 		; bic $!3000,r3 / clear all bits except 9 and 10
 23358 00006304 668123FFF9          <1> 	and 	word [ebx], 0F9FFh
 23359                              <1>        		; bic $3000,(r1) / clear only bits 9 and 10
 23360 00006309 C0E403              <1> 	shl	ah, 3
 23361                              <1>        		; rol r3
 23362                              <1>                 ; rol r3
 23363                              <1>                 ; rol r3	
 23364 0000630C 660903              <1> 	or	[ebx], ax
 23365                              <1> 		; bis r3,(r1) / or old value of bits 9 and 10 with 
 23366                              <1> 			   ; bits 12 and 13
 23367 0000630F E887F1FFFF          <1> 	call	idle ; 18/01/2014
 23368                              <1> 	;; sti
 23369                              <1> 	;hlt 	; wait for a hardware interrupt
 23370                              <1> 	;; cli
 23371                              <1> 	; NOTE: In fact, disk controller's 'disk I/O completed' 
 23372                              <1>         ; interrupt would be used to reset busy bits, but INT 13h
 23373                              <1> 	; returns when disk I/O is completed. So, here, as temporary
 23374                              <1> 	; method, this procedure will wait for a time according to
 23375                              <1> 	; multi tasking and time sharing concept.
 23376                              <1> 	;
 23377                              <1> 	; 24/10/2015
 23378                              <1> 	;not	ax 
 23379 00006314 66B8FF00            <1> 	mov 	ax, 0FFh ; 24/10/2015 (temporary)
 23380 00006318 662103              <1> 	and	[ebx], ax ; clear bits 12 and 13
 23381                              <1> poke_5: ;2:
 23382 0000631B 81FE[4A740000]      <1>         cmp     esi, bufp
 23383                              <1>                ; cmp r2,$bufp / test to see if entire I/O queue 
 23384                              <1>                             ; / has been scanned
 23385 00006321 778D                <1> 	ja      short poke_1
 23386                              <1>                ; bhi 1b
 23387                              <1> 	; 24/03/2013
 23388                              <1>        		; mov (sp)+,r3
 23389                              <1>        		; mov (sp)+,r2
 23390                              <1>        		; mov (sp)+,r1
 23391 00006323 58                  <1>         pop 	eax  ; Physical Block Number (r1) (mget)
 23392 00006324 5B                  <1> 	pop 	ebx
 23393                              <1> 	; 02/07/2015 (32 bit modification)
 23394                              <1> 	; 20/07/2013
 23395                              <1> 	;cmp 	dword [ebx+4], 0FFFFFFFFh
 23396 00006325 803BFF              <1> 	cmp	byte [ebx], 0FFh ; 20/08/2015
 23397                              <1> 	;	
 23398                              <1> 	; 'poke' returns with cf=0 if the requested buffer is read 
 23399                              <1> 	; or written succesfully; even if an error occurs while
 23400                              <1> 	; reading to or writing from other buffers. 20/07/2013
 23401                              <1> 	;
 23402                              <1> 	; 09/06/2015
 23403 00006328 F5                  <1> 	cmc
 23404 00006329 C3                  <1> 	retn
 23405                              <1>                 ; rts r0
 23406                              <1> 
 23407                              <1> bufaloc:
 23408                              <1> 	; 20/08/2015
 23409                              <1> 	; 19/08/2015
 23410                              <1> 	; 02/07/2015
 23411                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 23412                              <1> 	;	     (32 bit modifications)	
 23413                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 23414                              <1> 	;
 23415                              <1> 	; bufaloc - Block device I/O buffer allocation
 23416                              <1> 	; 
 23417                              <1> 	; INPUTS ->
 23418                              <1> 	;    r1 - block number
 23419                              <1> 	;    cdev - current (block/disk) device number
 23420                              <1> 	;    bufp+(2*n)-2 --- n = 1 ... nbuff
 23421                              <1> 	; OUTPUTS ->
 23422                              <1> 	;    r5 - pointer to buffer allocated
 23423                              <1> 	;    bufp ... bufp+12 --- (bufp), (bufp)+2
 23424                              <1> 	;
 23425                              <1> 	; ((AX = R1)) input/output
 23426                              <1> 	; ((BX = R5)) output
 23427                              <1>         ;    ((Modified registers: DX, CX, BX, SI, DI, BP))
 23428                              <1> 	;    zf=1 -> block already in a I/O buffer
 23429                              <1> 	;    zf=0 -> a new I/O buffer has been allocated
 23430                              <1> 	;    ((DL = Device ID))
 23431                              <1> 	;    (((DH = 0 or 1)))
 23432                              <1> 	;    (((CX = previous value of word ptr [bufp])))
 23433                              <1> 	;    ((CX and DH will not be used after return)))
 23434                              <1> 
 23435                              <1> 	;;push 	esi ; ***
 23436                              <1> 		; mov r2,-(sp) / save r2 on stack
 23437                              <1>        		; mov $340,*$ps / set processor priority to 7
 23438                              <1> 	; 20/07/2013
 23439                              <1> 	; 26/04/2013
 23440 0000632A 0FB61D[66740000]    <1> 	movzx	ebx, byte [cdev] ; 0 or 1
 23441 00006331 BF[68740000]        <1> 	mov	edi, rdev  ; offset mdev = offset rdev + 1
 23442 00006336 01DF                <1> 	add	edi, ebx
 23443                              <1> bufaloc_0: ; 26/04/2013 !! here is called from bread or bwrite !!
 23444                              <1> 			;; eDI points to device id.
 23445 00006338 0FB61F              <1> 	movzx	ebx, byte [edi] ; [EDI] -> rdev/mdev or brwdev
 23446                              <1> 	; 11/06/20215
 23447 0000633B 80BB[246E0000]F0    <1> 	cmp 	byte [ebx+drv.status], 0F0h ; Drive not ready !
 23448 00006342 720F                <1> 	jb	short bufaloc_9
 23449 00006344 C705[D5740000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 23450 0000634C 0000                <1>
 23451 0000634E E929DDFFFF          <1> 	jmp	error
 23452                              <1> bufaloc_9:
 23453 00006353 89DA                <1> 	mov	edx, ebx ; dh = 0, dl = device number (0 to 5)
 23454                              <1> bufaloc_10: ; 02/07/2015
 23455 00006355 31ED                <1> 	xor 	ebp, ebp ; 0
 23456 00006357 55                  <1> 	push	ebp ; 0
 23457 00006358 89E5                <1>         mov     ebp, esp	
 23458                              <1> 	;
 23459                              <1> bufaloc_1: ;1:
 23460                              <1> 		; clr -(sp) / vacant buffer
 23461 0000635A BE[4A740000]        <1>         mov 	esi, bufp
 23462                              <1> 		; mov $bufp,r2 / bufp contains pointers to I/O queue 
 23463                              <1> 			     ; / entrys in buffer area
 23464                              <1> bufaloc_2: ;2:
 23465 0000635F 8B1E                <1> 	mov	ebx, [esi]
 23466                              <1>        		; mov (r2)+,r5 / move pointer to word 1 of an I/O 
 23467                              <1> 			    ; queue entry into r5
 23468 00006361 66F70300F6          <1> 	test	word [ebx], 0F600h
 23469                              <1> 		; bit $173000,(r5) / lock+keep+active+outstanding
 23470 00006366 7503                <1>         jnz	short bufaloc_3
 23471                              <1> 		; bne 3f / branch when 
 23472                              <1> 		       ; / any of bits 9,10,12,13,14,15 are set
 23473                              <1>                        ; / (i.e., buffer busy)
 23474 00006368 897500              <1>         mov     [ebp], esi ; pointer to I/0 queue entry
 23475                              <1>                 ; mov  r2,(sp) ;/ save pointer to last non-busy buffer
 23476                              <1> 			; / found points to word 2 of I/O queue entry)
 23477                              <1> bufaloc_3: ;3:
 23478                              <1> 	;mov	dl, [edi] ; 26/04/2013
 23479                              <1> 	;
 23480 0000636B 3813                <1> 	cmp	[ebx], dl	
 23481                              <1> 		; cmpb (r5),cdev / is device in I/O queue entry same 
 23482                              <1> 			       ; / as current device
 23483 0000636D 7508                <1> 	jne	short bufaloc_4
 23484                              <1>        		; bne 3f
 23485 0000636F 394304              <1> 	cmp	[ebx+4], eax
 23486                              <1>        		; cmp 2(r5),r1 / is block number in I/O queue entry, 
 23487                              <1> 			     ; / same as current block number
 23488 00006372 7503                <1>        	jne	short bufaloc_4
 23489                              <1> 		; bne 3f
 23490                              <1> 	;add	esp, 4
 23491 00006374 59                  <1> 	pop	ecx
 23492                              <1>        		; tst (sp)+ / bump stack pointer
 23493 00006375 EB20                <1> 	jmp	short bufaloc_7 ; Retro Unix 8086 v1 modification
 23494                              <1> 				; jump to bufaloc_6 in original Unix v1
 23495                              <1>        		; br 1f / use this buffer
 23496                              <1> bufaloc_4: ;3:
 23497 00006377 83C604              <1> 	add	esi, 4 ; 20/08/2015
 23498                              <1> 	;
 23499 0000637A 81FE[5A740000]      <1> 	cmp	esi, bufp + (nbuf*4)
 23500                              <1> 		; cmp r2,$bufp+nbuf+nbuf
 23501 00006380 72DD                <1> 	jb	short bufaloc_2
 23502                              <1> 		; blo 2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
 23503                              <1>                        ; / buffers not checked)
 23504 00006382 5E                  <1>         pop	esi
 23505                              <1> 		; mov (sp)+,r2 / once all bufs are examined move pointer
 23506                              <1> 			     ; / to last free block
 23507 00006383 09F6                <1>        	or	esi, esi 
 23508 00006385 7507                <1> 	jnz	short bufaloc_5
 23509                              <1> 		; bne 2f / if (sp) is non zero, i.e., 
 23510                              <1> 	        ; / if a free buffer is found branch to 2f
 23511                              <1>         ;; mov  ecx, [s.wait_]
 23512 00006387 E80FF1FFFF          <1> 	call	idle
 23513                              <1> 		; jsr r0,idle; s.wait+2 / idle if no free buffers
 23514 0000638C EBC7                <1> 	jmp 	short bufaloc_10 ; 02/07/2015
 23515                              <1>        		; br 1b
 23516                              <1> bufaloc_5: ;2:
 23517                              <1> 		; tst (r0)+ / skip if warmed over buffer
 23518 0000638E FEC6                <1> 	inc	dh ; Retro UNIX 8086 v1 modification
 23519                              <1> bufaloc_6: ;1:
 23520 00006390 8B1E                <1>         mov    	ebx, [esi] 
 23521                              <1> 		; mov -(r2),r5 / put pointer to word 1 of I/O queue 
 23522                              <1> 			     ; / entry in r5
 23523                              <1> 	;; 26/04/2013
 23524                              <1>         ;mov	dl, [edi] ; byte [rdev] or byte [mdev]
 23525 00006392 8813                <1> 	mov 	[ebx], dl
 23526                              <1> 		; movb cdev,(r5) / put current device number 
 23527                              <1> 				 ; / in I/O queue entry
 23528 00006394 894304              <1> 	mov 	[ebx+4], eax
 23529                              <1> 		; mov r1,2(r5) / move block number into word 2 
 23530                              <1> 			     ; / of I/O queue entry
 23531                              <1> bufaloc_7: ;1:
 23532 00006397 81FE[4A740000]      <1>         cmp	esi, bufp
 23533                              <1> 		; cmp r2,$bufp / bump all entrys in bufp 
 23534                              <1> 			     ; / and put latest assigned
 23535 0000639D 760A                <1> 	jna	short bufaloc_8	
 23536                              <1>        		; blos 1f / buffer on the top 
 23537                              <1> 			; / (this makes if the lowest priority)
 23538 0000639F 83EE04              <1> 	sub	esi, 4
 23539 000063A2 8B0E                <1> 	mov	ecx, [esi]
 23540 000063A4 894E04              <1> 	mov	[esi+4], ecx
 23541                              <1> 		; mov -(r2),2(r2) / job for a particular device
 23542 000063A7 EBEE                <1> 	jmp 	short bufaloc_7        
 23543                              <1> 		; br 1b
 23544                              <1> bufaloc_8: ;1:
 23545 000063A9 891E                <1>         mov	[esi], ebx
 23546                              <1> 		; mov r5,(r2)
 23547                              <1> 	;;pop	esi ; ***
 23548                              <1>        		; mov (sp)+,r2 / restore r2
 23549 000063AB 08F6                <1>        	or 	dh, dh ; 0 or 1 ?
 23550                              <1> 		; Retro UNIX 8086 v1 modification
 23551                              <1> 		; zf=1 --> block already is in an I/O buffer
 23552                              <1> 		; zf=0 --> a new I/O buffer has been allocated
 23553 000063AD C3                  <1> 	retn
 23554                              <1> 		; rts r0
 23555                              <1> 
 23556                              <1> diskio:
 23557                              <1> 	; 10/07/2015
 23558                              <1> 	; 02/07/2015
 23559                              <1> 	; 16/06/2015
 23560                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 23561                              <1> 	;	     (80386 protected mode modifications)	
 23562                              <1> 	; 15/03/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 23563                              <1> 	;
 23564                              <1> 	; Retro UNIX 8086 v1 feature only !
 23565                              <1> 	;
 23566                              <1> 	; Derived from proc_chs_read procedure of TRDOS DISKIO.ASM (2011)
 23567                              <1> 	; 04/07/2009 - 20/07/2011
 23568                              <1> 	;
 23569                              <1> 	; NOTE: Reads only 1 block/sector (sector/block size is 512 bytes)
 23570                              <1> 	;
 23571                              <1>         ; INPUTS ->
 23572                              <1> 	; 	   eBX = System I/O Buffer header address
 23573                              <1> 	;
 23574                              <1>         ; OUTPUTS -> cf=0 --> done 
 23575                              <1> 	; 	     cf=1 ---> error code in AH
 23576                              <1> 	;
 23577                              <1> 	; (Modified registers: eAX, eCX, eDX)
 23578                              <1> 	
 23579                              <1> ;rw_disk_sector:
 23580                              <1> 	; 10/07/2015
 23581                              <1> 	; 02/07/2015
 23582                              <1> 	; 11/06/2015 - Retro UNIX 386 v1 - 'u8.s' 
 23583                              <1> 	; 21/02/2015 ('dsectpm.s', 'read_disk_sector')
 23584                              <1> 	; 16/02/2015 (Retro UNIX 386 v1 test - 'unix386.s')
 23585                              <1> 	; 01/12/2014 - 18/01/2015 ('dsectrm2.s')
 23586                              <1> 	;
 23587                              <1> 	;mov	dx, 0201h ; Read 1 sector/block
 23588 000063AE B602                <1> 	mov	dh, 2
 23589 000063B0 668B03              <1> 	mov	ax, [ebx] 
 23590                              <1> 	;
 23591 000063B3 56                  <1> 	push	esi ; ****
 23592 000063B4 53                  <1> 	push	ebx ; ***
 23593                              <1> 	;
 23594 000063B5 0FB6C8              <1> 	movzx	ecx, al
 23595 000063B8 89CE                <1> 	mov	esi, ecx
 23596                              <1> 	;
 23597 000063BA 38F1                <1> 	cmp	cl, dh ; 2
 23598 000063BC 7202                <1> 	jb	short rwdsk0
 23599 000063BE 047E                <1> 	add	al, 7Eh  ; 80h, 81h, 82h, 83h
 23600                              <1> rwdsk0:
 23601 000063C0 A2[D56D0000]        <1> 	mov	[drv], al
 23602 000063C5 81C6[246E0000]      <1> 	add	esi, drv.status
 23603                              <1> 	; 11/06/2015
 23604 000063CB 803EF0              <1> 	cmp	byte [esi], 0F0h 
 23605 000063CE 720F                <1> 	jb      short rwdsk1
 23606                              <1> 	; 'drive not ready' error
 23607 000063D0 C705[D5740000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 23608 000063D8 0000                <1>
 23609 000063DA E99DDCFFFF          <1> 	jmp	error
 23610                              <1> rwdsk1:
 23611 000063DF F6C402              <1> 	test	ah, 2
 23612                              <1> 	;test	ax, 200h ; Bit 9 of word 0 (status word)
 23613                              <1> 			   ; write bit
 23614 000063E2 7402                <1> 	jz	short rwdsk2
 23615                              <1> 	;test	ah, 4
 23616                              <1> 	;;test	ax, 400h ; Bit 10 of word 0 (status word)
 23617                              <1> 	;		 ; read bit
 23618                              <1> 	;jz	short diskio_ret
 23619 000063E4 FEC6                <1> 	inc	dh ; 03h = write
 23620                              <1> rwdsk2:
 23621 000063E6 88C2                <1> 	mov	dl, al
 23622 000063E8 83C304              <1> 	add	ebx, 4 ; sector/block address/number pointer
 23623 000063EB 8B03                <1> 	mov	eax, [ebx] ; sector/block number (LBA)
 23624 000063ED C0E102              <1> 	shl	cl, 2
 23625 000063F0 81C1[086E0000]      <1> 	add	ecx, drv.size ; disk size
 23626 000063F6 3B01                <1> 	cmp	eax, [ecx] ; Last sector + 1 (number of secs.)
 23627 000063F8 720F                <1> 	jb      short rwdsk3
 23628                              <1>  	; 'out of volume' error
 23629 000063FA C705[D5740000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE 	
 23630 00006402 0000                <1>
 23631 00006404 E973DCFFFF          <1> 	jmp	error
 23632                              <1> rwdsk3:
 23633                              <1> 	; 11/06/2015
 23634 00006409 83C304              <1> 	add	ebx, 4 ; buffer address
 23635 0000640C C605[06750000]04    <1> 	mov	byte [retry_count], 4
 23636 00006413 F60601              <1> 	test	byte [esi], 1 ; LBA ready ?
 23637 00006416 7432                <1>         jz      short rwdsk_chs
 23638                              <1> rwdsk_lba:
 23639                              <1> 	; LBA read/write (with private LBA function) 
 23640                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 23641 00006418 83C607              <1>         add     esi, drv.error - drv.status ; 10/07/2015
 23642 0000641B 89C1                <1> 	mov	ecx, eax ; sector number
 23643                              <1> 	; ebx = buffer (data) address
 23644                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
 23645                              <1> rwdsk_lba_retry:
 23646                              <1> 	;mov	dl, [drv]
 23647                              <1> 		; Function 1Bh = LBA read, 1Ch = LBA write
 23648 0000641D B419                <1> 	mov	ah, 1Ch - 3h ; LBA write function number - 3
 23649 0000641F 00F4                <1> 	add	ah, dh		
 23650 00006421 B001                <1> 	mov	al, 1
 23651                              <1> 	;int	13h
 23652 00006423 E8DBC3FFFF          <1> 	call	int13h
 23653 00006428 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 23654 0000642A 730E                <1> 	jnc	short rwdsk_lba_ok
 23655 0000642C 80FC80              <1> 	cmp	ah, 80h ; time out ?
 23656 0000642F 7408                <1>         je      short rwdsk_lba_fails
 23657 00006431 FE0D[06750000]      <1> 	dec	byte [retry_count]
 23658 00006437 7504                <1>         jnz     short rwdsk_lba_reset ; 10/07/2015
 23659                              <1> rwdsk_lba_fails:
 23660 00006439 F9                  <1> 	stc
 23661                              <1> rwdsk_lba_ok:
 23662 0000643A 5B                  <1> 	pop	ebx ; ***
 23663 0000643B 5E                  <1> 	pop	esi ; ****
 23664 0000643C C3                  <1> 	retn
 23665                              <1> rwdsk_lba_reset:
 23666 0000643D B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 23667                              <1> 	;int	13h
 23668 0000643F E8BFC3FFFF          <1>         call	int13h
 23669 00006444 73D7                <1> 	jnc     short rwdsk_lba_retry
 23670 00006446 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 23671 00006448 EBF0                <1> 	jmp	short rwdsk_lba_ok
 23672                              <1> 	;
 23673                              <1> 	; CHS read (convert LBA address to CHS values)	
 23674                              <1> rwdsk_chs:
 23675                              <1> 	; 10/07/2015
 23676 0000644A 81EE[246E0000]      <1> 	sub	esi, drv.status
 23677 00006450 89F1                <1> 	mov	ecx, esi
 23678 00006452 81C6[2B6E0000]      <1> 	add 	esi, drv.error
 23679                              <1> 	; 02/07/2015
 23680                              <1> 	; 16/06/2015
 23681                              <1>  	; 11/06/2015 
 23682 00006458 53                  <1> 	push	ebx ; ** ; buffer
 23683 00006459 D1E1                <1> 	shl	ecx, 1
 23684 0000645B 51                  <1> 	push	ecx ; * 
 23685                              <1> 	;
 23686 0000645C 89CB                <1> 	mov	ebx, ecx
 23687 0000645E 8835[05750000]      <1> 	mov	[rwdsk], dh ; 02/07/2015
 23688 00006464 31D2                <1> 	xor	edx, edx ; 0
 23689 00006466 29C9                <1> 	sub	ecx, ecx 
 23690 00006468 81C3[FA6D0000]      <1>         add     ebx, drv.spt
 23691 0000646E 668B0B              <1> 	mov	cx, [ebx] ; sector per track
 23692                              <1> 		; EDX:EAX = LBA
 23693 00006471 F7F1                <1> 	div	ecx
 23694 00006473 88D1                <1> 	mov	cl, dl	; sector number - 1
 23695 00006475 FEC1                <1> 	inc	cl	; sector number (1 based)
 23696 00006477 5B                  <1> 	pop	ebx ; * ; 11/06/2015
 23697 00006478 6651                <1> 	push	cx
 23698 0000647A 81C3[EC6D0000]      <1>         add     ebx, drv.heads
 23699 00006480 668B0B              <1> 	mov	cx, [ebx] ; heads
 23700 00006483 31D2                <1> 	xor	edx, edx
 23701                              <1> 		; EAX = cylinders * heads + head
 23702 00006485 F7F1                <1> 	div	ecx
 23703 00006487 6659                <1> 	pop	cx     ; sector number
 23704 00006489 88D6                <1> 	mov	dh, dl ; head number
 23705 0000648B 8A15[D56D0000]      <1> 	mov	dl, [drv]
 23706 00006491 88C5                <1> 	mov	ch, al ; cylinder (bits 0-7)
 23707 00006493 C0E406              <1> 	shl	ah, 6
 23708 00006496 08E1                <1> 	or	cl, ah ; cylinder (bits 8-9)
 23709                              <1> 		       ; sector (bits 0-7)
 23710 00006498 5B                  <1> 	pop	ebx ; ** ; buffer ; 11/06/2015
 23711                              <1> 		; CL = sector (bits 0-5)
 23712                              <1> 		;      cylinder (bits 8-9 -> bits 6-7)
 23713                              <1> 		; CH = cylinder (bits 0-7)
 23714                              <1> 		; DH = head
 23715                              <1> 		; DL = drive
 23716                              <1> 	;
 23717 00006499 C605[06750000]04    <1> 	mov	byte [retry_count], 4
 23718                              <1> rwdsk_retry:	
 23719 000064A0 8A25[05750000]      <1> 	mov	ah, [rwdsk] ; 02h = read, 03h = write
 23720 000064A6 B001                <1> 	mov	al, 1 ; sector count	
 23721                              <1> 	;int	13h
 23722 000064A8 E856C3FFFF          <1> 	call	int13h
 23723 000064AD 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 23724 000064AF 730E                <1> 	jnc	short rwdsk_ok ; ah = 0
 23725 000064B1 80FC80              <1> 	cmp	ah, 80h ; time out ?
 23726 000064B4 7408                <1> 	je	short rwdsk_fails
 23727 000064B6 FE0D[06750000]      <1> 	dec	byte [retry_count]
 23728 000064BC 7504                <1> 	jnz	short rwdsk_reset
 23729                              <1> rwdsk_fails:
 23730 000064BE F9                  <1> 	stc
 23731                              <1> rwdsk_ok:
 23732 000064BF 5B                  <1> 	pop	ebx ; ***
 23733 000064C0 5E                  <1> 	pop	esi ; ****
 23734 000064C1 C3                  <1> 	retn
 23735                              <1> rwdsk_reset:
 23736                              <1> 	; 02/02/2015
 23737 000064C2 28E4                <1> 	sub	ah, ah
 23738 000064C4 80FA80              <1> 	cmp	dl, 80h
 23739 000064C7 7202                <1> 	jb	short rwdsk_fd_reset
 23740 000064C9 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 23741                              <1> rwdsk_fd_reset:
 23742                              <1> 	;int	13h
 23743 000064CB E833C3FFFF          <1>         call	int13h
 23744 000064D0 73CE                <1> 	jnc	short rwdsk_retry
 23745 000064D2 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 23746 000064D4 EBE9                <1> 	jmp 	short rwdsk_ok
 23747                              <1> 
 23748                              <1> 
 23749                              <1> ; Original UNIX v1 - drum (& disk) interrupt routine
 23750                              <1> ;	(Equivalent to IRQ 14 & IRQ 15 disk/hardware interrupts)
 23751                              <1> ;
 23752                              <1> ; This feature is not used in Retro UNIX 386 (& 8086) for now.
 23753                              <1> ; Because, current Retro UNIX 386 disk I/O -INT13H- routine is 
 23754                              <1> ; derived from IBM PC AT -infact: XT286- BIOS source code, int 13h
 23755                              <1> ; that uses hardware -transfer has been completed-  interrupt inside it. 
 23756                              <1> ; In a next Retro UNIX 386 version, these interrupts
 23757                              <1> ; (fdc_int, hdc1_int, hdc2_int) will be handled by a separate routine
 23758                              <1> ; as in original unix v1.
 23759                              <1> ; I am not removing IBM BIOS source code derivatives -compatible code-
 23760                              <1> ; for now, regarding the new/next 32 bit TRDOS project by me
 23761                              <1> ; (to keep source code files easy adaptable to 32 bit TRDOS.)
 23762                              <1> ;
 23763                              <1> ; Erdogan tan (10/07/2015) 
 23764                              <1> 
 23765                              <1> ;drum: / interrupt handler
 23766                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 23767                              <1> ;       jsr     r0,trapt; dcs; rfap; 1 / check for stray interrupt or
 23768                              <1> ;                                      / error
 23769                              <1> ;               br 3f / no, error
 23770                              <1> ;       br      2f / error
 23771                              <1> ;
 23772                              <1> ;disk:
 23773                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 23774                              <1> ;       jmp     *$0f
 23775                              <1> ;0:
 23776                              <1> ;       jsr     r0,trapt; rkcs; rkap; 2
 23777                              <1> ;      	        br 3f / no, errors
 23778                              <1> ;       mov     $115,(r2) / drive reset, errbit was set
 23779                              <1> ;       mov     $1f,0b-2 / next time jmp *$0f is executed jmp will be
 23780                              <1> ;                        / to 1f
 23781                              <1> ;       br      4f
 23782                              <1> ;1:
 23783                              <1> ;       bit     $20000,rkcs
 23784                              <1> ;       beq     4f / wait for seek complete
 23785                              <1> ;       mov     $0b,0b-2
 23786                              <1> ;       mov     rkap,r1
 23787                              <1> ;2:
 23788                              <1> ;       bit     $3000,(r1) / are bits 9 or 10 set in the 1st word of
 23789                              <1> ;                          / the disk buffer
 23790                              <1> ;       bne     3f / no, branch ignore error if outstanding
 23791                              <1> ;       inc     r1
 23792                              <1> ;       asr     (r1)
 23793                              <1> ;       asr     (r1)
 23794                              <1> ;       asr     (r1) / reissue request
 23795                              <1> ;       dec     r1
 23796                              <1> ;3:
 23797                              <1> ;       bic     $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
 23798                              <1> ;       mov     ac,-(sp)
 23799                              <1> ;       mov     mq,-(sp) / put these on the stack
 23800                              <1> ;       mov     sc,-(sp)
 23801                              <1> ;       jsr     r0,poke
 23802                              <1> ;       mov     (sp)+,sc
 23803                              <1> ;       mov     (sp)+,mq / pop them off stack
 23804                              <1> ;       mov     (sp)+,ac
 23805                              <1> ;4:
 23806                              <1> ;       jmp     retisp / u4-3
 23807                              <1> ;
 23808                              <1> ;trapt:                  / r2 points to the
 23809                              <1> ;       mov     (r0)+,r2 / device control register
 23810                              <1> ;       mov     *(r0)+,r1 / transaction pointer points to buffer
 23811                              <1> ;       tst     (sp)+
 23812                              <1> ;       tstb    (r2) / is ready bit of dcs set?
 23813                              <1> ;       bge     4b / device still active so branch
 23814                              <1> ;       bit     (r0),active / was device busy?
 23815                              <1> ;       beq     4b / no, stray interrupt
 23816                              <1> ;       bic     (r0)+,active / yes, set active to zero
 23817                              <1> ;       tst     (r2) / test the err(bit is) of dcs
 23818                              <1> ;       bge     2f / if no error jump to 2f
 23819                              <1> ;       tst     (r0)+ / skip on error
 23820                              <1> ; 2:
 23821                              <1> ;       jmp     (r0)
 23822                                  %include 'u9.s'        ; 29/06/2015
 23823                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
 23824                              <1> ; Last Modification: 09/12/2015
 23825                              <1> ; ----------------------------------------------------------------------------
 23826                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 23827                              <1> ; (v0.1 - Beginning: 11/07/2012)
 23828                              <1> ;
 23829                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 23830                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 23831                              <1> ; <Bell Laboratories (17/3/1972)>
 23832                              <1> ; <Preliminary Release of UNIX Implementation Document>
 23833                              <1> ;
 23834                              <1> ; Retro UNIX 8086 v1 - U9.ASM (01/09/2014) //// UNIX v1 -> u9.s
 23835                              <1> ;
 23836                              <1> ; ****************************************************************************
 23837                              <1> 
 23838                              <1> getch:
 23839                              <1> 	; 30/06/2015
 23840                              <1> 	; 18/02/2015 - Retro UNIX 386 v1 - feature only!
 23841 000064D6 28C0                <1> 	sub	al, al ; 0
 23842                              <1> getch_q: ; 06/08/2015
 23843 000064D8 8A25[D6700000]      <1> 	mov 	ah, [ptty] ; active (current) video page
 23844 000064DE EB06                <1>         jmp     short getc_n
 23845                              <1> 
 23846                              <1> getc: 
 23847                              <1> 	; 12/11/2015
 23848                              <1> 	; 15/09/2015
 23849                              <1> 	; 01/07/2015
 23850                              <1> 	; 30/06/2015
 23851                              <1> 	; 18/02/2015 (Retro UNIX 386 v1 - Beginning)
 23852                              <1> 	; 13/05/2013 - 04/07/2014 (Retro UNIX 8086 v1)
 23853                              <1> 	;
 23854                              <1> 	; Retro UNIX 8086 v1 modification !
 23855                              <1> 	; 
 23856                              <1> 	; 'getc' gets (next) character 
 23857                              <1> 	;	 from requested TTY (keyboard) buffer 
 23858                              <1> 	; INPUTS ->
 23859                              <1> 	;     [u.ttyn] = tty number (0 to 7) (8 is COM1, 9 is COM2)	
 23860                              <1> 	;     AL=0 -> Get (next) character from requested TTY buffer
 23861                              <1> 	;	(Keyboard buffer will point to 
 23862                              <1> 	;			next character at next call)
 23863                              <1> 	;     AL=1 -> Test a key is available in requested TTY buffer
 23864                              <1> 	;	(Keyboard buffer will point to 
 23865                              <1> 	;			current character at next call)
 23866                              <1> 	; OUTPUTS ->
 23867                              <1> 	;     (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 23868                              <1> 	;     			 ZF=0 -> AX has (current) character
 23869                              <1> 	;      AL = ascii code
 23870                              <1> 	;      AH = scan code	(AH = line status for COM1 or COM2)	 			
 23871                              <1> 	; 		        (cf=1 -> error code/flags in AH)
 23872                              <1> 	; Original UNIX V1 'getc': 
 23873                              <1> 	;		get a character off character list
 23874                              <1> 	;
 23875                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))	
 23876                              <1> 	;
 23877                              <1> 	; 30/06/20045 (32 bit modifications)
 23878                              <1> 	; 16/07/2013
 23879                              <1> 	; mov 	[getctty], ah
 23880                              <1> 	;
 23881                              <1> 
 23882 000064E0 8A25[D4740000]      <1> 	mov	ah, [u.ttyn] 	; 28/07/2013
 23883                              <1> getc_n:
 23884                              <1> 	; 30/06/2015
 23885 000064E6 08E4                <1> 	or	ah, ah
 23886 000064E8 740D                <1> 	jz	short getc0 
 23887 000064EA D0E4                <1> 	shl	ah, 1
 23888 000064EC 0FB6DC              <1> 	movzx	ebx, ah
 23889 000064EF 81C3[D8700000]      <1> 	add	ebx, ttychr
 23890 000064F5 EB05                <1> 	jmp	short getc1
 23891                              <1> getc0:
 23892 000064F7 BB[D8700000]        <1> 	mov	ebx, ttychr
 23893                              <1> getc1:
 23894 000064FC 668B0B              <1> 	mov	cx, [ebx] 	; ascii & scan code
 23895                              <1> 				; (by kb_int)	
 23896 000064FF 6609C9              <1> 	or	cx, cx
 23897 00006502 7508                <1> 	jnz	short getc2
 23898 00006504 20C0                <1> 	and 	al, al
 23899 00006506 7416                <1> 	jz	short getc_s
 23900 00006508 6631C0              <1> 	xor	ax, ax
 23901 0000650B C3                  <1> 	retn
 23902                              <1> getc2:	
 23903 0000650C 20C0                <1> 	and	al, al
 23904 0000650E 6689C8              <1> 	mov	ax, cx
 23905 00006511 66B90000            <1> 	mov	cx, 0
 23906 00006515 7506                <1> 	jnz	short getc3
 23907                              <1> getc_sn:
 23908 00006517 66890B              <1> 	mov	[ebx], cx ; 0, reset
 23909 0000651A 6639C8              <1> 	cmp	ax, cx  ; zf = 0
 23910                              <1> getc3:
 23911 0000651D C3                  <1> 	retn
 23912                              <1> getc_s:
 23913                              <1> 	; 12/11/2015
 23914                              <1> 	; 15/09/2015
 23915                              <1> 	; 01/07/2015
 23916                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 23917                              <1> 	; 16/07/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 23918                              <1> 	;
 23919                              <1> 	; tty  of the current process is not 
 23920                              <1> 	; current tty (ptty); so, current process only 
 23921                              <1> 	; can use keyboard input when its tty becomes 
 23922                              <1> 	; current tty (ptty).
 23923                              <1> 	; 'sleep' is for preventing an endless lock
 23924                              <1> 	; during this tty input request.
 23925                              <1> 	; (Because, the user is not looking at the video page
 23926                              <1> 	; of the process to undersand there is a keyboard
 23927                              <1> 	; input request.)
 23928                              <1> 	;
 23929                              <1> 	;((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 23930                              <1> 	;
 23931                              <1> 	; 05/10/2013
 23932                              <1> 	; ah = byte ptr [u.ttyn] ; (tty number)
 23933                              <1> 	;
 23934                              <1> 	; 10/10/2013
 23935                              <1> gcw0:
 23936 0000651E B10A                <1> 	mov	cl, 10 ; ch = 0
 23937                              <1> gcw1:	
 23938                              <1> 	; 12/11/2015
 23939 00006520 E859DCFFFF          <1> 	call intract ; jumps to 'sysexit' if [u.quit] = FFFFh
 23940                              <1> 	; 10/10/2013
 23941 00006525 E871EFFFFF          <1> 	call	idle
 23942 0000652A 668B03              <1> 	mov	ax, [ebx] 	; ascii & scan code
 23943                              <1> 				; (by kb_int)
 23944 0000652D 6609C0              <1> 	or	ax, ax
 23945                              <1> ;	jnz	short gcw3
 23946 00006530 7519                <1> 	jnz	short gcw2 ; 15/09/2015
 23947                              <1> 	; 30/06/2015
 23948 00006532 FEC9                <1> 	dec	cl
 23949 00006534 75EA                <1> 	jnz	short gcw1
 23950                              <1> 	;
 23951 00006536 8A25[D4740000]      <1> 	mov	ah, [u.ttyn] 	; 20/10/2013
 23952                              <1> ;	; 10/12/2013
 23953                              <1> ;	cmp 	ah, [ptty]
 23954                              <1> ;	jne	short gcw2
 23955                              <1> ;	; 14/02/2014
 23956                              <1> ;	cmp	byte [u.uno], 1
 23957                              <1> ;	jna	short gcw0		
 23958                              <1> ;gcw2:
 23959 0000653C E8EEEFFFFF          <1> 	call	sleep
 23960                              <1> 	;
 23961                              <1> 	; 20/09/2013
 23962 00006541 8A25[D4740000]      <1> 	mov	ah, [u.ttyn]
 23963 00006547 30C0                <1> 	xor 	al, al
 23964 00006549 EB9B                <1> 	jmp	short getc_n
 23965                              <1> ;gcw3:
 23966                              <1> gcw2: 	; 15/09/2015
 23967                              <1> 	; 10/10/2013
 23968 0000654B 30C9                <1> 	xor	cl, cl
 23969 0000654D EBC8                <1> 	jmp	short getc_sn
 23970                              <1> 
 23971                              <1> sndc:   ; <Send character>
 23972                              <1> 	;
 23973                              <1> 	; 17/11/2015
 23974                              <1> 	; 16/11/2015
 23975                              <1> 	; 11/11/2015
 23976                              <1> 	; 10/11/2015
 23977                              <1> 	; 09/11/2015
 23978                              <1> 	; 08/11/2015
 23979                              <1> 	; 07/11/2015
 23980                              <1> 	; 06/11/2015 (serial4.asm, 'sendchr')	
 23981                              <1> 	; 29/10/2015
 23982                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 23983                              <1> 	; 14/05/2013 - 28/07/2014 (Retro UNIX 8086 v1)
 23984                              <1> 	;
 23985                              <1> 	; Retro UNIX 8086 v1 feature only !
 23986                              <1> 	;
 23987                              <1> 	; ah = [u.ttyn]
 23988                              <1> 	;
 23989                              <1> 	; 30/06/2015
 23990 0000654F 80EC08              <1> 	sub	ah, 8 ; ; 0 = tty8 or 1 = tty9
 23991                              <1> 	; 07/11/2015
 23992 00006552 0FB6DC              <1> 	movzx	ebx, ah ; serial port index (0 or 1)
 23993                              <1> sndc0:
 23994                              <1> 	; 07/11/2015
 23995 00006555 E82EF0FFFF          <1> 	call	isintr ; quit (ctrl+break) check
 23996 0000655A 7405                <1> 	jz	short sndc1
 23997 0000655C E81DDCFFFF          <1> 	call	intract ; quit (ctrl+break) check
 23998                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 23999                              <1> sndc1:
 24000                              <1> 	; 16/11/2015
 24001 00006561 6689C1              <1> 	mov	cx, ax	; *** al = character (to be sent)
 24002                              <1> sndcx:
 24003 00006564 8A83[1A710000]      <1> 	mov	al, [ebx+schar] ; last sent character
 24004 0000656A 8AA3[18710000]      <1> 	mov	ah, [ebx+rchar] ; last received character
 24005                              <1> 	;
 24006                              <1> 	; 17/11/2015
 24007                              <1> 	; check 'request for response' status
 24008 00006570 80BB[14710000]00    <1> 	cmp	byte [ebx+req_resp], 0
 24009 00006577 740A                <1> 	jz	short query
 24010                              <1> response:
 24011 00006579 FE05[17710000]      <1> 	inc 	byte [comqr] ; query or response status
 24012 0000657F B0FF                <1> 	mov	al, 0FFh	 
 24013 00006581 EB14                <1> 	jmp	short sndc3
 24014                              <1> query:
 24015 00006583 08C0                <1> 	or 	al, al  ; 0 = query (also end of text)
 24016 00006585 750E                <1> 	jnz 	short sndc2 ; normal character
 24017                              <1> 	;cmp 	ah, 0FFh     ; is it responded by terminal ?
 24018                              <1> 	;je	short sndc2  ; yes, already responded
 24019                              <1> 	; 16/11/2015
 24020                              <1> 	; query: request for response (again)
 24021 00006587 8883[18710000]      <1> 	mov	[ebx+rchar], al ; 0 ; reset
 24022 0000658D FE05[17710000]      <1> 	inc 	byte [comqr] ; query or response status
 24023 00006593 EB02                <1> 	jmp	short sndc3
 24024                              <1> sndc2:
 24025 00006595 88C8                <1> 	mov	al, cl 	; *** character (to be sent)
 24026                              <1> sndc3:
 24027 00006597 8883[1A710000]      <1> 	mov	[ebx+schar], al ; current character (to be sent)
 24028 0000659D 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 24029                              <1> 	; 30/06/2015
 24030 0000659F E87DD5FFFF          <1> 	call	sp_status ; get serial port status
 24031                              <1> 	; AL = Line status, AH = Modem status
 24032                              <1> 	; 07/11/2015
 24033 000065A4 A880                <1> 	test	al, 80h
 24034 000065A6 7504                <1> 	jnz	short sndc4
 24035 000065A8 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 24036 000065AA 751D                <1> 	jnz	short sndc5
 24037                              <1> sndc4: 	; Check line status again
 24038                              <1> 	; 16/11/2015
 24039 000065AC 6651                <1> 	push	cx
 24040 000065AE B906000000          <1> 	mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 24041 000065B3 E874B0FFFF          <1> 	call	WAITF
 24042 000065B8 6659                <1> 	pop	cx
 24043                              <1> 	;
 24044 000065BA 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 24045 000065BC E860D5FFFF          <1> 	call	sp_status ; get serial port status
 24046                              <1> 	; 16/11/2015
 24047                              <1> 	; 09/11/2015
 24048                              <1> 	; 08/11/2015
 24049 000065C1 A880                <1> 	test	al, 80h	; time out error
 24050 000065C3 756C                <1>         jnz     short sndc7
 24051 000065C5 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 24052 000065C7 7468                <1>         jz	short sndc7
 24053                              <1> sndc5:  
 24054 000065C9 8A83[1A710000]      <1> 	mov	al, [ebx+schar] ; character (to be sent)
 24055 000065CF 66BAF803            <1> 	mov	dx, 3F8h   ; data port (COM2)
 24056 000065D3 28DE                <1> 	sub	dh, bl
 24057 000065D5 EE                  <1> 	out	dx, al	   ; send on serial port
 24058                              <1> 	; 10/11/2015
 24059                              <1> 	; delay for 3*30 (3*(15..80)) micro seconds
 24060                              <1> 	; (to improve text flow to the terminal)
 24061                              <1> 	; ('diskette.inc': 'WAITF')
 24062                              <1> 	; Uses port 61h, bit 4 to have CPU speed independent waiting.
 24063                              <1> 	; (refresh periods = 1 per 30 microseconds on most machines)
 24064 000065D6 6651                <1> 	push	cx 
 24065 000065D8 B906000000          <1> 	mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 24066 000065DD E84AB0FFFF          <1> 	call	WAITF
 24067 000065E2 6659                <1> 	pop	cx
 24068                              <1>     	;
 24069                              <1> 	; 07/11/2015
 24070 000065E4 88D8                <1> 	mov	al, bl ; al = 0 (tty8) or 1 (tty9)
 24071                              <1> 	;
 24072 000065E6 E836D5FFFF          <1> 	call	sp_status ; get serial port status
 24073                              <1> 	; AL = Line status, AH = Modem status
 24074                              <1> 	;
 24075 000065EB E898EFFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 24076 000065F0 7405                <1> 	jz	short sndc6
 24077 000065F2 E887DBFFFF          <1> 	call	intract ; quit (ctrl+break) check
 24078                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 24079                              <1> sndc6:
 24080 000065F7 3C80                <1> 	cmp	al, 80h
 24081 000065F9 7336                <1> 	jnb	short sndc7		
 24082                              <1> 	;
 24083 000065FB 803D[17710000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 24084 00006602 7248                <1> 	jb	short sndc8 	; no, normal character
 24085 00006604 883D[17710000]      <1> 	mov 	byte [comqr], bh ; 0 ; reset
 24086                              <1> 	; 17/11/2015
 24087 0000660A E88CEEFFFF          <1> 	call	idle
 24088                              <1> 	;
 24089 0000660F 38BB[1A710000]      <1> 	cmp	[ebx+schar], bh ; 0 ; query ?
 24090 00006615 0F877AFFFFFF        <1>         ja      sndc2       ; response (will be followed by
 24091                              <1> 			    ; a normal character)
 24092                              <1> 	; Query request must be responded by the terminal
 24093                              <1> 	; before sending a normal character !
 24094 0000661B 53                  <1> 	push	ebx
 24095 0000661C 6651                <1> 	push	cx ; *** cl = character (to be sent)
 24096 0000661E 8A25[D4740000]      <1> 	mov	ah, [u.ttyn]
 24097 00006624 E806EFFFFF          <1> 	call	sleep ; this process will be awakened by
 24098                              <1> 		      ; received data available interrupt
 24099 00006629 6659                <1> 	pop	cx ; *** cl = character (to be sent)
 24100 0000662B 5B                  <1> 	pop	ebx
 24101 0000662C E933FFFFFF          <1>         jmp	sndcx
 24102                              <1> sndc7:
 24103                              <1> 	 ; 16/11/2015
 24104 00006631 803D[17710000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 24105 00006638 7213                <1> 	jb	short sndc9 	; no
 24106                              <1> 	;
 24107 0000663A 88BB[18710000]      <1> 	mov	[ebx+rchar], bh ; 0 ; reset
 24108 00006640 88BB[1A710000]      <1> 	mov	[ebx+schar], bh ; 0 ; reset
 24109                              <1> 	;
 24110 00006646 883D[17710000]      <1> 	mov	byte [comqr], bh ; 0 ; reset  
 24111                              <1> sndc8:
 24112 0000664C F5                  <1> 	cmc  ; jnc -> jc, jb -> jnb
 24113                              <1> sndc9:
 24114                              <1> 	; AL = Line status, AH = Modem status
 24115 0000664D C3                  <1> 	retn
 24116                              <1> 
 24117                              <1> putc:	
 24118                              <1> 	; 13/08/2015
 24119                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 24120                              <1> 	; 15/05/2013 - 27/07/2014 (Retro UNIX 8086 v1)
 24121                              <1> 	;
 24122                              <1> 	; Retro UNIX 8086 v1 modification !
 24123                              <1> 	; 
 24124                              <1> 	; 'putc' puts a character 
 24125                              <1> 	;	 onto requested (tty) video page or
 24126                              <1> 	;	 serial port
 24127                              <1> 	; INPUTS ->
 24128                              <1> 	;     AL = ascii code of the character
 24129                              <1> 	;     AH = video page (tty) number (0 to 7)
 24130                              <1> 	;			  (8 is COM1, 9 is COM2)	
 24131                              <1> 	; OUTPUTS ->
 24132                              <1> 	;    (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 24133                              <1> 	;      			ZF=0 -> AX has (current) character
 24134                              <1> 	;     cf=0 and AH = 0 -> no error
 24135                              <1> 	;     cf=1 and AH > 0 -> error (only for COM1 and COM2)		 			
 24136                              <1> 	; 
 24137                              <1> 	; Original UNIX V1 'putc': 
 24138                              <1> 	;     put a character at the end of character list
 24139                              <1> 	;
 24140                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 24141                              <1> 	;
 24142 0000664E 80FC07              <1> 	cmp	ah, 7
 24143 00006651 0F87F8FEFFFF        <1>         ja      sndc
 24144                              <1> 	; 30/06/2015
 24145 00006657 0FB6DC              <1> 	movzx	ebx, ah
 24146                              <1> 	; 13/08/2015
 24147 0000665A B407                <1> 	mov	ah, 07h ; black background, light gray character color
 24148 0000665C E9BCAEFFFF          <1> 	jmp	write_tty ; 'video.inc'
 24149                              <1> 
 24150                              <1> get_cpos:
 24151                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 24152                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 24153                              <1> 	;
 24154                              <1> 	; INPUT -> bl = video page number
 24155                              <1> 	; RETURN -> dx = cursor position
 24156                              <1> 
 24157 00006661 53                  <1> 	push	ebx
 24158 00006662 83E30F              <1> 	and	ebx, 0Fh ; 07h ; tty0 to tty7
 24159 00006665 D0E3                <1> 	shl	bl, 1
 24160 00006667 81C3[C6700000]      <1> 	add	ebx, cursor_posn
 24161 0000666D 668B13              <1> 	mov	dx, [ebx]
 24162 00006670 5B                  <1> 	pop	ebx
 24163 00006671 C3                  <1> 	retn
 24164                              <1> 
 24165                              <1> read_ac_current:
 24166                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 24167                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 24168                              <1> 	;
 24169                              <1> 	; INPUT -> bl = video page number
 24170                              <1> 	; RETURN -> ax = character (al) and attribute (ah)
 24171                              <1> 
 24172 00006672 E827B0FFFF          <1> 	call 	find_position ; 'video.inc'
 24173                              <1> 	; dx = status port
 24174                              <1> 	; esi = cursor location/address
 24175 00006677 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
 24176 0000667D 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
 24177 00006680 C3                  <1> 	retn
 24178                              <1> 
 24179                              <1> syssleep:
 24180                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
 24181                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
 24182                              <1> 	;
 24183                              <1> 	; Retro UNIX 8086 v1 feature only
 24184                              <1> 	; (INPUT -> none)
 24185                              <1> 	;
 24186 00006681 0FB61D[CF740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 24187 00006688 8AA3[D5710000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 24188 0000668E E89CEEFFFF          <1> 	call	sleep
 24189 00006693 E904DAFFFF          <1> 	jmp	sysret
 24190                              <1> 
 24191                              <1> vp_clr:
 24192                              <1> 	; Reset/Clear Video Page
 24193                              <1> 	;
 24194                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
 24195                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
 24196                              <1> 	;
 24197                              <1> 	; Retro UNIX 8086 v1 feature only !
 24198                              <1> 	;
 24199                              <1> 	; INPUTS -> 
 24200                              <1> 	;   BL = video page number	 
 24201                              <1> 	;
 24202                              <1> 	; OUTPUT ->
 24203                              <1> 	;   none
 24204                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
 24205                              <1> 	;
 24206                              <1> 	; 04/12/2013
 24207 00006698 28C0                <1> 	sub	al, al
 24208                              <1> 	; al = 0 (clear video page)
 24209                              <1> 	; bl = video page
 24210 0000669A B407                <1> 	mov	ah, 07h
 24211                              <1> 	; ah = 7 (attribute/color)
 24212 0000669C 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
 24213 0000669F 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
 24214 000066A3 E822B0FFFF          <1> 	call	scroll_up
 24215                              <1> 	; bl = video page
 24216 000066A8 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
 24217 000066AB E991AFFFFF          <1> 	jmp 	set_cpos
 24218                              <1> 
 24219                              <1> sysmsg:
 24220                              <1> 	; 11/11/2015
 24221                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
 24222                              <1> 	; Print user-application message on user's console tty
 24223                              <1> 	;
 24224                              <1> 	; Input -> EBX = Message address
 24225                              <1> 	;	   ECX = Message length (max. 255)
 24226                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
 24227                              <1> 	;
 24228 000066B0 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
 24229 000066B6 0F87E0D9FFFF        <1> 	ja	sysret ; nothing to do with big message size
 24230 000066BC 08C9                <1> 	or	cl, cl
 24231 000066BE 0F84D8D9FFFF        <1> 	jz	sysret
 24232 000066C4 20D2                <1> 	and	dl, dl
 24233 000066C6 7502                <1> 	jnz	short sysmsg0
 24234 000066C8 B207                <1> 	mov	dl, 07h ; default color
 24235                              <1> 		; (black background, light gray character) 
 24236                              <1> sysmsg0:
 24237 000066CA 891D[A0740000]      <1> 	mov	[u.base], ebx
 24238 000066D0 8815[D7700000]      <1> 	mov	[ccolor], dl ; color attributes
 24239 000066D6 89E5                <1> 	mov	ebp, esp
 24240 000066D8 31DB                <1> 	xor	ebx, ebx ; 0
 24241 000066DA 891D[A8740000]      <1> 	mov	[u.nread], ebx ; 0
 24242                              <1> 	;
 24243 000066E0 381D[E7740000]      <1> 	cmp	[u.kcall], bl ; 0
 24244 000066E6 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
 24245                              <1> 	;
 24246 000066E8 890D[A4740000]      <1> 	mov	[u.count], ecx
 24247 000066EE 41                  <1> 	inc	ecx ; + 00h ; ASCIZZ
 24248 000066EF 29CC                <1> 	sub	esp, ecx
 24249 000066F1 89E7                <1> 	mov	edi, esp
 24250 000066F3 89E6                <1> 	mov	esi, esp
 24251 000066F5 66891D[E5740000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
 24252                              <1> 	; 11/11/2015
 24253 000066FC 8A25[B0740000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
 24254                              <1> 	; 0 = none
 24255 00006702 FECC                <1> 	dec	ah
 24256 00006704 790C                <1> 	jns	short sysmsg1 
 24257 00006706 8A1D[CF740000]      <1> 	mov	bl, [u.uno] ; process number	
 24258 0000670C 8AA3[D5710000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
 24259                              <1> sysmsg1:
 24260 00006712 8825[D4740000]      <1> 	mov	[u.ttyn], ah
 24261                              <1> sysmsg2:
 24262 00006718 E89CF5FFFF          <1> 	call	cpass
 24263 0000671D 7416                <1> 	jz	short sysmsg5
 24264 0000671F AA                  <1> 	stosb
 24265 00006720 20C0                <1> 	and	al, al
 24266 00006722 75F4                <1> 	jnz	short sysmsg2
 24267                              <1> sysmsg3:
 24268 00006724 80FC07              <1> 	cmp	ah, 7 ; tty number
 24269 00006727 7711                <1> 	ja	short sysmsg6 ; serial port
 24270 00006729 E83E000000          <1> 	call	print_cmsg
 24271                              <1> sysmsg4:
 24272 0000672E 89EC                <1> 	mov	esp, ebp	
 24273 00006730 E967D9FFFF          <1> 	jmp	sysret
 24274                              <1> sysmsg5:
 24275 00006735 C60700              <1> 	mov	byte [edi], 0
 24276 00006738 EBEA                <1> 	jmp	short sysmsg3
 24277                              <1> sysmsg6:
 24278 0000673A 8A06                <1> 	mov	al, [esi]
 24279 0000673C E80EFEFFFF          <1> 	call	sndc
 24280 00006741 72EB                <1> 	jc	short sysmsg4
 24281 00006743 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
 24282 00006746 76E6                <1> 	jna	short sysmsg4
 24283 00006748 46                  <1> 	inc 	esi
 24284 00006749 8A25[D4740000]      <1> 	mov	ah, [u.ttyn]
 24285 0000674F EBE9                <1> 	jmp	short sysmsg6
 24286                              <1> 
 24287                              <1> sysmsgk: ; Temporary (01/07/2015)
 24288                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
 24289                              <1> 	; (ECX -character count- will not be considered)
 24290 00006751 8B35[A0740000]      <1> 	mov	esi, [u.base]
 24291 00006757 8A25[D6700000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
 24292 0000675D 8825[D4740000]      <1> 	mov	[u.ttyn], ah
 24293 00006763 C605[E7740000]00    <1> 	mov	byte [u.kcall], 0
 24294 0000676A EBB8                <1> 	jmp	short sysmsg3
 24295                              <1> 	
 24296                              <1> 
 24297                              <1> print_cmsg: 
 24298                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
 24299                              <1> 	;
 24300                              <1> 	; print message (on user's console tty) 
 24301                              <1> 	;	with requested color
 24302                              <1> 	;
 24303                              <1> 	; INPUTS:
 24304                              <1> 	;	esi = message address
 24305                              <1> 	;	[u.ttyn] = tty number (0 to 7)
 24306                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
 24307                              <1> 	;
 24308 0000676C AC                  <1> 	lodsb
 24309                              <1> pcmsg1:
 24310 0000676D 56                  <1> 	push 	esi
 24311 0000676E 0FB61D[D4740000]    <1>         movzx   ebx, byte [u.ttyn]
 24312 00006775 8A25[D7700000]      <1> 	mov	ah, [ccolor]
 24313 0000677B E89DADFFFF          <1> 	call 	write_tty
 24314 00006780 5E                  <1> 	pop	esi
 24315 00006781 AC                  <1> 	lodsb
 24316 00006782 20C0                <1> 	and 	al, al  ; 0
 24317 00006784 75E7                <1> 	jnz 	short pcmsg1
 24318 00006786 C3                  <1> 	retn
 24319                              <1> 
 24320                              <1> sysgeterr:
 24321                              <1> 	; 09/12/2015
 24322                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
 24323                              <1> 	; Get last error number or page fault count
 24324                              <1> 	; (for debugging)
 24325                              <1> 	;
 24326                              <1> 	; Input -> EBX = return type
 24327                              <1> 	;	   0 = last error code (which is in 'u.error')	
 24328                              <1> 	;	   FFFFFFFFh = page fault count for running process
 24329                              <1> 	;	   FFFFFFFEh = total page fault count
 24330                              <1> 	;	   1 .. FFFFFFFDh = undefined 
 24331                              <1> 	;
 24332                              <1> 	; Output -> EAX = last error number or page fault count
 24333                              <1> 	;	   (depending on EBX input)
 24334                              <1> 	; 	
 24335 00006787 21DB                <1> 	and 	ebx, ebx
 24336 00006789 750B                <1> 	jnz	short glerr_2
 24337                              <1> glerr_0:
 24338 0000678B A1[D5740000]        <1> 	mov	eax, [u.error]
 24339                              <1> glerr_1:
 24340 00006790 A3[80740000]        <1> 	mov	[u.r0], eax
 24341 00006795 C3                  <1>  	retn
 24342                              <1> glerr_2:
 24343 00006796 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
 24344 00006797 74FD                <1> 	jz	short glerr_2 ; page fault count for process
 24345 00006799 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
 24346 0000679A 75EF                <1> 	jnz	short glerr_0
 24347 0000679C A1[58810000]        <1> 	mov	eax, [PF_Count] ; total page fault count
 24348 000067A1 EBED                <1>         jmp     short glerr_1
 24349                              <1> glerr_3:
 24350 000067A3 A1[E9740000]        <1> 	mov 	eax, [u.pfcount]
 24351 000067A8 EBE6                <1> 	jmp	short glerr_1
 24352                                  
 24353                                  ; 07/03/2015
 24354                                  ; Temporary Code
 24355                                  display_disks:
 24356 000067AA 803D[D86D0000]00        	cmp 	byte [fd0_type], 0
 24357 000067B1 7605                    	jna 	short ddsks1
 24358 000067B3 E87D000000              	call	pdskm
 24359                                  ddsks1:
 24360 000067B8 803D[D96D0000]00        	cmp	byte [fd1_type], 0
 24361 000067BF 760C                    	jna	short ddsks2
 24362 000067C1 C605[2B6D0000]31        	mov	byte [dskx], '1'
 24363 000067C8 E868000000              	call	pdskm
 24364                                  ddsks2:
 24365 000067CD 803D[DA6D0000]00        	cmp	byte [hd0_type], 0
 24366 000067D4 7654                    	jna	short ddsk6
 24367 000067D6 66C705[296D0000]68-     	mov	word [dsktype], 'hd'
 24368 000067DE 64                 
 24369 000067DF C605[2B6D0000]30        	mov	byte [dskx], '0'
 24370 000067E6 E84A000000              	call	pdskm
 24371                                  ddsks3:
 24372 000067EB 803D[DB6D0000]00        	cmp	byte [hd1_type], 0
 24373 000067F2 7636                    	jna	short ddsk6
 24374 000067F4 C605[2B6D0000]31        	mov	byte [dskx], '1'
 24375 000067FB E835000000              	call	pdskm
 24376                                  ddsks4:
 24377 00006800 803D[DC6D0000]00        	cmp	byte [hd2_type], 0
 24378 00006807 7621                    	jna	short ddsk6
 24379 00006809 C605[2B6D0000]32        	mov	byte [dskx], '2'
 24380 00006810 E820000000              	call	pdskm
 24381                                  ddsks5:
 24382 00006815 803D[DD6D0000]00        	cmp	byte [hd3_type], 0
 24383 0000681C 760C                    	jna	short ddsk6
 24384 0000681E C605[2B6D0000]33        	mov	byte [dskx], '3'
 24385 00006825 E80B000000              	call	pdskm
 24386                                  ddsk6:
 24387 0000682A BE[3A6D0000]            	mov	esi, nextline
 24388 0000682F E806000000              	call	pdskml
 24389                                  pdskm_ok:
 24390 00006834 C3                      	retn
 24391                                  pdskm:
 24392 00006835 BE[276D0000]            	mov	esi, dsk_ready_msg
 24393                                  pdskml:	
 24394 0000683A AC                      	lodsb
 24395 0000683B 08C0                    	or	al, al
 24396 0000683D 74F5                    	jz	short pdskm_ok
 24397 0000683F 56                      	push	esi
 24398 00006840 31DB                    	xor	ebx, ebx ; 0
 24399                                  			; Video page 0 (bl=0)
 24400 00006842 B407                    	mov	ah, 07h ; Black background, 
 24401                                  			; light gray forecolor
 24402 00006844 E8D4ACFFFF              	call	write_tty
 24403 00006849 5E                      	pop	esi
 24404 0000684A EBEE                    	jmp	short pdskml
 24405                                  
 24406 0000684C 90<rept>                align 16
 24407                                  
 24408                                  gdt:	; Global Descriptor Table
 24409                                  	; (30/07/2015, conforming cs)
 24410                                  	; (26/03/2015)
 24411                                  	; (24/03/2015, tss)
 24412                                  	; (19/03/2015)
 24413                                  	; (29/12/2013)
 24414                                  	;
 24415 00006850 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
 24416                                  	; 18/08/2014
 24417                                  			; 8h kernel code segment, base = 00000000h		
 24418 00006858 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
 24419                                  			; 10h kernel data segment, base = 00000000h	
 24420 00006860 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
 24421                                  			; 1Bh user code segment, base address = 400000h ; CORE
 24422 00006868 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
 24423                                  			; 23h user data segment, base address = 400000h ; CORE
 24424 00006870 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
 24425                                  			; Task State Segment
 24426 00006878 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
 24427                                  			       ;  no IO permission in ring 3)
 24428                                  gdt_tss0:
 24429 0000687A 0000                    	dw 0  ; TSS base address, bits 0-15 
 24430                                  gdt_tss1:
 24431 0000687C 00                      	db 0  ; TSS base address, bits 16-23 
 24432                                  	      		; 49h	
 24433 0000687D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
 24434 0000687E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
 24435                                  gdt_tss2:
 24436 0000687F 00                      	db 0  ; TSS base address, bits 24-31 
 24437                                  
 24438                                  gdt_end:
 24439                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 24440                                  					;; Type= 1 (code)/C=0/R=1/A=0
 24441                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 24442                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 24443                                  
 24444                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 24445                                  					;; Type= 0 (data)/E=0/W=1/A=0
 24446                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 24447                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 24448                                  		; W= Writeable, A= Accessed
 24449                                  	
 24450                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
 24451                                  					;; Type= 1 (code)/C=0/R=1/A=0
 24452                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 24453                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 24454                                  
 24455                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
 24456                                  					;; Type= 0 (data)/E=0/W=1/A=0
 24457                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 24458                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 24459                                  	
 24460                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
 24461                                  
 24462                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
 24463                                  		;	 = 100000h * 1000h (G=1) = 4GB
 24464                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
 24465                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
 24466                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
 24467                                  		; AVL= Available to programmers	
 24468                                  
 24469                                  gdtd:
 24470 00006880 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
 24471 00006882 [50680000]                      dd gdt			; Address of the GDT
 24472                                  
 24473                                  	; 20/08/2014
 24474                                  idtd:
 24475 00006886 FF01                            dw idt_end - idt - 1    ; Limit (size)
 24476 00006888 [406E0000]                      dd idt			; Address of the IDT
 24477                                  
 24478                                  Align 4
 24479                                  
 24480                                  	; 21/08/2014
 24481                                  ilist:
 24482                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
 24483                                  	;
 24484                                  	; Exception list
 24485                                  	; 25/08/2014	
 24486 0000688C [34090000]              	dd	exc0	; 0h,  Divide-by-zero Error
 24487 00006890 [3B090000]              	dd	exc1	
 24488 00006894 [42090000]              	dd 	exc2	
 24489 00006898 [49090000]              	dd	exc3	
 24490 0000689C [4D090000]              	dd	exc4	
 24491 000068A0 [51090000]              	dd	exc5	
 24492 000068A4 [55090000]              	dd 	exc6	; 06h,  Invalid Opcode
 24493 000068A8 [59090000]              	dd	exc7	
 24494 000068AC [5D090000]              	dd	exc8	
 24495 000068B0 [61090000]              	dd	exc9	
 24496 000068B4 [65090000]              	dd 	exc10	
 24497 000068B8 [69090000]              	dd	exc11
 24498 000068BC [6D090000]              	dd	exc12
 24499 000068C0 [71090000]              	dd	exc13	; 0Dh, General Protection Fault
 24500 000068C4 [75090000]              	dd 	exc14	; 0Eh, Page Fault
 24501 000068C8 [79090000]              	dd	exc15
 24502 000068CC [7D090000]              	dd	exc16
 24503 000068D0 [81090000]              	dd	exc17
 24504 000068D4 [85090000]              	dd 	exc18
 24505 000068D8 [89090000]              	dd	exc19
 24506 000068DC [8D090000]              	dd 	exc20
 24507 000068E0 [91090000]              	dd	exc21
 24508 000068E4 [95090000]              	dd	exc22
 24509 000068E8 [99090000]              	dd	exc23
 24510 000068EC [9D090000]              	dd 	exc24
 24511 000068F0 [A1090000]              	dd	exc25
 24512 000068F4 [A5090000]              	dd	exc26
 24513 000068F8 [A9090000]              	dd	exc27
 24514 000068FC [AD090000]              	dd 	exc28
 24515 00006900 [B1090000]              	dd	exc29
 24516 00006904 [B5090000]              	dd 	exc30
 24517 00006908 [B9090000]              	dd	exc31
 24518                                  	; Interrupt list
 24519 0000690C [6A070000]              	dd	timer_int	; INT 20h
 24520                                  		;dd	irq0	
 24521 00006910 [730C0000]              	dd	keyb_int	; 27/08/2014
 24522                                  		;dd	irq1
 24523 00006914 [8A080000]              	dd	irq2
 24524                                  		; COM2 int
 24525 00006918 [8E080000]              	dd	irq3
 24526                                  		; COM1 int
 24527 0000691C [99080000]              	dd	irq4
 24528 00006920 [A4080000]              	dd	irq5
 24529                                  ;DISKETTE_INT: ;06/02/2015
 24530 00006924 [AE270000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
 24531                                  		;dd	irq6
 24532                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
 24533                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 24534 00006928 [200C0000]              	dd	default_irq7	; 25/02/2015
 24535                                  		;dd	irq7
 24536                                  ; Real Time Clock Interrupt
 24537 0000692C [C30A0000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
 24538                                  		;dd	irq8	; INT 28h
 24539 00006930 [B4080000]              	dd	irq9
 24540 00006934 [B8080000]              	dd	irq10
 24541 00006938 [BC080000]              	dd	irq11
 24542 0000693C [C0080000]              	dd	irq12
 24543 00006940 [C4080000]              	dd	irq13
 24544                                  ;HDISK_INT1:  ;06/02/2015 	
 24545 00006944 [EA2F0000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
 24546                                  		;dd	irq14
 24547                                  ;HDISK_INT2:  ;06/02/2015
 24548 00006948 [11300000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
 24549                                  		;dd	irq15	; INT 2Fh
 24550                                  		; 14/08/2015
 24551 0000694C [803F0000]              	dd	sysent		; INT 30h (system calls)
 24552                                  	
 24553                                  	;dd	ignore_int
 24554 00006950 00000000                	dd	0
 24555                                  
 24556                                  ;;;
 24557                                  ;;; 11/03/2015
 24558                                  %include 'kybdata.inc'	; KEYBOARD (BIOS) DATA
 24559                              <1> ; Retro UNIX 386 v1 Kernel - KYBDATA.INC
 24560                              <1> ; Last Modification: 11/03/2015
 24561                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
 24562                              <1> ;
 24563                              <1> ; ///////// KEYBOARD DATA ///////////////
 24564                              <1> 
 24565                              <1> ; 05/12/2014
 24566                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
 24567                              <1> ; 03/06/86  KEYBOARD BIOS
 24568                              <1> 
 24569                              <1> ;---------------------------------------------------------------------------------
 24570                              <1> ;	KEY IDENTIFICATION SCAN TABLES
 24571                              <1> ;---------------------------------------------------------------------------------
 24572                              <1> 
 24573                              <1> ;-----	TABLES FOR ALT CASE ------------
 24574                              <1> ;-----	ALT-INPUT-TABLE 
 24575 00006954 524F50514B          <1> K30:	db	82,79,80,81,75
 24576 00006959 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
 24577                              <1> ;-----	SUPER-SHIFT-TABLE 
 24578 0000695E 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
 24579 00006964 161718191E1F        <1> 	db	22,23,24,25,30,31
 24580 0000696A 202122232425        <1> 	db	32,33,34,35,36,37
 24581 00006970 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
 24582 00006976 3132                <1> 	db	49,50
 24583                              <1> 
 24584                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
 24585                              <1> ;-----	KEY_TABLE 
 24586 00006978 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
 24587 00006979 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
 24588 0000697E 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
 24589                              <1> _K6L    equ     $-_K6
 24590                              <1> 
 24591                              <1> ;-----	MASK_TABLE
 24592 00006980 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
 24593 00006981 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
 24594 00006986 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
 24595                              <1> 
 24596                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
 24597 00006988 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
 24598 0000698E 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
 24599 00006994 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
 24600 0000699A 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
 24601 000069A0 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
 24602 000069A6 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
 24603 000069AC 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
 24604 000069B2 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
 24605 000069B8 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
 24606 000069BE 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
 24607                              <1> 	;				;----- FUNCTIONS ------		
 24608 000069C2 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
 24609 000069C8 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
 24610 000069CE 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
 24611 000069D4 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
 24612 000069DA 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
 24613                              <1> 
 24614                              <1> ;-----	TABLES FOR LOWER CASE ----------
 24615 000069E0 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
 24616 000069E9 39302D3D0809        <1>
 24617 000069EF 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
 24618 000069F8 705B5D0DFF61736466- <1>
 24619 00006A01 67686A6B6C3B27      <1>
 24620 00006A08 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
 24621 00006A11 6D2C2E2FFF2AFF20FF  <1>
 24622                              <1> ;-----	LC TABLE SCAN
 24623 00006A1A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
 24624 00006A1F 4041424344          <1> 	db	64,65,66,67,68
 24625 00006A24 FFFF                <1> 	db	-1,-1			; NL, SL
 24626                              <1> 
 24627                              <1> ;-----	KEYPAD TABLE
 24628 00006A26 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
 24629 00006A2C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
 24630 00006A33 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
 24631                              <1> 
 24632                              <1> ;-----	TABLES FOR UPPER CASE ----------
 24633 00006A38 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
 24634 00006A41 28295F2B0800        <1>
 24635 00006A47 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
 24636 00006A50 507B7D0DFF41534446- <1>
 24637 00006A59 47484A4B4C3A22      <1>
 24638 00006A60 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
 24639 00006A69 4D3C3E3FFF2AFF20FF  <1>
 24640                              <1> ;-----	UC TABLE SCAN
 24641 00006A72 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
 24642 00006A77 595A5B5C5D          <1> 	db	89,90,91,92,93
 24643 00006A7C FFFF                <1> 	db	-1,-1			; NL, SL
 24644                              <1> 
 24645                              <1> ;-----	NUM STATE TABLE
 24646 00006A7E 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
 24647 00006A87 3233302E            <1>
 24648                              <1> 	;
 24649 00006A8B FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
 24650                              <1> 
 24651                              <1> Align	4
 24652                              <1> ;----------------------------------------
 24653                              <1> ;	VIDEO DISPLAY DATA AREA		;
 24654                              <1> ;----------------------------------------
 24655 00006A90 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
 24656 00006A91 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
 24657                              <1> 				; (29h default setting for video mode 3)
 24658                              <1> 				; Mode Select register Bits
 24659                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
 24660                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
 24661                              <1> 				;   BIT 2 - COLOR (0), BW (1)
 24662                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
 24663                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
 24664                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
 24665                              <1> 				;   BIT 6, 7 - Not Used
 24666                              <1> 
 24667                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
 24668                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
 24669                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
 24670                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
 24671                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
 24672                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
 24673                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
 24674                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
 24675                              <1> ; Mode & 37h = Video signal OFF
 24676                              <1> 			
 24677                              <1> 
 24678                              <1> ; 26/08/2014
 24679                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
 24680                              <1> ; Derived from IBM "pc-at" 
 24681                              <1> ; rombios source code (06/10/1985)
 24682                              <1> ; 'dseg.inc'
 24683                              <1> 
 24684                              <1> ;---------------------------------------;
 24685                              <1> ;	SYSTEM DATA AREA		;
 24686                              <1> ;----------------------------------------
 24687 00006A92 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
 24688                              <1> 
 24689                              <1> ;----------------------------------------
 24690                              <1> ;	KEYBOARD DATA AREAS		;
 24691                              <1> ;----------------------------------------
 24692                              <1> 
 24693 00006A93 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
 24694 00006A94 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
 24695 00006A95 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
 24696 00006A96 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
 24697 00006A97 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
 24698 00006A98 [A86A0000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
 24699 00006A9C [C86A0000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
 24700 00006AA0 [A86A0000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
 24701 00006AA4 [A86A0000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
 24702                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
 24703 00006AA8 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
 24704                              <1> 
 24705                              <1> ; /// End Of KEYBOARD DATA ///
 24706                                  %include 'vidata.inc'	; VIDEO (BIOS) DATA
 24707                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.INC
 24708                              <1> ; Last Modification: 11/03/2015
 24709                              <1> ;		    (Data section for 'VIDEO.INC')	
 24710                              <1> ;
 24711                              <1> ; ///////// VIDEO DATA ///////////////
 24712                              <1> 
 24713                              <1> video_params:
 24714                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
 24715                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
 24716                              <1> 	; VIDEO MODE 3
 24717 00006AC8 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
 24718 00006ACF 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
 24719 00006AD4 00000000            <1> 	db	0,0,0,0
 24720                              <1> 
 24721                              <1> ; /// End Of VIDEO DATA ///
 24722                                  %include 'diskdata.inc'	; DISK (BIOS) DATA (initialized)
 24723                              <1> ; Retro UNIX 386 v1 Kernel - DISKDATA.INC
 24724                              <1> ; Last Modification: 11/03/2015
 24725                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
 24726                              <1> ;
 24727                              <1> ; *****************************************************************************
 24728                              <1> 
 24729                              <1> ;----------------------------------------
 24730                              <1> ;	80286 INTERRUPT LOCATIONS	:
 24731                              <1> ;	REFERENCED BY POST & BIOS	:
 24732                              <1> ;----------------------------------------
 24733                              <1> 
 24734 00006AD8 [3B6B0000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
 24735                              <1> 
 24736                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
 24737                              <1> ;----------------------------------------------------------------
 24738                              <1> ; DISK_BASE							:
 24739                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
 24740                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
 24741                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
 24742                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
 24743                              <1> ;----------------------------------------------------------------
 24744                              <1> 
 24745                              <1> ;DISK_BASE:	
 24746                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24747                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24748                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24749                              <1> ;	DB	2		; 512 BYTES/SECTOR
 24750                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
 24751                              <1> ;	db	18		; (EOT for 1.44MB diskette)
 24752                              <1> ;	DB	01BH		; GAP LENGTH
 24753                              <1> ;	DB	0FFH		; DTL
 24754                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
 24755                              <1> ;	db	06ch		; (for 1.44MB dsikette)
 24756                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
 24757                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24758                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24759                              <1> 
 24760                              <1> ;----------------------------------------
 24761                              <1> ;	ROM BIOS DATA AREAS		:
 24762                              <1> ;----------------------------------------
 24763                              <1> 
 24764                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 24765                              <1> 
 24766                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
 24767                              <1> 
 24768                              <1> ;----------------------------------------
 24769                              <1> ;	DISKETTE DATA AREAS		:
 24770                              <1> ;----------------------------------------
 24771                              <1> 
 24772                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
 24773                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
 24774                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
 24775                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
 24776                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
 24777                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
 24778                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
 24779                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
 24780                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
 24781                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
 24782                              <1> 
 24783                              <1> ;----------------------------------------
 24784                              <1> ;	POST AND BIOS WORK DATA AREA	:
 24785                              <1> ;----------------------------------------
 24786                              <1> 
 24787                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
 24788                              <1> 
 24789                              <1> ;----------------------------------------
 24790                              <1> ;	TIMER DATA AREA 		:
 24791                              <1> ;----------------------------------------
 24792                              <1> 
 24793                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
 24794                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
 24795                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
 24796                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
 24797                              <1> 
 24798                              <1> ;----------------------------------------
 24799                              <1> ;	ADDITIONAL MEDIA DATA		:
 24800                              <1> ;----------------------------------------
 24801                              <1> 
 24802                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 24803                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 24804                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 24805                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 24806                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 24807                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 24808                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 24809                              <1> 
 24810                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 24811                              <1> 
 24812                              <1> ;--------------------------------------------------------
 24813                              <1> ;	DRIVE TYPE TABLE				:
 24814                              <1> ;--------------------------------------------------------
 24815                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
 24816                              <1> DR_TYPE:
 24817 00006ADC 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
 24818                              <1>                 ;DW      MD_TBL1
 24819 00006ADD [FA6A0000]          <1> 		dd	MD_TBL1
 24820 00006AE1 82                  <1> 		DB	02+BIT7ON
 24821                              <1> 		;DW      MD_TBL2
 24822 00006AE2 [076B0000]          <1>                 dd      MD_TBL2
 24823 00006AE6 02                  <1> DR_DEFAULT:	DB	02
 24824                              <1>                 ;DW      MD_TBL3
 24825 00006AE7 [146B0000]          <1> 		dd      MD_TBL3
 24826 00006AEB 03                  <1> 		DB	03
 24827                              <1>                 ;DW      MD_TBL4
 24828 00006AEC [216B0000]          <1> 		dd      MD_TBL4
 24829 00006AF0 84                  <1> 		DB	04+BIT7ON
 24830                              <1>                 ;DW      MD_TBL5
 24831 00006AF1 [2E6B0000]          <1> 		dd      MD_TBL5
 24832 00006AF5 04                  <1> 		DB	04
 24833                              <1>                 ;DW      MD_TBL6
 24834 00006AF6 [3B6B0000]          <1> 		dd      MD_TBL6
 24835                              <1> DR_TYPE_E       equ $                   ; END OF TABLE
 24836                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
 24837                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
 24838                              <1> ;--------------------------------------------------------
 24839                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
 24840                              <1> ;--------------------------------------------------------
 24841                              <1> ;--------------------------------------------------------
 24842                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
 24843                              <1> ;--------------------------------------------------------
 24844                              <1> MD_TBL1:        
 24845 00006AFA DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24846 00006AFB 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24847 00006AFC 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24848 00006AFD 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24849 00006AFE 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24850 00006AFF 2A                  <1> 	DB	02AH		; GAP LENGTH
 24851 00006B00 FF                  <1> 	DB	0FFH		; DTL
 24852 00006B01 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24853 00006B02 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24854 00006B03 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24855 00006B04 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24856 00006B05 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 24857 00006B06 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24858                              <1> ;--------------------------------------------------------
 24859                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
 24860                              <1> ;--------------------------------------------------------
 24861                              <1> MD_TBL2:        
 24862 00006B07 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24863 00006B08 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24864 00006B09 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24865 00006B0A 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24866 00006B0B 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24867 00006B0C 2A                  <1> 	DB	02AH		; GAP LENGTH
 24868 00006B0D FF                  <1> 	DB	0FFH		; DTL
 24869 00006B0E 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24870 00006B0F F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24871 00006B10 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24872 00006B11 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24873 00006B12 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 24874 00006B13 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
 24875                              <1> ;--------------------------------------------------------
 24876                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
 24877                              <1> ;--------------------------------------------------------
 24878                              <1> MD_TBL3:
 24879 00006B14 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24880 00006B15 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24881 00006B16 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24882 00006B17 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24883 00006B18 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
 24884 00006B19 1B                  <1> 	DB	01BH		; GAP LENGTH
 24885 00006B1A FF                  <1> 	DB	0FFH		; DTL
 24886 00006B1B 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
 24887 00006B1C F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24888 00006B1D 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24889 00006B1E 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24890 00006B1F 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24891 00006B20 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 24892                              <1> ;--------------------------------------------------------
 24893                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
 24894                              <1> ;--------------------------------------------------------
 24895                              <1> MD_TBL4:
 24896 00006B21 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24897 00006B22 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24898 00006B23 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24899 00006B24 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24900 00006B25 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24901 00006B26 2A                  <1> 	DB	02AH		; GAP LENGTH
 24902 00006B27 FF                  <1> 	DB	0FFH		; DTL
 24903 00006B28 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24904 00006B29 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24905 00006B2A 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24906 00006B2B 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24907 00006B2C 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24908 00006B2D 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24909                              <1> ;--------------------------------------------------------
 24910                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
 24911                              <1> ;--------------------------------------------------------
 24912                              <1> MD_TBL5:
 24913 00006B2E DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24914 00006B2F 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24915 00006B30 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24916 00006B31 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24917 00006B32 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24918 00006B33 2A                  <1> 	DB	02AH		; GAP LENGTH
 24919 00006B34 FF                  <1> 	DB	0FFH		; DTL
 24920 00006B35 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24921 00006B36 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24922 00006B37 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24923 00006B38 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24924 00006B39 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24925 00006B3A 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24926                              <1> ;--------------------------------------------------------
 24927                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
 24928                              <1> ;--------------------------------------------------------
 24929                              <1> MD_TBL6:
 24930 00006B3B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24931 00006B3C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24932 00006B3D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24933 00006B3E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24934 00006B3F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
 24935 00006B40 1B                  <1> 	DB	01BH		; GAP LENGTH
 24936 00006B41 FF                  <1> 	DB	0FFH		; DTL
 24937 00006B42 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
 24938 00006B43 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24939 00006B44 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24940 00006B45 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24941 00006B46 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24942 00006B47 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 24943                              <1> 
 24944                              <1> 
 24945                              <1> ; << diskette.inc >>
 24946                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 24947                              <1> ;
 24948                              <1> ;----------------------------------------
 24949                              <1> ;	ROM BIOS DATA AREAS		:
 24950                              <1> ;----------------------------------------
 24951                              <1> 
 24952                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 24953                              <1> 
 24954                              <1> ;----------------------------------------
 24955                              <1> ;	FIXED DISK DATA AREAS		:
 24956                              <1> ;----------------------------------------
 24957                              <1> 
 24958                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
 24959                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
 24960                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
 24961                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
 24962                              <1> 
 24963                              <1> ;----------------------------------------
 24964                              <1> ;	ADDITIONAL MEDIA DATA		:
 24965                              <1> ;----------------------------------------
 24966                              <1> 
 24967                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 24968                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
 24969                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
 24970                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
 24971                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
 24972                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 24973                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 24974                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 24975                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 24976                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 24977                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 24978                              <1> 
 24979                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 24980                              <1> ;
 24981                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 24982                              <1> 
 24983                              <1> ERR_TBL:
 24984 00006B48 E0                  <1> 	db	NO_ERR
 24985 00006B49 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
 24986 00006B4D 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
 24987                              <1> 
 24988                              <1> ; 17/12/2014 (mov ax, [cfd])
 24989                              <1> ; 11/12/2014
 24990 00006B51 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
 24991                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
 24992 00006B52 01                  <1> pfd:		db 1			; previous floppy drive (for GET_PARM)
 24993                              <1> 					; (initial value of 'pfd 
 24994                              <1> 					; must be different then 'cfd' value
 24995                              <1> 					; to force updating/initializing
 24996                              <1> 					; current drive parameters) 
 24997 00006B53 90                  <1> align 2
 24998                              <1> 
 24999 00006B54 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
 25000                              <1> 			      ; (170h)
 25001 00006B56 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
 25002                              <1> 
 25003                              <1> ; 05/01/2015 
 25004 00006B58 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
 25005                              <1> 
 25006                              <1> ; *****************************************************************************
 25007                                  ;;;
 25008                                  
 25009                                  ; 27/08/2014
 25010                                  scr_row:
 25011 00006B59 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
 25012                                  scr_col:
 25013 00006B5D 00000000                	dd 0
 25014                                  
 25015                                  ;; 14/08/2015
 25016                                  ;;msgPM:
 25017                                  ;;      db "Protected mode and paging are ENABLED ... ", 0
 25018                                  msgKVER:
 25019 00006B61 526574726F20554E49-     	db "Retro UNIX 386 v1.1 - Kernel v0.2.1.0 [03/01/2016]", 0
 25020 00006B6A 58203338362076312E-
 25021 00006B73 31202D204B65726E65-
 25022 00006B7C 6C2076302E322E312E-
 25023 00006B85 30205B30332F30312F-
 25024 00006B8E 323031365D00       
 25025                                  
 25026                                  Align 2
 25027                                  
 25028                                  ; 20/08/2014
 25029                                    ; /* This is the default interrupt "handler" :-) */ 
 25030                                    ; Linux v0.12 (head.s)
 25031                                  int_msg:
 25032 00006B94 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
 25033 00006B9D 6E7465727275707420-
 25034 00006BA6 212000             
 25035                                  
 25036 00006BA9 90                      Align 2  
 25037                                  
 25038                                  ; 21/08/2014
 25039                                  timer_msg:
 25040 00006BAA 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
 25041 00006BB3 542032306829202120-
 25042 00006BBC 54696D657220496E74-
 25043 00006BC5 657272757074203A20 
 25044                                  tcountstr:
 25045 00006BCE 303030303020            	db "00000 "
 25046 00006BD4 00                      	db 0
 25047                                  
 25048 00006BD5 90                      Align 2
 25049                                  	; 21/08/2014
 25050                                  exc_msg:
 25051 00006BD6 435055206578636570-     	db "CPU exception ! "
 25052 00006BDF 74696F6E202120     
 25053                                  excnstr: 		; 25/08/2014
 25054 00006BE6 3F3F68202045495020-     	db "??h", "  EIP : "
 25055 00006BEF 3A20               
 25056                                  EIPstr: ; 29/08/2014
 25057 00006BF1 00<rept>                	times 12 db 0
 25058                                  rtc_msg:
 25059 00006BFD 5265616C2054696D65-     	db "Real Time Clock - "
 25060 00006C06 20436C6F636B202D20 
 25061                                  datestr:
 25062 00006C0F 30302F30302F303030-     	db "00/00/0000"
 25063 00006C18 30                 
 25064 00006C19 20                      	db " "
 25065                                  daystr:
 25066 00006C1A 44415920                	db "DAY "
 25067                                  timestr:	
 25068 00006C1E 30303A30303A3030                db "00:00:00"
 25069 00006C26 20                      	db " "
 25070 00006C27 00                      	db 0 
 25071                                  
 25072                                  daytmp:
 25073                                  	; 28/02/2015
 25074 00006C28 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
 25075 00006C31 4F4E20545545205745-
 25076 00006C3A 442054485520465249-
 25077 00006C43 2053415420         
 25078                                  
 25079 00006C48 FF                      ptime_seconds: db 0FFh
 25080                                  
 25081                                  	; 23/02/2015
 25082                                  	; 25/08/2014
 25083                                  ;scounter:
 25084                                  ;	db 5
 25085                                  ;	db 19
 25086                                  
 25087                                  ; 05/11/2014
 25088                                  msg_out_of_memory:
 25089 00006C49 070D0A                  	db 	07h, 0Dh, 0Ah
 25090 00006C4C 496E73756666696369-             db      'Insufficient memory ! (Minimum 2 MB memory is needed.)'
 25091 00006C55 656E74206D656D6F72-
 25092 00006C5E 79202120284D696E69-
 25093 00006C67 6D756D2032204D4220-
 25094 00006C70 6D656D6F7279206973-
 25095 00006C79 206E65656465642E29 
 25096 00006C82 0D0A00                   	db	0Dh, 0Ah, 0
 25097                                  	;
 25098                                  setup_error_msg:
 25099 00006C85 0D0A                    	db 0Dh, 0Ah
 25100 00006C87 4469736B2053657475-     	db 'Disk Setup Error!' 
 25101 00006C90 70204572726F7221   
 25102 00006C98 0D0A00                  	db 0Dh, 0Ah,0
 25103                                  
 25104                                  ; 02/09/2014 (Retro UNIX 386 v1)
 25105                                  ;crt_ulc : db 0 ; upper left column (for scroll) 
 25106                                  ;	  db 0 ; upper left row (for scroll)	
 25107                                  
 25108                                  ;crt_lrc : db 79 ; lower right column (for scroll) 
 25109                                  ;	  db 24 ; lower right row (for scroll)
 25110                                  
 25111                                  
 25112                                  ; 06/11/2014 (Temporary Data)
 25113                                  ; Memory Information message
 25114                                  ; 14/08/2015
 25115                                  msg_memory_info:
 25116 00006C9B 07                      	db	07h
 25117 00006C9C 0D0A                    	db	0Dh, 0Ah
 25118                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
 25119 00006C9E 546F74616C206D656D-     	db	"Total memory : "
 25120 00006CA7 6F7279203A20       
 25121                                  mem_total_b_str: ; 10 digits
 25122 00006CAD 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
 25123 00006CB6 302062797465730D0A 
 25124 00006CBF 202020202020202020-     	db	"               ", 20h, 20h, 20h
 25125 00006CC8 202020202020202020 
 25126                                  mem_total_p_str: ; 7 digits
 25127 00006CD1 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
 25128 00006CDA 616765730D0A       
 25129 00006CE0 0D0A                    	db 	0Dh, 0Ah
 25130 00006CE2 46726565206D656D6F-     	db	"Free memory  : "
 25131 00006CEB 727920203A20       
 25132                                  free_mem_b_str:  ; 10 digits
 25133 00006CF1 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
 25134 00006CFA 3F2062797465730D0A 
 25135 00006D03 202020202020202020-     	db	"               ", 20h, 20h, 20h
 25136 00006D0C 202020202020202020 
 25137                                  free_mem_p_str:  ; 7 digits
 25138 00006D15 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
 25139 00006D1E 616765730D0A       
 25140 00006D24 0D0A00                  	db	0Dh, 0Ah, 0
 25141                                  
 25142                                  dsk_ready_msg:
 25143 00006D27 0D0A                    	db 	0Dh, 0Ah
 25144                                  dsktype:
 25145 00006D29 6664                    	db	'fd'
 25146                                  dskx:
 25147 00006D2B 30                      	db	'0'
 25148 00006D2C 20                      	db	20h
 25149 00006D2D 697320524541445920-     	db 	'is READY ...'
 25150 00006D36 2E2E2E             
 25151 00006D39 00                      	db 	0
 25152                                  nextline:
 25153 00006D3A 0D0A00                  	db 	0Dh, 0Ah, 0
 25154                                  
 25155                                  ; KERNEL - SYSINIT Messages
 25156                                  ; 24/08/2015
 25157                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
 25158                                  ; 14/07/2013
 25159                                  ;kernel_init_err_msg:
 25160                                  ;	db 0Dh, 0Ah
 25161                                  ;	db 07h
 25162                                  ;	db 'Kernel initialization ERROR !'
 25163                                  ;	db 0Dh, 0Ah, 0 
 25164                                  ; 24/08/2015
 25165                                  ;;; (temporary kernel init message has been removed
 25166                                  ;;;  from 'sys_init' code)
 25167                                  ;kernel_init_ok_msg: 
 25168                                  ;	db 0Dh, 0Ah
 25169                                  ;	db 07h
 25170                                  ;	db 'Welcome to Retro UNIX 386 v1.1 Operating System !'
 25171                                  ;	db 0Dh, 0Ah
 25172                                  ;       db 'by Erdogan Tan - 03/01/2016 (v0.2.1.0)'
 25173                                  ;	db 0Dh, 0Ah, 0
 25174                                  panic_msg:
 25175 00006D3D 0D0A07                  	db 0Dh, 0Ah, 07h
 25176 00006D40 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
 25177 00006D49 726E656C2050616E69-
 25178 00006D52 632021             
 25179 00006D55 0D0A00                  	db 0Dh, 0Ah, 0
 25180                                  etc_init_err_msg:
 25181 00006D58 0D0A                    	db 0Dh, 0Ah
 25182 00006D5A 07                      	db 07h
 25183 00006D5B 4552524F523A202F65-     	db 'ERROR: /etc/init !?'
 25184 00006D64 74632F696E69742021-
 25185 00006D6D 3F                 
 25186 00006D6E 0D0A00                  	db 0Dh, 0Ah, 0
 25187                                  
 25188                                  ; 10/05/2015
 25189                                  badsys_msg:
 25190 00006D71 0D0A                    	db 0Dh, 0Ah
 25191 00006D73 07                      	db 07h
 25192 00006D74 496E76616C69642053-     	db 'Invalid System Call !'
 25193 00006D7D 797374656D2043616C-
 25194 00006D86 6C2021             
 25195 00006D89 0D0A                    	db 0Dh, 0Ah
 25196 00006D8B 4541583A20              	db 'EAX: '
 25197                                  bsys_msg_eax:
 25198 00006D90 303030303030303068      	db '00000000h'
 25199 00006D99 0D0A                    	db 0Dh, 0Ah
 25200 00006D9B 4549503A20              	db 'EIP: '
 25201                                  bsys_msg_eip:
 25202 00006DA0 303030303030303068      	db '00000000h' 
 25203 00006DA9 0D0A00                  	db 0Dh, 0Ah, 0
 25204                                  
 25205                                  BSYS_M_SIZE equ $ - badsys_msg
 25206                                  
 25207                                  
 25208                                  align 2
 25209                                  
 25210                                  ; EPOCH Variables
 25211                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
 25212                                  ; 09/04/2013 epoch variables
 25213                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
 25214                                  ;
 25215 00006DAC B207                    year: 	dw 1970
 25216 00006DAE 0100                    month: 	dw 1
 25217 00006DB0 0100                    day: 	dw 1
 25218 00006DB2 0000                    hour: 	dw 0
 25219 00006DB4 0000                    minute: dw 0
 25220 00006DB6 0000                    second: dw 0
 25221                                  
 25222                                  DMonth:
 25223 00006DB8 0000                    	dw 0
 25224 00006DBA 1F00                    	dw 31
 25225 00006DBC 3B00                    	dw 59
 25226 00006DBE 5A00                    	dw 90
 25227 00006DC0 7800                    	dw 120
 25228 00006DC2 9700                    	dw 151
 25229 00006DC4 B500                    	dw 181
 25230 00006DC6 D400                    	dw 212
 25231 00006DC8 F300                    	dw 243
 25232 00006DCA 1101                    	dw 273
 25233 00006DCC 3001                    	dw 304
 25234 00006DCE 4E01                    	dw 334
 25235                                  
 25236                                  ; 04/11/2014 (Retro UNIX 386 v1)
 25237 00006DD0 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
 25238                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
 25239 00006DD2 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
 25240                                  		   ;   between 16 MB and 4 GB.
 25241                                  
 25242                                  ; 12/11/2014 (Retro UNIX 386 v1)
 25243 00006DD4 00                      boot_drv:    db 0 ; boot drive number (physical)
 25244                                  ; 24/11/2014
 25245 00006DD5 00                      drv:	     db 0 
 25246 00006DD6 00                      last_drv:    db 0 ; last hdd
 25247 00006DD7 00                      hdc:         db 0  ; number of hard disk drives
 25248                                  		     ; (present/detected)
 25249                                  ;
 25250                                  ; 24/11/2014 (Retro UNIX 386 v1)
 25251                                  ; Physical drive type & flags
 25252 00006DD8 00                      fd0_type:    db 0  ; floppy drive type
 25253 00006DD9 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
 25254                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
 25255                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
 25256                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
 25257                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
 25258 00006DDA 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
 25259 00006DDB 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
 25260 00006DDC 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
 25261 00006DDD 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
 25262                                  		     ; bit 0 - Fixed disk access subset supported
 25263                                  		     ; bit 1 - Drive locking and ejecting
 25264                                  		     ; bit 2 - Enhanced disk drive support
 25265                                  		     ; bit 3 = Reserved (64 bit EDD support)
 25266                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
 25267                                  		     ; will interpret it as 'LBA ready'!)		
 25268                                  
 25269                                  ; 11/03/2015 - 10/07/2015
 25270 00006DDE 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
 25271 00006DE7 0000000000         
 25272 00006DEC 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
 25273 00006DF5 0000000000         
 25274 00006DFA 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
 25275 00006E03 0000000000         
 25276 00006E08 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
 25277 00006E11 000000000000000000-
 25278 00006E1A 000000000000000000-
 25279 00006E23 00                 
 25280 00006E24 00000000000000          drv.status:    db 0,0,0,0,0,0,0
 25281 00006E2B 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
 25282                                  ;
 25283                                  
 25284 00006E32 90<rept>                align 16
 25285                                  
 25286                                  bss_start:
 25287                                  
 25288                                  ABSOLUTE bss_start
 25289                                  
 25290                                  	; 11/03/2015
 25291                                  	; Interrupt Descriptor Table (20/08/2014)
 25292                                  idt:
 25293 00006E40 <res 00000200>          	resb	64*8 ; INT 0 to INT 3Fh
 25294                                  idt_end:
 25295                                  
 25296                                  ;alignb 4
 25297                                  
 25298                                  task_state_segment:
 25299                                  	; 24/03/2015
 25300 00007040 <res 00000002>          tss.link:   resw 1
 25301 00007042 <res 00000002>          	    resw 1
 25302                                  ; tss offset 4	
 25303 00007044 <res 00000004>          tss.esp0:   resd 1
 25304 00007048 <res 00000002>          tss.ss0:    resw 1
 25305 0000704A <res 00000002>          	    resw 1	
 25306 0000704C <res 00000004>          tss.esp1:   resd 1
 25307 00007050 <res 00000002>          tss.ss1:    resw 1
 25308 00007052 <res 00000002>          	    resw 1 	
 25309 00007054 <res 00000004>          tss.esp2:   resd 1
 25310 00007058 <res 00000002>          tss.ss2:    resw 1
 25311 0000705A <res 00000002>          	    resw 1
 25312                                  ; tss offset 28
 25313 0000705C <res 00000004>          tss.CR3:    resd 1
 25314 00007060 <res 00000004>          tss.eip:    resd 1
 25315 00007064 <res 00000004>          tss.eflags: resd 1
 25316                                  ; tss offset 40
 25317 00007068 <res 00000004>          tss.eax:    resd 1		 		
 25318 0000706C <res 00000004>          tss.ecx:    resd 1
 25319 00007070 <res 00000004>          tss.edx:    resd 1
 25320 00007074 <res 00000004>          tss.ebx:    resd 1
 25321 00007078 <res 00000004>          tss.esp:    resd 1
 25322 0000707C <res 00000004>          tss.ebp:    resd 1
 25323 00007080 <res 00000004>          tss.esi:    resd 1
 25324 00007084 <res 00000004>          tss.edi:    resd 1
 25325                                  ; tss offset 72
 25326 00007088 <res 00000002>          tss.ES:     resw 1
 25327 0000708A <res 00000002>          	    resw 1	
 25328 0000708C <res 00000002>          tss.CS:	    resw 1
 25329 0000708E <res 00000002>          	    resw 1
 25330 00007090 <res 00000002>          tss.SS:	    resw 1
 25331 00007092 <res 00000002>          	    resw 1
 25332 00007094 <res 00000002>          tss.DS:	    resw 1
 25333 00007096 <res 00000002>          	    resw 1
 25334 00007098 <res 00000002>          tss.FS:	    resw 1
 25335 0000709A <res 00000002>          	    resw 1
 25336 0000709C <res 00000002>          tss.GS:	    resw 1
 25337 0000709E <res 00000002>          	    resw 1		
 25338 000070A0 <res 00000002>          tss.LDTR:   resw 1
 25339 000070A2 <res 00000002>          	    resw 1
 25340                                  ; tss offset 100		
 25341 000070A4 <res 00000002>          	    resw 1		
 25342 000070A6 <res 00000002>          tss.IOPB:   resw 1
 25343                                  ; tss offset 104 
 25344                                  tss_end:
 25345                                  
 25346 000070A8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
 25347                                  		  ;   (Physical address = Virtual address)	 	
 25348 000070AC <res 00000004>          memory_size: resd 1 ; memory size in pages
 25349 000070B0 <res 00000004>          free_pages:  resd 1 ; number of free pages		
 25350 000070B4 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
 25351                                  		  ;   first free page search
 25352 000070B8 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
 25353                                  		  ;   next free page search will be
 25354                                  		  ; stopped after it. (end of M.A.T.)
 25355 000070BC <res 00000004>          first_page:  resd 1 ;   offset value in M.A.T. which
 25356                                  		  ; first free page search
 25357                                  		  ;   will be started on it. (for user)
 25358 000070C0 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
 25359                                  
 25360                                  ;;;
 25361                                  ; 02/09/2014 (Retro UNIX 386 v1)
 25362                                  ; 04/12/2013 (Retro UNIX 8086 v1)
 25363 000070C4 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
 25364                                  			  ; NOTE: active page only
 25365 000070C6 <res 00000010>          cursor_posn: resw 8 	  ; cursor positions for video pages
 25366                                  active_page: 
 25367 000070D6 <res 00000001>          ptty: 	     resb 1 	  ; current tty
 25368                                  ; 01/07/2015
 25369 000070D7 <res 00000001>          ccolor:	     resb 1	  ; current color attributes ('sysmsg')	
 25370                                  ; 26/10/2015
 25371                                  ; 07/09/2014
 25372 000070D8 <res 00000014>          ttychr:      resw ntty+2  ; Character buffer (multiscreen)
 25373                                  
 25374                                  ; 21/08/2014
 25375 000070EC <res 00000004>          tcount:	     resd 1
 25376                                  
 25377                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
 25378 000070F0 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
 25379                                  
 25380                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
 25381                                  ; (open mode locks for pseudo TTYs)
 25382                                  ; [ major tty locks (return error in any conflicts) ]
 25383 000070F4 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
 25384                                  
 25385                                  ; 15/04/2015 (Retro UNIX 386 v1)
 25386                                  ; 22/09/2013 (Retro UNIX 8086 v1)
 25387 00007108 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
 25388                                  ; 15/04/2015 (Retro UNIX 386 v1)
 25389                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
 25390                                  ;; 0 means serial port is not available 
 25391                                  ;;comprm: ; 25/06/2014
 25392 00007112 <res 00000001>          com1p:       resb 1  ;;0E3h
 25393 00007113 <res 00000001>          com2p:       resb 1  ;;0E3h
 25394                                  
 25395                                  ; 17/11/2015
 25396                                  ; request for response (from the terminal)	
 25397 00007114 <res 00000002>          req_resp:     resw 1 			
 25398                                  ; 07/11/2015
 25399 00007116 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
 25400                                  		    ; (0= COM1, 1= COM2)
 25401                                  ; 09/11/2015
 25402 00007117 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
 25403                                  ; 07/11/2015
 25404 00007118 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
 25405 0000711A <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
 25406                                  
 25407                                  ; 23/10/2015
 25408                                  ; SERIAL PORTS - COMMUNICATION MODES
 25409                                  ; (Retro UNIX 386 v1 feature only!)
 25410                                  ; 0 - command mode (default/initial mode)
 25411                                  ; 1 - terminal mode (Retro UNIX 386 v1 terminal, ascii chars)
 25412                                  ;;; communication modes for futre versions:  
 25413                                  ; // 2 - keyboard mode (ascii+scancode input)
 25414                                  ; // 3 - mouse mode
 25415                                  ; // 4 - device control (output) mode
 25416                                  ; VALID COMMANDS for current version:
 25417                                  ; 	'LOGIN'
 25418                                  ;  Login request: db 0FFh, 'LOGIN', 0 
 25419                                  ;	 ("Retro UNIX 386 v1 terminal requests login")
 25420                                  ;  Login response: db 0FFh, 'login', 0
 25421                                  ;	 ("login request accepted, wait for login prompt") 
 25422                                  ; When a login requests is received and acknowledged (by
 25423                                  ; serial port interrupt handler (communication procedure),
 25424                                  ; Retro UNIX 386 v1 operating system will start terminal mode
 25425                                  ; (login procedure) by changing comm. mode to 1 (terminal mode)
 25426                                  ; and then running 'etc/getty' for tty8 (COM1) or tty9 (COM2)
 25427                                  ; 
 25428                                  ; 'sys connect' system call is used to change communication mode
 25429                                  ; except 'LOGIN' command which is used to start terminal mode
 25430                                  ; by using (COM port) terminal.
 25431                                  
 25432                                  ;com1own:     resb 1 ; COM1 owner (u.uno)
 25433                                  ;com2own:     resb 1 ; COM2 owner (u.uno)
 25434                                  ;com1mode:    resb 1 ; communication mode for COM1
 25435                                  ;com1com:     resb 1 ; communication command for COM1
 25436                                  ;com2mode:    resb 1 ; communication mode for COM1
 25437                                  ;com2com      resb 1 ; communication command for COM1
 25438                                  ;com1cbufp:   resb 8 ; COM1 command buffer char pointer	
 25439                                  ;com2cbufp:   resb 8 ; COM2 command buffer char pointer	
 25440                                  ;com1cbuf:    resb 8 ; COM2 command buffer
 25441                                  ;com2cbuf:    resb 8 ; COM2 command buffer
 25442                                  
 25443                                  ; 22/08/2014 (RTC)
 25444                                  ; (Packed BCD)
 25445 0000711C <res 00000001>          time_seconds: resb 1
 25446 0000711D <res 00000001>          time_minutes: resb 1
 25447 0000711E <res 00000001>          time_hours:   resb 1
 25448 0000711F <res 00000001>          date_wday:    resb 1
 25449 00007120 <res 00000001>          date_day:     resb 1
 25450 00007121 <res 00000001>          date_month:   resb 1			
 25451 00007122 <res 00000001>          date_year:    resb 1
 25452 00007123 <res 00000001>          date_century: resb 1
 25453                                  
 25454                                  %include 'diskbss.inc'	; UNINITIALIZED DISK (BIOS) DATA
 25455                              <1> ; Retro UNIX 386 v1 Kernel - DISKBSS.INC
 25456                              <1> ; Last Modification: 10/07/2015
 25457                              <1> ;	(Unnitialized Disk Parameters Data section for 'DISKIO.INC') 
 25458                              <1> ;
 25459                              <1> ; *****************************************************************************
 25460                              <1> 
 25461                              <1> alignb 2
 25462                              <1> 
 25463                              <1> ;----------------------------------------
 25464                              <1> ;	TIMER DATA AREA 		:
 25465                              <1> ;----------------------------------------
 25466                              <1> 
 25467                              <1> TIMER_LH:	; 16/02/205
 25468 00007124 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
 25469 00007126 <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
 25470 00007128 <res 00000001>      <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
 25471                              <1> 
 25472                              <1> ;----------------------------------------
 25473                              <1> ;	DISKETTE DATA AREAS		:
 25474                              <1> ;----------------------------------------
 25475                              <1> 
 25476 00007129 <res 00000001>      <1> SEEK_STATUS:	resb	1
 25477 0000712A <res 00000001>      <1> MOTOR_STATUS:	resb	1
 25478 0000712B <res 00000001>      <1> MOTOR_COUNT:	resb	1
 25479 0000712C <res 00000001>      <1> DSKETTE_STATUS:	resb	1
 25480 0000712D <res 00000007>      <1> NEC_STATUS:	resb	7
 25481                              <1> 
 25482                              <1> ;----------------------------------------
 25483                              <1> ;	ADDITIONAL MEDIA DATA		:
 25484                              <1> ;----------------------------------------
 25485                              <1> 
 25486 00007134 <res 00000001>      <1> LASTRATE:	resb 	1
 25487 00007135 <res 00000001>      <1> HF_STATUS:	resb 	1
 25488 00007136 <res 00000001>      <1> HF_ERROR:	resb 	1
 25489 00007137 <res 00000001>      <1> HF_INT_FLAG:	resb 	1
 25490 00007138 <res 00000001>      <1> HF_CNTRL:	resb 	1
 25491 00007139 <res 00000004>      <1> DSK_STATE:	resb 	4
 25492 0000713D <res 00000002>      <1> DSK_TRK:	resb 	2
 25493                              <1> 
 25494                              <1> ;----------------------------------------
 25495                              <1> ;	FIXED DISK DATA AREAS		:
 25496                              <1> ;----------------------------------------
 25497                              <1> 
 25498 0000713F <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
 25499 00007140 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
 25500 00007141 <res 00000001>      <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
 25501                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
 25502                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
 25503                              <1> ;port2_off	resb	1		; Hard idsk controller 2 - port offset
 25504                              <1> 
 25505 00007142 <res 00000002>      <1> alignb 4
 25506                              <1> 
 25507                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 25508                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 25509                              <1> HF_TBL_VEC: ; 22/12/2014	
 25510 00007144 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 25511 00007148 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 25512 0000714C <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
 25513 00007150 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
 25514                              <1> 
 25515                              <1> ; 03/01/2015
 25516 00007154 <res 00000001>      <1> LBAMode:     	resb	1
 25517                              <1> 
 25518                              <1> ; *****************************************************************************
 25519                                  
 25520                                  ;;; Real Mode Data (10/07/2015 - BSS)
 25521                                  
 25522                                  ;alignb 2
 25523                                  
 25524                                  %include 'ux.s' ; 12/04/2015 (unix system/user/process data)
 25525                              <1> ; Retro UNIX 386 v1 Kernel - ux.s
 25526                              <1> ; Last Modification: 04/12/2015
 25527                              <1> ;
 25528                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 25529                              <1> ; (Modified from 
 25530                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 25531                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 25532                              <1> ; ----------------------------------------------------------------------------
 25533                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 25534                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 25535                              <1> ; <Bell Laboratories (17/3/1972)>
 25536                              <1> ; <Preliminary Release of UNIX Implementation Document>
 25537                              <1> ; (Section E10 (17/3/1972) - ux.s)
 25538                              <1> ; ****************************************************************************
 25539                              <1> 
 25540 00007155 <res 00000001>      <1> alignb 2
 25541                              <1> 
 25542                              <1> inode:
 25543                              <1> 	; 11/03/2013. 
 25544                              <1> 	;Derived from UNIX v1 source code 'inode' structure (ux).
 25545                              <1> 	;i.
 25546                              <1> 
 25547 00007156 <res 00000002>      <1> 	i.flgs:	 resw 1
 25548 00007158 <res 00000001>      <1> 	i.nlks:	 resb 1
 25549 00007159 <res 00000001>      <1> 	i.uid:	 resb 1
 25550 0000715A <res 00000002>      <1>         i.size:  resw 1 ; size
 25551 0000715C <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
 25552 0000716C <res 00000004>      <1> 	i.ctim:	 resd 1
 25553 00007170 <res 00000004>      <1> 	i.mtim:	 resd 1
 25554 00007174 <res 00000002>      <1> 	i.rsvd:  resw 1 ; Reserved (ZERO/Undefined word for UNIX v1.)
 25555                              <1> 
 25556                              <1> I_SIZE	equ $ - inode 
 25557                              <1> 
 25558                              <1> process:
 25559                              <1> 	; 06/05/2015
 25560                              <1> 	; 11/03/2013 - 05/02/2014
 25561                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
 25562                              <1> 	;p.
 25563                              <1> 	
 25564 00007176 <res 00000020>      <1>         p.pid:   resw nproc
 25565 00007196 <res 00000020>      <1>         p.ppid:  resw nproc
 25566 000071B6 <res 00000020>      <1>         p.break: resw nproc
 25567 000071D6 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
 25568 000071E6 <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
 25569 000071F6 <res 00000010>      <1> 	p.link:	 resb nproc
 25570 00007206 <res 00000010>      <1> 	p.stat:	 resb nproc
 25571                              <1> 
 25572                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 fetaure only !) 
 25573 00007216 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
 25574                              <1> 			    ; 'user' structure	
 25575                              <1> 
 25576                              <1> 
 25577                              <1> P_SIZE	equ $ - process
 25578                              <1> 
 25579                              <1> 
 25580                              <1> ; fsp table (original UNIX v1)
 25581                              <1> ;
 25582                              <1> ;Entry
 25583                              <1> ;          15                                      0
 25584                              <1> ;  1     |---|---------------------------------------|
 25585                              <1> ;        |r/w|       i-number of open file           |
 25586                              <1> ;        |---|---------------------------------------| 
 25587                              <1> ;        |               device number               |
 25588                              <1> ;        |-------------------------------------------|
 25589                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
 25590                              <1> ;        |-------------------------------------------| 
 25591                              <1> ;        |  flag that says    | number of processes  |
 25592                              <1> ;        |   file deleted     | that have file open  |
 25593                              <1> ;        |-------------------------------------------| 
 25594                              <1> ;  2     |                                           |
 25595                              <1> ;        |-------------------------------------------| 
 25596                              <1> ;        |                                           |
 25597                              <1> ;        |-------------------------------------------|
 25598                              <1> ;        |                                           |
 25599                              <1> ;        |-------------------------------------------|
 25600                              <1> ;        |                                           |
 25601                              <1> ;        |-------------------------------------------| 
 25602                              <1> ;  3     |                                           | 
 25603                              <1> ;        |                                           |  
 25604                              <1> ;
 25605                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
 25606                              <1> 
 25607                              <1> 
 25608                              <1> ; 15/04/2015
 25609 00007256 <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
 25610 0000744A <res 00000018>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
 25611 00007462 <res 00000002>      <1> ii:	 resw 1
 25612 00007464 <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
 25613 00007466 <res 00000002>      <1> cdev:    resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
 25614                              <1> ; 18/05/2015
 25615                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
 25616                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
 25617                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
 25618                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
 25619                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
 25620                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
 25621                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
 25622                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
 25623                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
 25624                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
 25625                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
 25626 00007468 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
 25627                              <1> 	        ; as above, for physical drives numbers in following table
 25628 00007469 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
 25629                              <1> ; 15/04/2015
 25630 0000746A <res 00000001>      <1> active:	 resb 1 
 25631 0000746B <res 00000001>      <1> 	 resb 1 ; 09/06/2015
 25632 0000746C <res 00000002>      <1> mnti:	 resw 1
 25633 0000746E <res 00000002>      <1> mpid:	 resw 1
 25634 00007470 <res 00000002>      <1> rootdir: resw 1
 25635                              <1> ; 14/02/2014
 25636                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
 25637                              <1> ;		      Single level run queue
 25638                              <1> ;		      (in order to solve sleep/wakeup lock)
 25639 00007472 <res 00000002>      <1> runq:	 resw 1
 25640 00007474 <res 00000001>      <1> imod:	 resb 1
 25641 00007475 <res 00000001>      <1> smod:	 resb 1
 25642 00007476 <res 00000001>      <1> mmod:	 resb 1
 25643 00007477 <res 00000001>      <1> sysflg:	 resb 1
 25644                              <1> 
 25645                              <1> alignb 4
 25646                              <1> 
 25647                              <1> user:
 25648                              <1> 	; 04/12/2015 
 25649                              <1> 	; 18/10/2015
 25650                              <1> 	; 12/10/2015
 25651                              <1> 	; 21/09/2015
 25652                              <1> 	; 24/07/2015
 25653                              <1> 	; 16/06/2015
 25654                              <1> 	; 09/06/2015
 25655                              <1> 	; 11/05/2015
 25656                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 25657                              <1> 	; 10/10/2013
 25658                              <1> 	; 11/03/2013. 
 25659                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
 25660                              <1> 	;u.
 25661                              <1> 
 25662 00007478 <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
 25663 0000747C <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
 25664 00007480 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
 25665 00007484 <res 00000002>      <1> 	u.cdir:	  resw 1
 25666 00007486 <res 0000000A>      <1> 	u.fp:	  resb 10
 25667 00007490 <res 00000004>      <1> 	u.fofp:	  resd 1
 25668 00007494 <res 00000004>      <1> 	u.dirp:	  resd 1
 25669 00007498 <res 00000004>      <1> 	u.namep:  resd 1
 25670 0000749C <res 00000004>      <1> 	u.off:	  resd 1
 25671 000074A0 <res 00000004>      <1> 	u.base:	  resd 1
 25672 000074A4 <res 00000004>      <1> 	u.count:  resd 1
 25673 000074A8 <res 00000004>      <1> 	u.nread:  resd 1
 25674 000074AC <res 00000004>      <1> 	u.break:  resd 1 ; break
 25675 000074B0 <res 00000002>      <1> 	u.ttyp:	  resw 1 
 25676 000074B2 <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
 25677                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
 25678 000074C2 <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
 25679 000074C3 <res 00000001>      <1> 	u.pri:	  resb 1 ; 
 25680 000074C4 <res 00000002>      <1> 	u.intr:	  resw 1
 25681 000074C6 <res 00000002>      <1> 	u.quit:	  resw 1
 25682                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
 25683 000074C8 <res 00000002>      <1> 	u.ilgins: resw 1
 25684 000074CA <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
 25685 000074CC <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
 25686 000074CD <res 00000001>      <1> 	u.ruid:	  resb 1
 25687 000074CE <res 00000001>      <1> 	u.bsys:	  resb 1
 25688 000074CF <res 00000001>      <1> 	u.uno:	  resb 1
 25689 000074D0 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
 25690                              <1> 	; tty number (rtty, rcvt, wtty)
 25691 000074D4 <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
 25692                              <1> 	; last error number
 25693 000074D5 <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
 25694                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
 25695 000074D9 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
 25696 000074DD <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
 25697 000074E1 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
 25698 000074E5 <res 00000002>      <1> 	u.pcount: resw 1 ; 20/05/2015 (byte -transfer- count for page)
 25699                              <1> 	;u.pncount: resw 1 
 25700                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
 25701                              <1> 	;u.pnbase:  resd 1 
 25702                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
 25703                              <1> 			 ; 09/06/2015
 25704 000074E7 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
 25705 000074E8 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
 25706                              <1> 			 ; 24/07/2015 - 24/06/2015
 25707                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
 25708                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
 25709                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
 25710                              <1>  			 ; 24/06/2015	  	
 25711                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
 25712                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
 25713                              <1> 			 ; 21/09/2015 (debugging - page fault analyze)
 25714 000074E9 <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
 25715                              <1> 
 25716 000074ED <res 00000003>      <1> alignb 4
 25717                              <1> 
 25718                              <1> U_SIZE	equ $ - user
 25719                              <1> 
 25720                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
 25721 000074F0 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
 25722 000074F4 <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
 25723 000074F8 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
 25724 000074FC <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
 25725 000074FE <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
 25726 00007500 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
 25727                              <1> 
 25728                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
 25729                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
 25730 00007504 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
 25731 00007505 <res 00000001>      <1> rwdsk:	 resb 1 ;; Read/Write function number (diskio) - 16/06/2015
 25732 00007506 <res 00000001>      <1> retry_count: resb 1 ; Disk I/O retry count - 11/06/2015
 25733 00007507 <res 00000001>      <1> 	 resb 1 ;; Reserved (16/06/2015) 
 25734                              <1> 
 25735                              <1> ;alignb 4
 25736                              <1> 
 25737                              <1> ; 22/08/2015
 25738 00007508 <res 00000820>      <1> buffer: resb nbuf * 520
 25739                              <1> 
 25740 00007D28 <res 00000008>      <1> sb0:	resd 2
 25741                              <1> ;s:
 25742                              <1> ; (root disk) super block buffer
 25743                              <1> systm:
 25744                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
 25745                              <1> 	; 11/03/2013. 
 25746                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
 25747                              <1> 	;s.
 25748                              <1> 
 25749 00007D30 <res 00000002>      <1> 	resw 1
 25750 00007D32 <res 00000168>      <1> 	resb 360 ; 2880 sectors ; original UNIX v1 value: 128
 25751 00007E9A <res 00000002>      <1> 	resw 1
 25752 00007E9C <res 00000020>      <1> 	resb 32	 ; 256+40 inodes ; original UNIX v1 value: 64
 25753 00007EBC <res 00000004>      <1> 	s.time:	 resd 1
 25754 00007EC0 <res 00000004>      <1> 	s.syst:	 resd 1
 25755 00007EC4 <res 00000004>      <1>         s.wait_: resd 1 ; wait
 25756 00007EC8 <res 00000004>      <1> 	s.idlet: resd 1
 25757 00007ECC <res 00000004>      <1> 	s.chrgt: resd 1
 25758 00007ED0 <res 00000002>      <1> 	s.drerr: resw 1
 25759                              <1> 
 25760                              <1> S_SIZE	equ $ - systm
 25761                              <1> 
 25762 00007ED2 <res 0000005E>      <1> 	resb 512-S_SIZE ; 03/06/2015	 
 25763                              <1> 
 25764 00007F30 <res 00000008>      <1> sb1:	resd 2
 25765                              <1> ; (mounted disk) super block buffer
 25766                              <1> mount:	
 25767 00007F38 <res 00000200>      <1> 	resb 512  ; 03/06/2015
 25768                              <1> 
 25769                              <1> ;/ ux -- unix
 25770                              <1> ;
 25771                              <1> ;systm:
 25772                              <1> ;
 25773                              <1> ;	.=.+2
 25774                              <1> ;	.=.+128.
 25775                              <1> ;	.=.+2
 25776                              <1> ;	.=.+64.
 25777                              <1> ;	s.time: .=.+4
 25778                              <1> ;	s.syst: .=.+4
 25779                              <1> ;	s.wait: .=.+4
 25780                              <1> ;	s.idlet:.=.+4
 25781                              <1> ;	s.chrgt:.=.+4
 25782                              <1> ;	s.drerr:.=.+2
 25783                              <1> ;inode:
 25784                              <1> ;	i.flgs: .=.+2
 25785                              <1> ;	i.nlks: .=.+1
 25786                              <1> ;	i.uid:  .=.+1
 25787                              <1> ;	i.size: .=.+2
 25788                              <1> ;	i.dskp: .=.+16.
 25789                              <1> ;	i.ctim: .=.+4
 25790                              <1> ;	i.mtim: .=.+4
 25791                              <1> ;	. = inode+32.
 25792                              <1> ;mount:	.=.+1024.
 25793                              <1> ;proc:
 25794                              <1> ;	p.pid:  .=.+[2*nproc]
 25795                              <1> ;	p.dska: .=.+[2*nproc]
 25796                              <1> ;	p.ppid: .=.+[2*nproc]
 25797                              <1> ;	p.break:.=.+[2*nproc]
 25798                              <1> ;	p.link: .=.+nproc
 25799                              <1> ;	p.stat: .=.+nproc
 25800                              <1> ;tty:
 25801                              <1> ;	. = .+[ntty*8.]
 25802                              <1> ;fsp:	.=.+[nfiles*8.]
 25803                              <1> ;bufp:	.=.+[nbuf*2]+6
 25804                              <1> ;sb0:	.=.+8
 25805                              <1> ;sb1:	.=.+8
 25806                              <1> ;swp:	.=.+8
 25807                              <1> ;ii:	.=.+2
 25808                              <1> ;idev:	.=.+2
 25809                              <1> ;cdev:	.=.+2
 25810                              <1> ;deverr: .=.+12.
 25811                              <1> ;active: .=.+2
 25812                              <1> ;rfap:	.=.+2
 25813                              <1> ;rkap:	.=.+2
 25814                              <1> ;tcap:	.=.+2
 25815                              <1> ;tcstate:.=.+2
 25816                              <1> ;tcerrc: .=.+2
 25817                              <1> ;mnti:	.=.+2
 25818                              <1> ;mntd:	.=.+2
 25819                              <1> ;mpid:	.=.+2
 25820                              <1> ;clockp: .=.+2
 25821                              <1> ;rootdir:.=.+2
 25822                              <1> ;toutt:	.=.+16.
 25823                              <1> ;touts: .=.+32.
 25824                              <1> ;runq:	.=.+6
 25825                              <1> ;
 25826                              <1> ;wlist:	.=.+40.
 25827                              <1> ;cc:	.=.+30.
 25828                              <1> ;cf:	.=.+31.
 25829                              <1> ;cl:	.=.+31.
 25830                              <1> ;clist:	.=.+510.
 25831                              <1> ;imod:	.=.+1
 25832                              <1> ;smod:	.=.+1
 25833                              <1> ;mmod:	.=.+1
 25834                              <1> ;uquant: .=.+1
 25835                              <1> ;sysflg: .=.+1
 25836                              <1> ;pptiflg:.=.+1
 25837                              <1> ;ttyoch: .=.+1
 25838                              <1> ; .even
 25839                              <1> ; .=.+100.; sstack:
 25840                              <1> ;buffer: .=.+[ntty*140.]
 25841                              <1> ;	.=.+[nbuf*520.]
 25842                              <1> ;
 25843                              <1> ; . = core-64.
 25844                              <1> ;user:
 25845                              <1> ;	u.sp:    .=.+2
 25846                              <1> ;	u.usp:   .=.+2
 25847                              <1> ;	u.r0:    .=.+2
 25848                              <1> ;	u.cdir:  .=.+2
 25849                              <1> ;	u.fp:    .=.+10.
 25850                              <1> ;	u.fofp:  .=.+2
 25851                              <1> ;	u.dirp:  .=.+2
 25852                              <1> ;	u.namep: .=.+2
 25853                              <1> ;	u.off:   .=.+2
 25854                              <1> ;	u.base:  .=.+2
 25855                              <1> ;	u.count: .=.+2
 25856                              <1> ;	u.nread: .=.+2
 25857                              <1> ;	u.break: .=.+2
 25858                              <1> ;	u.ttyp:  .=.+2
 25859                              <1> ;	u.dirbuf:.=.+10.
 25860                              <1> ;	u.pri:   .=.+2
 25861                              <1> ;	u.intr:  .=.+2
 25862                              <1> ;	u.quit:  .=.+2
 25863                              <1> ;	u.emt:   .=.+2
 25864                              <1> ;	u.ilgins:.=.+2
 25865                              <1> ;	u.cdev:  .=.+2
 25866                              <1> ;	u.uid:   .=.+1
 25867                              <1> ;	u.ruid:  .=.+1
 25868                              <1> ;	u.bsys:  .=.+1
 25869                              <1> ;	u.uno:   .=.+1
 25870                              <1> ;. = core
 25871                                  
 25872                                  ;; Memory (swap) Data (11/03/2015)
 25873                                  ; 09/03/2015
 25874 00008138 <res 00000002>          swpq_count: resw 1 ; count of pages on the swap que
 25875 0000813A <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
 25876 0000813E <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 25877 00008142 <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 25878 00008146 <res 00000004>          swpd_next:  resd 1 ; next free page block
 25879 0000814A <res 00000004>          swpd_last:  resd 1 ; last swap page block	
 25880                                  
 25881 0000814E <res 00000002>          alignb 4
 25882                                  
 25883                                  ; 10/07/2015
 25884                                  ; 28/08/2014
 25885 00008150 <res 00000004>          error_code:	resd 1
 25886                                  ; 29/08/2014
 25887 00008154 <res 00000004>          FaultOffset: 	resd 1
 25888                                  ; 21/09/2015
 25889 00008158 <res 00000004>          PF_Count:	resd 1	; total page fault count
 25890                                  		       	; (for debugging - page fault analyze)
 25891                                  		 	; 'page _fault_handler' (memory.inc)
 25892                                  			; 'sysgeterr' (u9.s)
 25893                                  ;; 21/08/2015
 25894                                  ;;buffer: resb (nbuf*520) ;; sysdefs.inc, ux.s
 25895                                  ;; ((NOTE: nbuf = 6, buffer r/w problem/bug here !? when nbuf > 4))
 25896                                  
 25897                                  bss_end:
 25898                                  
 25899                                  ; 27/12/2013
 25900                                  _end:  ; end of kernel code (and read only data, just before bss)
