     1                                  ; ****************************************************************************
     2                                  ; UNIX386.ASM (RETRO UNIX 386 Kernel) - v0.2.0.17
     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: 04/02/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[2A6B]              	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[FE6D]              	mov	[mem_1m_1k], cx
   169 00000017 8916[006E]              	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[776C]                	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: 04/02/2016
   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                              <1> 
   215 00000044 81FB55AA            <1> 	cmp	bx, 0AA55h
   216 00000048 7514                <1> 	jne	short L2
   217 0000004A FE06[2D6B]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
   218 0000004E 8816[2C6B]          <1>         mov     [last_drv], dl  ; last hard disk number
   219 00000052 BB[B06A]            <1> 	mov	bx, hd0_type - 80h
   220 00000055 01D3                <1> 	add	bx, dx	 
   221 00000057 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
   222                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
   223                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
   224                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
   225                              <1>                          ;            (EDD) ready (DPTE ready)
   226                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
   227                              <1>                          ;            (EDD-3)
   228                              <1> 			 ; Bit 4 to 15 - 0, Reserved
   229 00000059 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
   230 0000005C 72DB                <1> 	jb	short L1
   231                              <1> L2:
   232                              <1> 	; 23/11/2014
   233                              <1> 	; 19/11/2014
   234 0000005E 30D2                <1> 	xor	dl, dl  ; 0
   235                              <1> 	; 04/02/2016 (esi -> si)
   236 00000060 BE[2E6B]            <1> 	mov	si, fd0_type
   237                              <1> L3:
   238                              <1> 	; 14/01/2015
   239 00000063 8816[2B6B]          <1> 	mov	[drv], dl
   240                              <1> 	;
   241 00000067 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   242 00000069 CD13                <1> 	int	13h	
   243 0000006B 7210                <1> 	jc	short L4
   244                              <1> 		; BL = drive type (for floppy drives)
   245                              <1> 		; DL = number of floppy drives
   246                              <1> 		;		
   247                              <1> 		; ES:DI = Address of DPT from BIOS
   248                              <1> 		;
   249 0000006D 881C                <1> 	mov	[si], bl ;  Drive type
   250                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
   251                              <1> 	; 14/01/2015
   252 0000006F E8A202              <1> 	call	set_disk_parms
   253                              <1> 	; 10/12/2014
   254 00000072 81FE[2E6B]          <1> 	cmp	si, fd0_type
   255 00000076 7705                <1> 	ja	short L4
   256 00000078 46                  <1> 	inc	si ; fd1_type
   257 00000079 B201                <1> 	mov	dl, 1
   258 0000007B EBE6                <1> 	jmp	short L3
   259                              <1> L4:
   260                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
   261 0000007D B27F                <1> 	mov	dl, 7Fh
   262                              <1> 	; 24/12/2014 (Temporary)
   263 0000007F 803E[2D6B]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
   264 00000084 0F879000            <1>         ja      L10       ; yes, all fixed disk operations
   265                              <1> 			  ; will be performed according to
   266                              <1> 			  ; present EDD specification
   267                              <1> L6:
   268 00000088 FEC2                <1> 	inc 	dl
   269 0000008A 8816[2B6B]          <1>         mov     [drv], dl
   270 0000008E 8816[2C6B]          <1>         mov     [last_drv], dl ; 14/01/2015
   271 00000092 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   272 00000094 CD13                <1> 	int	13h	; (conventional function)
   273 00000096 0F828201            <1>         jc      L13	; fixed disk drive not ready
   274 0000009A 8816[2D6B]          <1>         mov     [hdc], dl ; number of drives
   275                              <1> 	;; 14/01/2013
   276                              <1> 	;;push	cx
   277 0000009E E87302              <1> 	call	set_disk_parms
   278                              <1> 	;;pop	cx
   279                              <1> 	;
   280                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   281 000000A1 8A16[2B6B]          <1>         mov     dl, [drv]
   282 000000A5 BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   283 000000A8 80FA80              <1> 	cmp	dl, 80h
   284 000000AB 7603                <1> 	jna	short L7
   285 000000AD 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   286                              <1> L7:	
   287 000000B0 31C0                <1> 	xor	ax, ax
   288 000000B2 8ED8                <1> 	mov	ds, ax
   289 000000B4 8B37                <1>         mov     si, [bx]
   290 000000B6 8B4702              <1>         mov     ax, [bx+2] 
   291 000000B9 8ED8                <1> 	mov	ds, ax
   292 000000BB 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   293 000000BE 0F855601            <1>         jne     L12 ; invalid FDPT
   294 000000C2 BF0000              <1> 	mov	di, HD0_DPT
   295 000000C5 80FA80              <1> 	cmp	dl, 80h
   296 000000C8 7603                <1> 	jna	short L8
   297 000000CA BF2000              <1> 	mov	di, HD1_DPT 
   298                              <1> L8:
   299                              <1> 	; 30/12/2014
   300 000000CD B80090              <1> 	mov	ax, DPT_SEGM
   301 000000D0 8EC0                <1> 	mov	es, ax
   302                              <1> 	; 24/12/2014
   303 000000D2 B90800              <1> 	mov	cx, 8
   304 000000D5 F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   305 000000D7 8CC8                <1> 	mov	ax, cs
   306 000000D9 8ED8                <1> 	mov	ds, ax
   307                              <1> 	; 02/02/2015
   308 000000DB 8A0E[2B6B]          <1>         mov     cl, [drv]
   309 000000DF 88CB                <1> 	mov	bl, cl
   310 000000E1 B8F001              <1> 	mov	ax, 1F0h
   311 000000E4 80E301              <1> 	and	bl, 1
   312 000000E7 7406                <1> 	jz	short L9
   313 000000E9 C0E304              <1> 	shl	bl, 4
   314 000000EC 2D8000              <1> 	sub	ax, 1F0h-170h
   315                              <1> L9:
   316 000000EF AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   317 000000F0 050602              <1> 	add	ax, 206h
   318 000000F3 AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   319 000000F4 88D8                <1> 	mov	al, bl
   320 000000F6 04A0                <1> 	add	al, 0A0h
   321 000000F8 AA                  <1> 	stosb	; Device/Head Register upper nibble
   322                              <1> 	;
   323 000000F9 FE06[2B6B]          <1> 	inc	byte [drv]
   324 000000FD BB[B06A]            <1> 	mov	bx, hd0_type - 80h
   325 00000100 01CB                <1> 	add	bx, cx
   326 00000102 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   327 00000105 A0[2D6B]            <1> 	mov	al, [hdc]
   328 00000108 FEC8                <1> 	dec	al
   329 0000010A 0F840E01            <1>         jz      L13
   330 0000010E 80FA80              <1> 	cmp	dl, 80h
   331 00000111 0F8673FF            <1>         jna     L6
   332 00000115 E90401              <1>         jmp     L13
   333                              <1> L10:
   334 00000118 FEC2                <1> 	inc 	dl
   335                              <1> 	; 25/12/2014
   336 0000011A 8816[2B6B]          <1> 	mov	[drv], dl
   337 0000011E B408                <1> 	mov 	ah, 08h ; Return drive parameters
   338 00000120 CD13                <1> 	int	13h	; (conventional function)
   339 00000122 0F82F600            <1>         jc      L13
   340                              <1> 	; 14/01/2015
   341 00000126 8A16[2B6B]          <1> 	mov	dl, [drv]
   342 0000012A 52                  <1> 	push	dx
   343 0000012B 51                  <1> 	push	cx
   344 0000012C E8E501              <1> 	call	set_disk_parms
   345 0000012F 59                  <1> 	pop	cx
   346 00000130 5A                  <1> 	pop	dx
   347                              <1> 	; 04/02/2016 (esi -> si)
   348 00000131 BE[3C85]            <1> 	mov	si, _end ; 30 byte temporary buffer address 	
   349                              <1> 			 ; at the '_end' of kernel.
   350 00000134 C7041E00            <1> 	mov	word [si], 30
   351 00000138 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   352 0000013A CD13                <1> 	int	13h
   353 0000013C 0F82DC00            <1>         jc      L13
   354                              <1> 	; 04/02/2016 (ebx -> bx)
   355                              <1> 	; 14/01/2015
   356 00000140 29DB                <1> 	sub	bx, bx
   357 00000142 88D3                <1> 	mov	bl, dl
   358 00000144 80EB80              <1> 	sub	bl, 80h
   359 00000147 81C3[306B]          <1> 	add	bx, hd0_type
   360 0000014B 8A07                <1> 	mov 	al, [bx]
   361 0000014D 0C80                <1> 	or	al, 80h
   362 0000014F 8807                <1> 	mov 	[bx], al	
   363 00000151 81EB[2E6B]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   364 00000155 81C3[7A6B]          <1> 	add	bx, drv.status
   365 00000159 8807                <1> 	mov	[bx], al
   366                              <1> 	; 04/02/2016 (eax -> ax)
   367 0000015B 8B4410              <1> 	mov	ax, [si+16]
   368 0000015E 854412              <1> 	test	ax, [si+18]
   369 00000161 7412                <1> 	jz	short L10_A0h 
   370                              <1> 			; 'CHS only' disks on EDD system 
   371                              <1> 			;  are reported with ZERO disk size
   372 00000163 81EB[7A6B]          <1> 	sub	bx, drv.status
   373 00000167 C1E302              <1> 	shl	bx, 2
   374 0000016A 81C3[5E6B]          <1> 	add	bx, drv.size ; disk size (in sectors)
   375 0000016E 8907                <1> 	mov	[bx], ax
   376 00000170 8B4412              <1> 	mov	ax, [si+18]
   377 00000173 8907                <1> 	mov	[bx], ax
   378                              <1> 
   379                              <1> L10_A0h: ; Jump here to fix a ZERO (LBA) disk size problem 
   380                              <1> 	 ; for CHS disks (28/02/2015)
   381                              <1> 	; 30/12/2014
   382 00000175 BF0000              <1> 	mov	di, HD0_DPT
   383 00000178 88D0                <1> 	mov	al, dl
   384 0000017A 83E003              <1> 	and 	ax, 3
   385 0000017D C0E005              <1> 	shl	al, 5 ; *32
   386 00000180 01C7                <1> 	add 	di, ax
   387 00000182 B80090              <1> 	mov	ax, DPT_SEGM
   388 00000185 8EC0                <1> 	mov	es, ax
   389                              <1> 	;
   390 00000187 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   391 00000189 88CC                <1> 	mov	ah, cl	
   392 0000018B C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   393 0000018E 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   394 0000018F AB                  <1> 	stosw		
   395 00000190 88F0                <1> 	mov	al, dh	; max. head number
   396 00000192 FEC0                <1> 	inc	al
   397 00000194 AA                  <1> 	stosb		; logical heads (limits 256)
   398 00000195 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   399 00000197 AA                  <1> 	stosb
   400 00000198 8A440C              <1> 	mov	al, [si+12]
   401 0000019B AA                  <1> 	stosb		 ; physical sectors per track
   402 0000019C 31C0                <1>  	xor	ax, ax
   403                              <1> 	;dec	ax	 ; 02/01/2015 
   404 0000019E AB                  <1> 	stosw		 ; precompensation (obsolete)
   405                              <1> 	;xor	al, al	 ; 02/01/2015	
   406 0000019F AA                  <1> 	stosb		 ; reserved
   407 000001A0 B008                <1> 	mov	al, 8	 ; drive control byte
   408                              <1> 		         ; (do not disable retries, 
   409                              <1> 			 ; more than 8 heads)
   410 000001A2 AA                  <1> 	stosb
   411 000001A3 8B4404              <1> 	mov	ax, [si+4]
   412 000001A6 AB                  <1> 	stosw		 ; physical number of cylinders	
   413                              <1> 	;push	ax	 ; 02/01/2015
   414 000001A7 8A4408              <1> 	mov	al, [si+8]
   415 000001AA AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   416 000001AB 29C0                <1> 	sub 	ax, ax
   417                              <1> 	;pop	ax	 ; 02/01/2015	
   418 000001AD AB                  <1> 	stosw		 ; landing zone (obsolete)
   419 000001AE 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   420 000001B0 243F                <1> 	and 	al, 3Fh	
   421 000001B2 AA                  <1> 	stosb
   422                              <1> 	;sub	al, al	 ; checksum
   423                              <1> 	;stosb
   424                              <1> 	;
   425 000001B3 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   426 000001B6 AD                  <1> 	lodsw
   427 000001B7 50                  <1> 	push	ax	 ; (BIOS) DPTE offset
   428 000001B8 AD                  <1> 	lodsw
   429 000001B9 50                  <1> 	push	ax	 ; (BIOS) DPTE segment
   430                              <1> 	;
   431                              <1> 	; checksum calculation
   432 000001BA 89FE                <1> 	mov	si, di
   433 000001BC 06                  <1> 	push	es
   434 000001BD 1F                  <1> 	pop	ds
   435                              <1> 	;mov	cx, 16
   436 000001BE B90F00              <1> 	mov 	cx, 15
   437 000001C1 29CE                <1> 	sub	si, cx
   438 000001C3 30E4                <1> 	xor	ah, ah
   439                              <1> 	;del	cl
   440                              <1> L11:		
   441 000001C5 AC                  <1> 	lodsb
   442 000001C6 00C4                <1> 	add	ah, al
   443 000001C8 E2FB                <1> 	loop	L11
   444                              <1> 	;
   445 000001CA 88E0                <1> 	mov	al, ah
   446 000001CC F6D8                <1> 	neg	al	; -x+x = 0
   447 000001CE AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   448                              <1> 	;
   449 000001CF 1F                  <1> 	pop	ds	; (BIOS) DPTE segment
   450 000001D0 5E                  <1> 	pop	si	; (BIOS) DPTE offset	
   451                              <1> 	;
   452                              <1> 	; 23/02/2015
   453 000001D1 57                  <1> 	push	di
   454                              <1> 	; ES:DI points to DPTE (FDPTE) location
   455                              <1> 	;mov	cx, 8
   456 000001D2 B108                <1> 	mov	cl, 8
   457 000001D4 F3A5                <1> 	rep	movsw	
   458                              <1> 	;
   459                              <1> 	; 23/02/2015
   460                              <1> 	; (P)ATA drive and LBA validation
   461                              <1> 	; (invalidating SATA drives and setting
   462                              <1> 	; CHS type I/O for old type fixed disks)
   463 000001D6 5B                  <1> 	pop	bx
   464 000001D7 8CC8                <1> 	mov	ax, cs
   465 000001D9 8ED8                <1> 	mov	ds, ax
   466 000001DB 268B07              <1> 	mov	ax, [es:bx]
   467 000001DE 3DF001              <1> 	cmp	ax, 1F0h
   468 000001E1 7418                <1> 	je	short L11a
   469 000001E3 3D7001              <1> 	cmp	ax, 170h
   470 000001E6 7413                <1> 	je	short L11a
   471                              <1> 	; invalidation 
   472                              <1> 	; (because base port address is not 1F0h or 170h)
   473 000001E8 30FF                <1> 	xor	bh, bh
   474 000001EA 88D3                <1> 	mov	bl, dl
   475 000001EC 80EB80              <1> 	sub	bl, 80h
   476 000001EF C687[306B]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   477 000001F4 808F[7C6B]F0        <1>         or      byte [bx+drv.status+2], 0F0h ; (failure sign)
   478 000001F9 EB14                <1> 	jmp	short L11b
   479                              <1> L11a:	
   480                              <1> 	; LBA validation
   481 000001FB 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   482 000001FF A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   483 00000201 750C                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   484                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   485 00000203 28FF                <1> 	sub	bh, bh
   486 00000205 88D3                <1> 	mov	bl, dl
   487 00000207 80EB80              <1> 	sub	bl, 80h ; 26/02/2015
   488 0000020A 80A7[7C6B]FE        <1>         and     byte [bx+drv.status+2], 0FEh ; clear bit 0
   489                              <1> 				; bit 0 = LBA ready bit
   490                              <1> 	; 'diskio' procedure will check this bit !
   491                              <1> L11b:
   492 0000020F 3A16[2C6B]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   493 00000213 7307                <1>         jnb     short L13
   494 00000215 E900FF              <1>         jmp     L10
   495                              <1> L12:
   496                              <1> 	; Restore data registers
   497 00000218 8CC8                <1> 	mov	ax, cs
   498 0000021A 8ED8                <1> 	mov	ds, ax	
   499                              <1> L13:
   500                              <1> 	; 13/12/2014
   501 0000021C 0E                  <1> 	push	cs
   502 0000021D 07                  <1> 	pop	es
   503                              <1> L14:
   504 0000021E B411                <1> 	mov 	ah, 11h
   505 00000220 CD16                <1> 	int 	16h
   506 00000222 7406                <1> 	jz 	short L15 ; no keys in keyboard buffer
   507 00000224 B010                <1> 	mov	al, 10h
   508 00000226 CD16                <1> 	int 	16h
   509 00000228 EBF4                <1> 	jmp 	short L14
   510                              <1> L15:
   511                              <1> ; //////
   512                              <1> 	; 24/11/2014
   513                              <1> 	; 19/11/2014
   514                              <1> 	; 14/11/2014
   515                              <1> 	; Temporary code for disk searching code check
   516                              <1> 	;
   517                              <1> 	; This code will show existing (usable) drives and also
   518                              <1> 	; will show EDD interface support status for hard disks		
   519                              <1> 	; (If status bit 7 is 1, Identify Device info is ready,
   520                              <1> 	; no need to get it again in protected mode...) 
   521                              <1> 	;	
   522                              <1> 	; 13/11/2014
   523 0000022A BB0700              <1> 	mov	bx, 7
   524 0000022D B40E                <1> 	mov	ah, 0Eh
   525 0000022F A0[2E6B]            <1> 	mov	al, [fd0_type]
   526 00000232 20C0                <1> 	and	al, al
   527 00000234 743D                <1> 	jz	short L15a
   528 00000236 88C2                <1> 	mov	dl, al
   529 00000238 B046                <1> 	mov	al, 'F'
   530 0000023A CD10                <1> 	int 	10h
   531 0000023C B044                <1> 	mov	al, 'D'
   532 0000023E CD10                <1> 	int 	10h
   533 00000240 B030                <1> 	mov	al, '0'
   534 00000242 CD10                <1> 	int 	10h
   535 00000244 B020                <1> 	mov	al, ' '
   536 00000246 CD10                <1> 	int	10h
   537 00000248 E8B200              <1> 	call	L15c
   538 0000024B B020                <1> 	mov	al, ' '
   539 0000024D CD10                <1> 	int	10h
   540                              <1> 	;
   541 0000024F A0[2F6B]            <1> 	mov	al, [fd1_type]
   542 00000252 20C0                <1> 	and	al, al
   543 00000254 741D                <1> 	jz	short L15a
   544 00000256 88C2                <1> 	mov	dl, al
   545 00000258 B046                <1> 	mov	al, 'F'
   546 0000025A CD10                <1> 	int 	10h
   547 0000025C B044                <1> 	mov	al, 'D'
   548 0000025E CD10                <1> 	int 	10h
   549 00000260 B031                <1> 	mov	al, '1'
   550 00000262 CD10                <1> 	int 	10h
   551 00000264 B020                <1> 	mov	al, ' '
   552 00000266 CD10                <1> 	int	10h
   553 00000268 E89200              <1> 	call	L15c
   554 0000026B B020                <1> 	mov	al, ' '
   555 0000026D CD10                <1> 	int	10h
   556 0000026F B020                <1> 	mov	al, ' '
   557 00000271 CD10                <1> 	int	10h
   558                              <1> L15a:
   559 00000273 A0[306B]            <1> 	mov	al, [hd0_type]
   560 00000276 20C0                <1> 	and	al, al
   561 00000278 7479                <1> 	jz	short L15b
   562 0000027A 88C2                <1> 	mov	dl, al
   563 0000027C B048                <1> 	mov	al, 'H'
   564 0000027E CD10                <1> 	int 	10h
   565 00000280 B044                <1> 	mov	al, 'D'
   566 00000282 CD10                <1> 	int 	10h
   567 00000284 B030                <1> 	mov	al, '0'
   568 00000286 CD10                <1> 	int 	10h
   569 00000288 B020                <1> 	mov	al, ' '
   570 0000028A CD10                <1> 	int 	10h
   571 0000028C E86E00              <1> 	call	L15c
   572 0000028F B020                <1> 	mov	al, ' '
   573 00000291 CD10                <1> 	int	10h
   574                              <1> 	;
   575 00000293 A0[316B]            <1> 	mov	al, [hd1_type]
   576 00000296 20C0                <1> 	and	al, al
   577 00000298 7459                <1> 	jz	short L15b
   578 0000029A 88C2                <1> 	mov	dl, al
   579 0000029C B048                <1> 	mov	al, 'H'
   580 0000029E CD10                <1> 	int 	10h
   581 000002A0 B044                <1> 	mov	al, 'D'
   582 000002A2 CD10                <1> 	int 	10h
   583 000002A4 B031                <1> 	mov	al, '1'
   584 000002A6 CD10                <1> 	int 	10h
   585 000002A8 B020                <1> 	mov	al, ' '
   586 000002AA CD10                <1> 	int 	10h
   587 000002AC E84E00              <1> 	call	L15c
   588 000002AF B020                <1> 	mov	al, ' '
   589 000002B1 CD10                <1> 	int	10h
   590                              <1> 	;
   591 000002B3 A0[326B]            <1> 	mov	al, [hd2_type]
   592 000002B6 20C0                <1> 	and	al, al
   593 000002B8 7439                <1> 	jz	short L15b
   594 000002BA 88C2                <1> 	mov	dl, al
   595 000002BC B048                <1> 	mov	al, 'H'
   596 000002BE CD10                <1> 	int 	10h
   597 000002C0 B044                <1> 	mov	al, 'D'
   598 000002C2 CD10                <1> 	int 	10h
   599 000002C4 B032                <1> 	mov	al, '2'
   600 000002C6 CD10                <1> 	int 	10h
   601 000002C8 B020                <1> 	mov	al, ' '
   602 000002CA CD10                <1> 	int 	10h
   603 000002CC E82E00              <1> 	call	L15c
   604 000002CF B020                <1> 	mov	al, ' '
   605 000002D1 CD10                <1> 	int	10h
   606                              <1> 	;
   607 000002D3 A0[336B]            <1> 	mov	al, [hd3_type]
   608 000002D6 20C0                <1> 	and	al, al
   609 000002D8 7419                <1> 	jz	short L15b
   610 000002DA 88C2                <1> 	mov	dl, al
   611 000002DC B048                <1> 	mov	al, 'H'
   612 000002DE CD10                <1> 	int 	10h
   613 000002E0 B044                <1> 	mov	al, 'D'
   614 000002E2 CD10                <1> 	int 	10h
   615 000002E4 B033                <1> 	mov	al, '3'
   616 000002E6 CD10                <1> 	int 	10h
   617 000002E8 B020                <1> 	mov	al, ' '
   618 000002EA CD10                <1> 	int 	10h
   619 000002EC E80E00              <1> 	call	L15c
   620 000002EF B020                <1> 	mov	al, ' '
   621 000002F1 CD10                <1> 	int	10h
   622                              <1> 	;
   623                              <1> L15b:
   624 000002F3 B00D                <1> 	mov	al, 0Dh
   625 000002F5 CD10                <1> 	int 	10h	
   626 000002F7 B00A                <1> 	mov	al, 0Ah
   627 000002F9 CD10                <1> 	int 	10h
   628                              <1> 	;;xor	ah, ah
   629                              <1> 	;;int 	16h	
   630                              <1> 	;
   631 000002FB EB77                <1>         jmp     L16  ; jmp short L16
   632                              <1>         ;
   633                              <1> L15c:
   634 000002FD 88D6                <1> 	mov	dh, dl
   635 000002FF C0EE04              <1> 	shr	dh, 4
   636 00000302 80C630              <1> 	add	dh, 30h
   637 00000305 80E20F              <1> 	and	dl, 15
   638 00000308 80C230              <1> 	add	dl, 30h
   639 0000030B 88F0                <1> 	mov	al, dh
   640 0000030D CD10                <1> 	int	10h
   641 0000030F 88D0                <1> 	mov	al, dl
   642 00000311 CD10                <1> 	int	10h
   643 00000313 C3                  <1> 	retn
   644                              <1> 	;
   645                              <1> 	; end of temporary code for disk searching code check
   646                              <1> 
   647                              <1> ; //////
   648                              <1> 
   649                              <1> set_disk_parms:
   650                              <1> 	; 04/02/2016 (ebx -> bx)
   651                              <1> 	; 10/07/2015
   652                              <1> 	; 14/01/2015
   653                              <1> 	;push	bx
   654 00000314 28FF                <1> 	sub	bh, bh
   655 00000316 8A1E[2B6B]          <1> 	mov	bl, [drv]
   656 0000031A 80FB80              <1> 	cmp	bl, 80h
   657 0000031D 7203                <1> 	jb	short sdp0
   658 0000031F 80EB7E              <1> 	sub	bl, 7Eh
   659                              <1> sdp0:	
   660 00000322 81C3[7A6B]          <1> 	add	bx, drv.status
   661 00000326 C60780              <1>   	mov	byte [bx], 80h ; 'Present' flag
   662                              <1> 	;
   663 00000329 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   664 0000032B 88CC                <1> 	mov	ah, cl ; 
   665 0000032D C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   666 00000330 81EB[7A6B]          <1> 	sub	bx, drv.status
   667 00000334 D0E3                <1> 	shl	bl, 1
   668 00000336 81C3[346B]          <1> 	add	bx, drv.cylinders
   669 0000033A 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   670 0000033B 8907                <1> 	mov	[bx], ax
   671 0000033D 50                  <1> 	push	ax ; ** cylinders
   672 0000033E 81EB[346B]          <1> 	sub	bx, drv.cylinders
   673 00000342 81C3[426B]          <1> 	add	bx, drv.heads
   674 00000346 30E4                <1> 	xor	ah, ah
   675 00000348 88F0                <1> 	mov	al, dh ; heads
   676 0000034A 40                  <1> 	inc	ax
   677 0000034B 8907                <1> 	mov	[bx], ax
   678 0000034D 81EB[426B]          <1>         sub     bx, drv.heads
   679 00000351 81C3[506B]          <1>         add     bx, drv.spt
   680 00000355 30ED                <1> 	xor	ch, ch
   681 00000357 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   682 0000035A 890F                <1> 	mov	[bx], cx
   683 0000035C 81EB[506B]          <1>         sub     bx, drv.spt
   684 00000360 D1E3                <1> 	shl	bx, 1
   685 00000362 81C3[5E6B]          <1> 	add	bx, drv.size ; disk size (in sectors)
   686                              <1> 	; LBA size = cylinders * heads * secpertrack
   687 00000366 F7E1                <1> 	mul	cx 
   688 00000368 89C2                <1> 	mov	dx, ax	; heads*spt					
   689 0000036A 58                  <1> 	pop	ax ; ** cylinders
   690 0000036B 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   691 0000036C F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   692 0000036E 8907                <1> 	mov	[bx], ax
   693 00000370 895702              <1> 	mov	[bx+2], dx
   694                              <1> 	;
   695                              <1> 	;pop	bx
   696 00000373 C3                  <1> 	retn
   697                              <1> 
   698                              <1> ;align 2
   699                              <1> 
   700                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   701                              <1> ;heads	  :  dw 0, 0, 0, 0, 0, 0
   702                              <1> ;spt	  :  dw 0, 0, 0, 0, 0, 0
   703                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   704                              <1> 
   705                              <1> ;last_drv:
   706                              <1> ;	db  0
   707                              <1> ;drv_status:
   708                              <1> ;	db  0,0,0,0,0,0
   709                              <1> ;	db 0
   710                              <1> 
   711                              <1> 
   712                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   713                              <1> 
   714                              <1> L16:
   715                                  
   716                                  	; 10/11/2014
   717 00000374 FA                           	cli	; Disable interrupts (clear interrupt flag)
   718                                  		; Reset Interrupt MASK Registers (Master&Slave)
   719                                  	;mov	al, 0FFh	; mask off all interrupts
   720                                  	;out	21h, al		; on master PIC (8259)
   721                                  	;jmp 	$+2  ; (delay)
   722                                  	;out	0A1h, al	; on slave PIC (8259)
   723                                  	;
   724                                  	; Disable NMI 
   725 00000375 B080                    	mov   	al, 80h 
   726 00000377 E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   727                                  	;23/02/2015
   728 00000379 90                      	nop			;
   729                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   730                                  				; for preventing unknown state (!?)
   731                                  	;
   732                                   	; 20/08/2014
   733                                  	; Moving the kernel 64 KB back (to physical address 0)
   734                                  	; DS = CS = 1000h
   735                                  	; 05/11/2014
   736 0000037A 31C0                    	xor	ax, ax
   737 0000037C 8EC0                    	mov	es, ax ; ES = 0
   738                                  	;
   739 0000037E B90040                  	mov	cx, (KEND - KLOAD)/4
   740 00000381 31F6                    	xor	si, si
   741 00000383 31FF                    	xor	di, di
   742 00000385 F366A5                  	rep	movsd
   743                                  	;
   744 00000388 06                      	push	es ; 0
   745 00000389 68[8D03]                	push	L17
   746 0000038C CB                      	retf
   747                                  	;
   748                                  L17:
   749                                  	; Turn off the floppy drive motor
   750 0000038D BAF203                          mov     dx, 3F2h
   751 00000390 EE                              out     dx, al ; 0 ; 31/12/2013
   752                                  
   753                                  	; Enable access to memory above one megabyte
   754                                  L18:
   755 00000391 E464                    	in	al, 64h
   756 00000393 A802                    	test	al, 2
   757 00000395 75FA                            jnz     short L18
   758 00000397 B0D1                    	mov	al, 0D1h	; Write output port
   759 00000399 E664                    	out	64h, al
   760                                  L19:
   761 0000039B E464                    	in	al, 64h
   762 0000039D A802                    	test	al, 2
   763 0000039F 75FA                            jnz     short L19
   764 000003A1 B0DF                    	mov	al, 0DFh	; Enable A20 line
   765 000003A3 E660                    	out	60h, al
   766                                  ;L20:
   767                                  	;
   768                                  	; Load global descriptor table register
   769                                  
   770                                          ;mov     ax, cs
   771                                          ;mov     ds, ax
   772                                  
   773 000003A5 2E0F0116[5068]                  lgdt    [cs:gdtd]
   774                                  
   775 000003AB 0F20C0                          mov     eax, cr0
   776                                  	; or 	eax, 1
   777 000003AE 40                      	inc     ax
   778 000003AF 0F22C0                  	mov     cr0, eax
   779                                  
   780                                  	; Jump to 32 bit code
   781                                  	
   782 000003B2 66                      	db 66h 			; Prefix for 32-bit
   783 000003B3 EA                      	db 0EAh 		; Opcode for far jump
   784 000003B4 [BA030000]              	dd StartPM 		; Offset to start, 32-bit
   785                                  				; (1000h:StartPM = StartPM + 10000h)
   786 000003B8 0800                    	dw KCODE		; This is the selector for CODE32_DESCRIPTOR,
   787                                  				; assuming that StartPM resides in code32
   788                                  
   789                                  [BITS 32] 
   790                                  
   791                                  StartPM:
   792                                  	; Kernel Base Address = 0 ; 30/12/2013
   793 000003BA 66B81000                	mov ax, KDATA           ; Save data segment identifier
   794 000003BE 8ED8                            mov ds, ax              ; Move a valid data segment into DS register
   795 000003C0 8EC0                           	mov es, ax              ; Move data segment into ES register
   796 000003C2 8EE0                           	mov fs, ax              ; Move data segment into FS register
   797 000003C4 8EE8                          	mov gs, ax              ; Move data segment into GS register
   798 000003C6 8ED0                            mov ss, ax              ; Move data segment into SS register
   799 000003C8 BC00000900                      mov esp, 90000h         ; Move the stack pointer to 090000h
   800                                  
   801                                  clear_bss: ; Clear uninitialized data area
   802                                  	; 11/03/2015
   803 000003CD 31C0                    	xor  eax, eax ; 0
   804 000003CF B9CB050000              	mov  ecx, (bss_end - bss_start)/4
   805                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   806 000003D4 BF[106E0000]            	mov  edi, bss_start	
   807 000003D9 F3AB                    	rep  stosd  		
   808                                  
   809                                  memory_init:
   810                                  	; Initialize memory allocation table and page tables
   811                                  	; 16/11/2014
   812                                  	; 15/11/2014
   813                                  	; 07/11/2014
   814                                  	; 06/11/2014
   815                                  	; 05/11/2014
   816                                  	; 04/11/2014
   817                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   818                                  	;
   819                                  ;	xor	eax, eax
   820                                  ;	xor 	ecx, ecx
   821 000003DB B108                    	mov	cl, 8
   822 000003DD BF00001000              	mov	edi, MEM_ALLOC_TBL	
   823 000003E2 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   824                                  				   ; for the first 1 MB memory
   825                                  	;
   826 000003E4 668B0D[FE6D0000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   827                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   828 000003EB 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   829 000003EF 890D[80700000]          	mov	[free_pages], ecx
   830 000003F5 668B15[006E0000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   831                                  				   ; between 16 MB and 4 GB.	
   832 000003FC 6609D2                  	or	dx, dx
   833 000003FF 7413                    	jz	short mi_0
   834                                  	;
   835 00000401 6689D0                  	mov	ax, dx
   836 00000404 C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   837 00000407 0105[80700000]          	add	[free_pages], eax
   838 0000040D 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   839 00000412 EB07                    	jmp	short mi_1
   840                                  mi_0:
   841 00000414 6689C8                  	mov	ax, cx
   842 00000417 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   843                                  mi_1:
   844 0000041B A3[7C700000]            	mov	[memory_size], eax ; Total available memory in pages
   845                                  				   ; 1 alloc. tbl. bit = 1 memory page
   846                                  				   ; 32 allocation bits = 32 mem. pages   
   847                                  	;
   848 00000420 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   849 00000425 C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   850                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   851                                  				   ;  --> x M.A.T. pages, if y = 0
   852 00000428 66A3[90700000]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   853 0000042E C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   854                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   855 00000431 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   856                                  	; Set/Calculate Kernel's Page Directory Address
   857 00000433 81C300001000            	add	ebx, MEM_ALLOC_TBL
   858 00000439 891D[78700000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   859                                  				   ; just after the last M.A.T. page
   860                                  	;
   861 0000043F 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   862 00000442 A3[88700000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   863                                  	;			   ; (allocation status search must be 
   864                                  				   ; stopped after here)	
   865 00000447 31C0                    	xor	eax, eax
   866 00000449 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   867 0000044A 6651                    	push	cx
   868 0000044C C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   869                                  				   ; count of 32 allocation bits
   870 0000044F F3AB                    	rep	stosd
   871 00000451 6659                    	pop	cx
   872 00000453 40                      	inc	eax		   ; 0	
   873 00000454 80E11F                  	and	cl, 31		   ; remain bits
   874 00000457 7412                    	jz	short mi_4
   875 00000459 8907                    	mov	[edi], eax	   ; reset	
   876                                  mi_2:
   877 0000045B 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   878 0000045E FEC9                    	dec	cl
   879 00000460 7404                    	jz	short mi_3
   880 00000462 FEC0                    	inc	al
   881 00000464 EBF5                    	jmp	short mi_2
   882                                  mi_3:
   883 00000466 28C0                    	sub	al, al	   	   ; 0
   884 00000468 83C704                  	add	edi, 4		   ; 15/11/2014
   885                                  mi_4:
   886 0000046B 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   887 0000046E 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   888                                  	;	
   889 00000470 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   890                                  	;	
   891 00000475 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   892 00000477 7406                    	jz	short mi_5	  ; jump if EDI points to 
   893                                  				  ;         end of first 16 MB	
   894 00000479 D1E9                    	shr	ecx, 1		  ; convert to dword count
   895 0000047B D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   896 0000047D F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   897                                  				  ; (memory hole under 16 MB)
   898                                  mi_5:
   899 0000047F 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   900 00000482 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   901 00000484 9C                      	pushf			  ; 16/11/2014		
   902 00000485 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   903 00000486 F3AB                    	rep	stosd
   904 00000488 40                      	inc	eax		  ; 0
   905 00000489 9D                      	popf			  ; 16/11/2014
   906 0000048A 7305                    	jnc	short mi_6
   907 0000048C 6648                    	dec	ax		  ; eax = 0000FFFFh
   908 0000048E AB                      	stosd
   909 0000048F 6640                    	inc	ax		  ; 0		
   910                                  mi_6:
   911 00000491 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   912 00000493 730A                    	jnb	short mi_7	  ; end of memory allocation table
   913                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   914 00000495 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   915 00000497 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   916 00000499 D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   917 0000049B D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   918 0000049D F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   919                                  mi_7:
   920                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   921 0000049F BA00001000              	mov	edx, MEM_ALLOC_TBL
   922                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   923                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   924 000004A4 668B0D[90700000]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   925 000004AB 89D7                    	mov	edi, edx
   926 000004AD C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   927                                  				  ; byte offset in M.A.T.
   928                                  				  ; (1 M.A.T. byte points to 
   929                                  				  ;	      32768 bytes)
   930                                  				  ; Note: MEM_ALLOC_TBL address 
   931                                  				  ; must be aligned on 128 KB 
   932                                  				  ; boundary!
   933 000004B0 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   934                                  	; eax = 0
   935 000004B2 290D[80700000]          	sub	[free_pages], ecx ; 07/11/2014
   936                                  mi_8:
   937 000004B8 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   938                                  	;dec	bl
   939 000004BB FEC9                    	dec	cl
   940 000004BD 7404                    	jz	short mi_9
   941 000004BF FEC0                    	inc	al
   942 000004C1 EBF5                    	jmp	short mi_8
   943                                  mi_9:
   944                                  	;
   945                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   946                                  	;		(allocate pages for system page tables)
   947                                  
   948                                  	; edx = MEM_ALLOC_TBL
   949 000004C3 8B0D[7C700000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   950 000004C9 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   951 000004CF C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   952                                  				 ; page table count (PDE count)
   953                                  	;
   954 000004D2 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   955                                  	;
   956 000004D3 41                      	inc	ecx		 ; +1 for kernel page directory	
   957                                  	;
   958 000004D4 290D[80700000]          	sub	[free_pages], ecx ; 07/11/2014
   959                                  	;
   960 000004DA 8B35[78700000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   961 000004E0 C1EE0C                  	shr	esi, 12		 ; convert to page number
   962                                  mi_10:
   963 000004E3 89F0                    	mov	eax, esi	 ; allocation bit offset		 
   964 000004E5 89C3                    	mov	ebx, eax
   965 000004E7 C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   966 000004EA 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   967                                  				 ;   to align on dword boundary
   968 000004ED 83E01F                  	and	eax, 31		 ; set allocation bit position 
   969                                  				 ;  (bit 0 to bit 31)
   970                                  	;
   971 000004F0 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   972                                  	;
   973 000004F2 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   974                                  	;
   975 000004F5 46                      	inc	esi		 ; next page table
   976 000004F6 E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   977                                  				 ; (ecx = page table count + 1)		
   978                                  	;
   979 000004F8 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
   980                                  	;
   981                                  	; Initialize Kernel Page Directory and Kernel Page Tables
   982                                  	;
   983                                  	; Initialize Kernel's Page Directory
   984 000004F9 8B3D[78700000]          	mov	edi, [k_page_dir]
   985 000004FF 89F8                    	mov	eax, edi
   986 00000501 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
   987                                  		     	      ; supervisor + read&write + present
   988 00000503 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
   989                                  mi_11:
   990 00000505 0500100000              	add	eax, 4096	; Add page size (PGSZ)
   991                                  			        ; EAX points to next page table
   992 0000050A AB                      	stosd
   993 0000050B E2F8                    	loop	mi_11
   994 0000050D 29C0                    	sub	eax, eax	; Empty PDE
   995 0000050F 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
   996 00000513 29D1                    	sub	ecx, edx
   997 00000515 7402                    	jz	short mi_12
   998 00000517 F3AB                    	rep	stosd 		; clear remain (empty) PDEs
   999                                  	;
  1000                                  	; Initialization of Kernel's Page Directory is OK, here.
  1001                                  mi_12:
  1002                                  	; Initialize Kernel's Page Tables
  1003                                  	;
  1004                                  	; (EDI points to address of page table 0)
  1005                                  	; eax = 0
  1006 00000519 8B0D[7C700000]          	mov	ecx, [memory_size] ; memory size in pages
  1007 0000051F 89CA                    	mov	edx, ecx	; (***)
  1008 00000521 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
  1009                                  			     ; supervisor + read&write + present 	
  1010                                  mi_13:
  1011 00000523 AB                      	stosd
  1012 00000524 0500100000              	add	eax, 4096	
  1013 00000529 E2F8                    	loop	mi_13	
  1014 0000052B 6681E2FF03              	and	dx, 1023	; (***)
  1015 00000530 740B                    	jz	short mi_14
  1016 00000532 66B90004                	mov	cx, 1024	
  1017 00000536 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
  1018 00000539 31C0                    	xor	eax, eax
  1019 0000053B F3AB                    	rep	stosd		; clear remain (empty) PTEs 
  1020                                  				; of the last page table
  1021                                  mi_14:
  1022                                  	;  Initialization of Kernel's Page Tables is OK, here.
  1023                                  	;
  1024 0000053D 89F8                    	mov	eax, edi	; end of the last page table page
  1025                                  			        ; (beginging of user space pages)
  1026 0000053F C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
  1027 00000542 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
  1028                                  				; aligning on dword boundary	
  1029                                  	 
  1030 00000544 A3[8C700000]            	mov	[first_page], eax
  1031 00000549 A3[84700000]            	mov	[next_page], eax ; The first free page pointer
  1032                                  				 ; for user programs
  1033                                  				 ; (Offset in Mem. Alloc. Tbl.)	
  1034                                  	;
  1035                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
  1036                                  	;
  1037                                  	
  1038                                  	; Enable paging
  1039                                  	;
  1040 0000054E A1[78700000]                    mov     eax, [k_page_dir]
  1041 00000553 0F22D8                  	mov	cr3, eax
  1042 00000556 0F20C0                  	mov	eax, cr0
  1043 00000559 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
  1044 0000055E 0F22C0                  	mov	cr0, eax
  1045                                          ;jmp    KCODE:StartPMP
  1046                                  
  1047 00000561 EA                      	db 0EAh 		; Opcode for far jump
  1048 00000562 [68050000]                      dd StartPMP		; 32 bit offset
  1049 00000566 0800                    	dw KCODE		; kernel code segment descriptor
  1050                                  
  1051                                  
  1052                                  StartPMP:
  1053                                  	; 06/11//2014
  1054                                  	; Clear video page 0
  1055                                  	;
  1056                                  	; Temporary Code
  1057                                  	;
  1058 00000568 B9E8030000              	mov	ecx, 80*25/2
  1059 0000056D BF00800B00              	mov	edi, 0B8000h
  1060 00000572 31C0                    	xor	eax, eax	; black background, black fore color
  1061 00000574 F3AB                    	rep	stosd
  1062                                  	
  1063                                  	; 19/08/2014
  1064                                  	; Kernel Base Address = 0
  1065                                  	; It is mapped to (physically) 0 in the page table.
  1066                                  	; So, here is exactly 'StartPMP' address.
  1067                                  	;
  1068                                  	;;mov	ah, 4Eh	; Red background, yellow forecolor
  1069                                  	;;mov	esi, msgPM
  1070                                  	;; 14/08/2015 (kernel version message will appear
  1071                                  	;;	       when protected mode and paging is enabled)
  1072 00000576 B40B                    	mov	ah, 0Bh ; Black background, light cyan forecolor
  1073 00000578 BE[906B0000]            	mov	esi, msgKVER
  1074 0000057D BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
  1075                                  	; 20/08/2014
  1076 00000582 E896010000              	call	printk
  1077                                  
  1078                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
  1079                                  	; // Set IRQ offsets
  1080                                  	;
  1081                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
  1082                                  	;
  1083                                  					;; ICW1
  1084 00000587 B011                    	mov	al, 11h			; Initialization sequence
  1085 00000589 E620                    	out	20h, al			; 	8259A-1
  1086                                  	; jmp 	$+2
  1087 0000058B E6A0                    	out	0A0h, al		; 	8259A-2
  1088                                  					;; ICW2
  1089 0000058D B020                    	mov	al, 20h			; Start of hardware ints (20h)
  1090 0000058F E621                    	out	21h, al			;	for 8259A-1
  1091                                  	; jmp 	$+2
  1092 00000591 B028                    	mov	al, 28h			; Start of hardware ints (28h)
  1093 00000593 E6A1                    	out	0A1h, al		; 	for 8259A-2
  1094                                  					;
  1095 00000595 B004                    	mov	al, 04h			;; ICW3
  1096 00000597 E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
  1097                                  	; jmp 	$+2
  1098 00000599 B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
  1099 0000059B E6A1                    	out	0A1h, al		;
  1100                                  					;; ICW4
  1101 0000059D B001                    	mov	al, 01h	 		;
  1102 0000059F E621                    	out	21h, al			; 	8086 mode, normal EOI	
  1103                                  	; jmp 	$+2
  1104 000005A1 E6A1                    	out	0A1h, al		;	for both chips.
  1105                                  
  1106                                  	;mov	al, 0FFh	; mask off all interrupts for now
  1107                                  	;out	21h, al
  1108                                  	;; jmp 	$+2
  1109                                  	;out	0A1h, al
  1110                                  
  1111                                  	; 02/04/2015
  1112                                  	; 26/03/2015 System call (INT 30h) modification
  1113                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
  1114                                  	;
  1115                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
  1116                                  	;  setup_idt:
  1117                                  	;
  1118                                          ;; 16/02/2015
  1119                                  	;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1120                                  	; 21/08/2014 (timer_int)
  1121 000005A3 BE[5C680000]            	mov	esi, ilist
  1122 000005A8 8D3D[106E0000]          	lea	edi, [idt]
  1123                                  	; 26/03/2015
  1124 000005AE B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
  1125                                  	; 02/04/2015
  1126 000005B3 BB00000800              	mov	ebx,  80000h
  1127                                  rp_sidt1:
  1128 000005B8 AD                      	lodsd
  1129 000005B9 89C2                    	mov	edx, eax
  1130 000005BB 66BA008E                	mov	dx, 8E00h
  1131 000005BF 6689C3                  	mov	bx, ax
  1132 000005C2 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
  1133                                         			        ; /* interrupt gate - dpl=0, present */
  1134 000005C4 AB                      	stosd	; selector & offset bits 0-15 	
  1135 000005C5 89D0                    	mov	eax, edx
  1136 000005C7 AB                      	stosd	; attributes & offset bits 16-23
  1137 000005C8 E2EE                    	loop	rp_sidt1
  1138 000005CA B110                    	mov	cl, 16        ; 16 software interrupts (INT 30h to INT 3Fh)
  1139                                  rp_sidt2:
  1140 000005CC AD                      	lodsd
  1141 000005CD 21C0                    	and	eax, eax
  1142 000005CF 7413                    	jz	short rp_sidt3
  1143 000005D1 89C2                    	mov	edx, eax
  1144 000005D3 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1145 000005D7 6689C3                  	mov	bx, ax
  1146 000005DA 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1147 000005DC AB                      	stosd
  1148 000005DD 89D0                    	mov	eax, edx
  1149 000005DF AB                      	stosd
  1150 000005E0 E2EA                    	loop	rp_sidt2
  1151 000005E2 EB16                    	jmp	short sidt_OK
  1152                                  rp_sidt3:
  1153 000005E4 B8[470A0000]            	mov	eax, ignore_int
  1154 000005E9 89C2                    	mov	edx, eax
  1155 000005EB 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1156 000005EF 6689C3                  	mov	bx, ax
  1157 000005F2 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1158                                  rp_sidt4:
  1159 000005F4 AB                      	stosd
  1160 000005F5 92                      	xchg	eax, edx
  1161 000005F6 AB                      	stosd
  1162 000005F7 92                      	xchg	edx, eax
  1163 000005F8 E2FA                    	loop	rp_sidt4
  1164                                  sidt_OK: 
  1165 000005FA 0F011D[56680000]        	lidt 	[idtd]
  1166                                  	;
  1167                                  	; TSS descriptor setup ; 24/03/2015
  1168 00000601 B8[10700000]            	mov	eax, task_state_segment
  1169 00000606 66A3[4A680000]          	mov	[gdt_tss0], ax
  1170 0000060C C1C010                  	rol	eax, 16
  1171 0000060F A2[4C680000]            	mov	[gdt_tss1], al
  1172 00000614 8825[4F680000]          	mov	[gdt_tss2], ah
  1173 0000061A 66C705[76700000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
  1174 00000622 00                 
  1175                                  		; 
  1176                                  		; IO Map Base address (When this address points
  1177                                  		; to end of the TSS, CPU does not use IO port 
  1178                                  		; permission bit map for RING 3 IO permissions, 
  1179                                  		; access to any IO ports in ring 3 will be forbidden.)
  1180                                   		;
  1181                                  	;mov	[tss.esp0], esp ; TSS offset 4
  1182                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
  1183 00000623 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
  1184                                  			 ; occurs (or a system call -software INT- is requested)
  1185                                  			 ; while cpu running in ring 3 (in user mode).				
  1186                                  			 ; (Kernel stack pointer and segment will be loaded
  1187                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
  1188 00000627 0F00D8                  	ltr	ax  ; Load task register
  1189                                  	;
  1190                                  esp0_set0:
  1191                                  	; 30/07/2015
  1192 0000062A 8B0D[7C700000]          	mov 	ecx, [memory_size] ; memory size in pages
  1193 00000630 C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
  1194 00000633 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
  1195                                  			  ; (kernel mode virtual address)
  1196 00000639 7605                    	jna	short esp0_set1
  1197                                  	;
  1198                                  	; If available memory > CORE (end of the 1st 4 MB)
  1199                                  	; set stack pointer to CORE
  1200                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
  1201                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
  1202 0000063B B900004000              	mov	ecx, CORE
  1203                                  esp0_set1:
  1204 00000640 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
  1205                                  esp0_set_ok:
  1206                                  	; 30/07/2015 (**tss.esp0**) 
  1207 00000642 8925[14700000]          	mov	[tss.esp0], esp
  1208 00000648 66C705[18700000]10-             mov     word [tss.ss0], KDATA
  1209 00000650 00                 
  1210                                  	; 14/08/2015
  1211                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
  1212                                  	;
  1213                                  	;cli	; Disable interrupts (for CPU)
  1214                                  	;    (CPU will not handle hardware interrupts, except NMI!)
  1215                                  	;
  1216 00000651 30C0                    	xor	al, al		; Enable all hardware interrupts!
  1217 00000653 E621                    	out	21h, al		; (IBM PC-AT compatibility)
  1218 00000655 EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
  1219 00000657 E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
  1220                                  				; (Even if related hardware component
  1221                                  				;  does not exist!)
  1222                                  	; Enable NMI 
  1223 00000659 B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
  1224 0000065B E670                    	out  	70h, al
  1225                                  	; 23/02/2015
  1226 0000065D 90                      	nop
  1227 0000065E E471                    	in	al, 71h		; read in 71h just after writing out to 70h
  1228                                  				; for preventing unknown state (!?)
  1229                                  	;
  1230                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
  1231                                  	;
  1232                                  	; 02/09/2014
  1233 00000660 6631DB                  	xor	bx, bx
  1234 00000663 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
  1235 00000667 E8920F0000              	call	set_cpos
  1236                                  	;
  1237                                  	; 06/11/2014
  1238                                  	; Temporary Code
  1239                                  	;
  1240 0000066C E8C2110000              	call	memory_info
  1241                                  	; 14/08/2015
  1242                                  	;call getch ; 28/02/2015
  1243                                  drv_init:
  1244 00000671 FB                      	sti	; Enable Interrupts 
  1245                                  	; 06/02/2015
  1246 00000672 8B15[306B0000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
  1247 00000678 668B1D[2E6B0000]        	mov	bx, [fd0_type] ; fd0, fd1
  1248                                  	; 22/02/2015
  1249 0000067F 6621DB                  	and	bx, bx
  1250 00000682 751B                    	jnz	short di1
  1251                                  	;
  1252 00000684 09D2                    	or 	edx, edx
  1253 00000686 7529                    	jnz	short di2
  1254                                  	;
  1255                                  setup_error:
  1256 00000688 BE[B36C0000]            	mov 	esi, setup_error_msg
  1257                                  psem:	
  1258 0000068D AC                      	lodsb
  1259 0000068E 08C0                    	or	al, al
  1260                                  	;jz	short haltx ; 22/02/2015
  1261 00000690 7426                    	jz	short di3
  1262 00000692 56                      	push	esi
  1263 00000693 31DB                    	xor	ebx, ebx ; 0
  1264                                  			; Video page 0 (bl=0)
  1265 00000695 B407                    	mov	ah, 07h ; Black background, 
  1266                                  			; light gray forecolor
  1267 00000697 E83E0E0000              	call	write_tty
  1268 0000069C 5E                      	pop	esi
  1269 0000069D EBEE                    	jmp	short psem
  1270                                  
  1271                                  di1:
  1272                                  	; supress 'jmp short T6'
  1273                                  	;  (activate fdc motor control code)
  1274 0000069F 66C705[9E070000]90-     	mov	word [T5], 9090h ; nop
  1275 000006A7 90                 
  1276                                  	;
  1277                                  	;mov	ax, int_0Eh	; IRQ 6 handler
  1278                                  	;mov	di, 0Eh*4	; IRQ 6 vector
  1279                                  	;stosw
  1280                                  	;mov 	ax, cs
  1281                                  	;stosw
  1282                                  	;; 16/02/2015
  1283                                          ;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1284                                  	;
  1285 000006A8 E8D8200000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
  1286                                  	;
  1287 000006AD 09D2                    	or	edx, edx
  1288 000006AF 7407                            jz      short di3
  1289                                  di2:
  1290 000006B1 E814210000              	call   	DISK_SETUP	; Initialize Fixed Disks
  1291 000006B6 72D0                            jc      short setup_error
  1292                                  di3:
  1293 000006B8 E84A110000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
  1294                                  	;
  1295 000006BD E8B3600000              	call	display_disks ; 07/03/2015  (Temporary)
  1296                                  ;haltx:
  1297                                  	; 14/08/2015
  1298                                  	;call	getch ; 22/02/2015
  1299 000006C2 FB                      	sti	; Enable interrupts (for CPU)
  1300                                  	; 14/08/2015
  1301 000006C3 B9FFFFFF0F              	mov 	ecx, 0FFFFFFFh	
  1302                                  md_info_msg_wait:
  1303 000006C8 51                      	push 	ecx
  1304 000006C9 B001                    	mov	al, 1
  1305 000006CB 8A25[A6700000]          	mov 	ah, [ptty] ; active (current) video page
  1306 000006D1 E8D45D0000              	call	getc_n
  1307 000006D6 59                      	pop	ecx
  1308 000006D7 7502                    	jnz	short md_info_msg_ok
  1309 000006D9 E2ED                    	loop	md_info_msg_wait
  1310                                  md_info_msg_ok:
  1311                                  	; 30/06/2015
  1312 000006DB E801310000              	call	sys_init
  1313                                  	;
  1314                                  	;jmp 	cpu_reset ; 22/02/2015
  1315                                  hang:  
  1316                                  	; 23/02/2015
  1317                                  	;sti			; Enable interrupts
  1318 000006E0 F4                      	hlt
  1319                                  	;
  1320                                  	;nop
  1321                                  	;; 03/12/2014
  1322                                  	;; 28/08/2014
  1323                                  	;mov	ah, 11h
  1324                                  	;call	getc
  1325                                  	;jz      _c8
  1326                                  	;
  1327                                  	; 23/02/2015
  1328                                  	; 06/02/2015
  1329                                  	; 07/09/2014
  1330 000006E1 31DB                    	xor	ebx, ebx
  1331 000006E3 8A1D[A6700000]          	mov	bl, [ptty]	; active_page
  1332 000006E9 89DE                    	mov	esi, ebx
  1333 000006EB 66D1E6                  	shl 	si, 1
  1334 000006EE 81C6[A8700000]          	add	esi, ttychr
  1335 000006F4 668B06                  	mov	ax, [esi]
  1336 000006F7 6621C0                  	and	ax, ax
  1337                                  	;jz	short _c8
  1338 000006FA 74E4                    	jz	short hang
  1339 000006FC 66C7060000              	mov	word [esi], 0
  1340 00000701 80FB03                  	cmp	bl, 3		; Video page 3
  1341                                  	;jb	short _c8
  1342 00000704 72DA                    	jb	short hang
  1343                                  	;	
  1344                                  	; 02/09/2014
  1345 00000706 B40E                    	mov	ah, 0Eh		; Yellow character 
  1346                                  				; on black background
  1347                                  	; 07/09/2014
  1348                                  nxtl:
  1349 00000708 6653                    	push	bx
  1350                                  	;
  1351                                  	;xor	bx, bx		; bl = 0 (video page 0)
  1352                                  				; bh = 0 (video mode)
  1353                                  				; Retro UNIX 386 v1 - Video Mode 0
  1354                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
  1355 0000070A 6650                    	push	ax
  1356 0000070C E8C90D0000              	call 	write_tty
  1357 00000711 6658                    	pop	ax
  1358 00000713 665B                    	pop	bx ; 07/09/2014
  1359 00000715 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
  1360                                  	;jne	short _c8
  1361 00000717 75C7                    	jne	short hang
  1362 00000719 B00A                    	mov	al, 0Ah		; next line
  1363 0000071B EBEB                    	jmp	short nxtl
  1364                                  	
  1365                                  ;_c8:
  1366                                  ;	; 25/08/2014
  1367                                  ;	cli				; Disable interrupts
  1368                                  ;	mov	al, [scounter + 1]
  1369                                  ;	and	al, al
  1370                                  ;	jnz	hang
  1371                                  ;	call	rtc_p
  1372                                  ;	jmp     hang
  1373                                  
  1374                                  
  1375                                  	; 27/08/2014
  1376                                  	; 20/08/2014
  1377                                  printk:
  1378                                          ;mov    edi, [scr_row]
  1379                                  pkl:
  1380 0000071D AC                      	lodsb
  1381 0000071E 08C0                    	or 	al, al
  1382 00000720 7404                    	jz	short pkr
  1383 00000722 66AB                    	stosw
  1384 00000724 EBF7                    	jmp	short pkl
  1385                                  pkr:
  1386 00000726 C3                      	retn
  1387                                  
  1388                                  ; 25/07/2015
  1389                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
  1390                                  ; 17/02/2015
  1391                                  ; 06/02/2015 (unix386.s)
  1392                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
  1393                                  ;
  1394                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
  1395                                  ;
  1396                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
  1397                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
  1398                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
  1399                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
  1400                                  ;									       :
  1401                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
  1402                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
  1403                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
  1404                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
  1405                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
  1406                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
  1407                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
  1408                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
  1409                                  ;-------------------------------------------------------------------------------
  1410                                  ;
  1411                                  
  1412                                  timer_int:	; IRQ 0
  1413                                  ;int_08h:	; Timer
  1414                                  	; 14/10/2015
  1415                                  	; Here, we are simulating system call entry (for task switch)
  1416                                  	; (If multitasking is enabled, 
  1417                                  	; 'clock' procedure may jump to 'sysrelease')
  1418 00000727 1E                      	push	ds
  1419 00000728 06                      	push	es
  1420 00000729 0FA0                    	push	fs
  1421 0000072B 0FA8                    	push	gs
  1422 0000072D 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1423 0000072E 66B91000                	mov     cx, KDATA
  1424 00000732 8ED9                            mov     ds, cx
  1425 00000734 8EC1                            mov     es, cx
  1426 00000736 8EE1                            mov     fs, cx
  1427 00000738 8EE9                            mov     gs, cx
  1428                                  	;
  1429 0000073A 0F20D9                  	mov	ecx, cr3
  1430 0000073D 890D[DC070000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1431                                  	;
  1432 00000743 3B0D[78700000]          	cmp 	ecx, [k_page_dir]
  1433 00000749 741F                    	je	short T3
  1434                                  	;
  1435                                  	; timer interrupt has been occurred while OS is in user mode
  1436 0000074B A3[58740000]            	mov 	[u.r0], eax
  1437 00000750 89E1                    	mov	ecx, esp
  1438 00000752 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1439 00000755 890D[50740000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1440 0000075B 8925[54740000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1441                                  	;
  1442 00000761 8B0D[78700000]          	mov	ecx, [k_page_dir]
  1443 00000767 0F22D9                  	mov	cr3, ecx
  1444                                  T3:
  1445 0000076A FB                      	sti				; INTERRUPTS BACK ON
  1446 0000076B 66FF05[F4700000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
  1447 00000772 7507                    	JNZ	short T4		; GO TO TEST_DAY
  1448 00000774 66FF05[F6700000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
  1449                                  T4:					; TEST_DAY
  1450 0000077B 66833D[F6700000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
  1451 00000783 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1452 00000785 66813D[F4700000]B0-     	CMP	word [TIMER_LOW],0B0H
  1453 0000078D 00                 
  1454 0000078E 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1455                                  
  1456                                  ;-----	TIMER HAS GONE 24 HOURS
  1457                                  	;;SUB	AX,AX
  1458                                  	;MOV	[TIMER_HIGH],AX
  1459                                  	;MOV	[TIMER_LOW],AX
  1460 00000790 29C0                    	sub	eax, eax
  1461 00000792 A3[F4700000]            	mov	[TIMER_LH], eax
  1462                                  	;	
  1463 00000797 C605[F8700000]01        	MOV	byte [TIMER_OFL],1
  1464                                  
  1465                                  ;-----	TEST FOR DISKETTE TIME OUT
  1466                                  
  1467                                  T5:
  1468                                  	; 23/12/2014
  1469 0000079E EB1D                    	jmp	short T6		; will be replaced with nop, nop
  1470                                  					; (9090h) if a floppy disk
  1471                                  					; is detected.
  1472                                  	;mov	al,[CS:MOTOR_COUNT]
  1473 000007A0 A0[FB700000]            	mov	al, [MOTOR_COUNT]
  1474 000007A5 FEC8                    	dec	al
  1475                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1476 000007A7 A2[FB700000]            	mov	[MOTOR_COUNT], al
  1477                                  	;mov	[ORG_MOTOR_COUNT], al
  1478 000007AC 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
  1479 000007AE B0F0                    	mov 	al,0F0h
  1480                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
  1481 000007B0 2005[FA700000]          	and	[MOTOR_STATUS], al
  1482                                  	;and	[ORG_MOTOR_STATUS], al
  1483 000007B6 B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
  1484                                  					; bit 2 = enable controller
  1485                                  					;	1 = normal operation
  1486                                  					;	0 = reset	
  1487                                  					; bit 0, 1 = drive select
  1488                                  					; bit 4-7 = motor running bits 
  1489 000007B8 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
  1490 000007BC EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
  1491                                  T6:	
  1492                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
  1493                                  					; TIMER TICK INTERRUPT
  1494                                  	;;inc	word [wait_count] ;;27/02/2015
  1495                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
  1496                                  	;;;;cli
  1497                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
  1498 000007BD FF15[D8070000]          	call	[x_timer] ; 14/05/2015
  1499                                  T7:
  1500                                  	; 14/10/2015
  1501 000007C3 B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  1502 000007C5 FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  1503 000007C6 E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  1504                                  	;
  1505 000007C8 A1[DC070000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1506 000007CD 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1507                                  	;
  1508 000007D0 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1509                                  	;
  1510 000007D1 0FA9                    	pop	gs
  1511 000007D3 0FA1                    	pop	fs
  1512 000007D5 07                      	pop	es
  1513 000007D6 1F                      	pop	ds
  1514 000007D7 CF                      	iretd	; return from interrupt
  1515                                  
  1516                                  
  1517                                  ; ////////////////
  1518                                  
  1519                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
  1520                                  x_timer:
  1521 000007D8 [E0070000]              	dd 	u_timer			; 14/05/2015
  1522                                  	;dd	clock
  1523                                  
  1524                                  ; 14/10/2015
  1525 000007DC 00000000                cr3reg: dd 0
  1526                                  
  1527                                  	; 06/02/2015
  1528                                  	; 07/09/2014
  1529                                  	; 21/08/2014
  1530                                  u_timer:
  1531                                  ;timer_int:	; IRQ 0
  1532                                  	; 06/02/2015
  1533                                  	;push	eax
  1534                                  	;push	edx
  1535                                  	;push	ecx
  1536                                  	;push	ebx
  1537                                  	;push	ds
  1538                                  	;push	es
  1539                                  	;mov	eax, KDATA
  1540                                  	;mov	ds, ax
  1541                                  	;mov	es, ax
  1542 000007E0 FF05[BC700000]          	inc	dword [tcount]
  1543 000007E6 BB[006C0000]            	mov	ebx, tcountstr + 4
  1544 000007EB 66A1[BC700000]          	mov	ax, [tcount]
  1545 000007F1 B90A000000              	mov	ecx, 10
  1546                                  rp_divtcnt:
  1547 000007F6 31D2                    	xor	edx, edx
  1548 000007F8 F7F1                    	div	ecx
  1549 000007FA 80C230                  	add	dl, 30h
  1550 000007FD 8813                    	mov	[ebx], dl
  1551 000007FF 6609C0                  	or	ax, ax
  1552 00000802 7403                    	jz	short print_lzero
  1553 00000804 4B                      	dec	ebx
  1554 00000805 EBEF                    	jmp	short rp_divtcnt
  1555                                  print_lzero:
  1556 00000807 81FB[FC6B0000]          	cmp	ebx, tcountstr
  1557 0000080D 7606                    	jna	short print_tcount
  1558 0000080F 4B                      	dec	ebx
  1559 00000810 C60330                   	mov	byte [ebx], 30h
  1560 00000813 EBF2                    	jmp	short print_lzero
  1561                                  print_tcount:
  1562 00000815 56                      	push	esi
  1563 00000816 57                      	push	edi
  1564 00000817 BE[D86B0000]            	mov	esi, timer_msg ; Timer interrupt message
  1565                                  	; 07/09/2014
  1566 0000081C 66BB0100                	mov	bx, 1		; Video page 1
  1567                                  ptmsg:
  1568 00000820 AC                      	lodsb
  1569 00000821 08C0                    	or	al, al
  1570 00000823 740F                    	jz	short ptmsg_ok
  1571 00000825 56                      	push	esi
  1572 00000826 6653                    	push	bx
  1573 00000828 B42F                            mov     ah,  2Fh ; Green background, white forecolor
  1574 0000082A E8AB0C0000              	call 	write_tty
  1575 0000082F 665B                    	pop	bx
  1576 00000831 5E                      	pop	esi
  1577 00000832 EBEC                    	jmp	short ptmsg
  1578                                  	;; 27/08/2014
  1579                                  	;mov     edi, 0B8000h + 0A0h ; Row 1
  1580                                  	;call	printk
  1581                                  	;
  1582                                  ptmsg_ok:
  1583                                  	; 07/09/2014
  1584 00000834 6631D2                  	xor	dx, dx		; column 0, row 0
  1585 00000837 E8C20D0000              	call	set_cpos	; set cursor position to 0,0 
  1586                                  	; 23/02/2015
  1587                                  	; 25/08/2014
  1588                                  	;mov	ebx, scounter		; (seconds counter)
  1589                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1590                                  ;	dec	byte [scounter+1]
  1591                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1592                                  ;	jns	short u_timer_retn
  1593                                  	; 26/02/2015
  1594                                  ;	call	rtc_p
  1595                                  ;	mov	ebx, scounter		; (seconds counter)
  1596                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1597                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1598                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1599                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1600                                  ;	mov	byte [ebx], 5
  1601                                  ;	inc	byte [ebx+1] ; 19
  1602                                  ;;timer_eoi:
  1603                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1604                                  ;;	out	20h, al	; 8259 PORT
  1605                                  	;
  1606                                  ;u_timer_retn:  ; 06/02/2015
  1607 0000083C 5F                      	pop	edi
  1608 0000083D 5E                      	pop	esi
  1609                                  	;pop	es
  1610                                  	;pop	ds
  1611                                  	;pop	ebx
  1612                                  	;pop	ecx
  1613                                  	;pop	edx
  1614                                  	;pop	eax
  1615                                  	;iret
  1616 0000083E C3                      	retn	; 06/02/2015
  1617                                  
  1618                                  	; 28/08/2014
  1619                                  irq0:
  1620 0000083F 6A00                            push 	dword 0
  1621 00000841 EB48                    	jmp	short which_irq
  1622                                  irq1:
  1623 00000843 6A01                            push 	dword 1
  1624 00000845 EB44                    	jmp	short which_irq
  1625                                  irq2:
  1626 00000847 6A02                            push 	dword 2
  1627 00000849 EB40                    	jmp	short which_irq
  1628                                  irq3:
  1629                                  	; 20/11/2015
  1630                                  	; 24/10/2015
  1631 0000084B 2EFF15[4C3F0000]        	call	dword [cs:com2_irq3]
  1632 00000852 6A03                    	push 	dword 3
  1633 00000854 EB35                    	jmp	short which_irq
  1634                                  irq4:
  1635                                  	; 20/11/2015
  1636                                  	; 24/10/2015
  1637 00000856 2EFF15[483F0000]        	call	dword [cs:com1_irq4]
  1638 0000085D 6A04                            push 	dword 4
  1639 0000085F EB2A                    	jmp	short which_irq
  1640                                  irq5:
  1641 00000861 6A05                            push 	dword 5
  1642 00000863 EB26                    	jmp	short which_irq
  1643                                  irq6:
  1644 00000865 6A06                            push 	dword 6
  1645 00000867 EB22                    	jmp	short which_irq
  1646                                  irq7:
  1647 00000869 6A07                            push 	dword 7
  1648 0000086B EB1E                    	jmp	short which_irq
  1649                                  irq8:
  1650 0000086D 6A08                            push 	dword 8
  1651 0000086F EB1A                    	jmp	short which_irq
  1652                                  irq9:
  1653 00000871 6A09                            push 	dword 9
  1654 00000873 EB16                    	jmp	short which_irq
  1655                                  irq10:
  1656 00000875 6A0A                            push 	dword 10
  1657 00000877 EB12                    	jmp	short which_irq
  1658                                  irq11:
  1659 00000879 6A0B                            push 	dword 11
  1660 0000087B EB0E                    	jmp	short which_irq
  1661                                  irq12:
  1662 0000087D 6A0C                            push 	dword 12
  1663 0000087F EB0A                    	jmp	short which_irq
  1664                                  irq13:
  1665 00000881 6A0D                            push 	dword 13
  1666 00000883 EB06                    	jmp	short which_irq
  1667                                  irq14:
  1668 00000885 6A0E                            push 	dword 14
  1669 00000887 EB02                    	jmp	short which_irq
  1670                                  irq15:
  1671 00000889 6A0F                            push 	dword 15
  1672                                  	;jmp	short which_irq
  1673                                  
  1674                                  	; 19/10/2015
  1675                                  	; 29/08/2014
  1676                                  	; 21/08/2014
  1677                                  which_irq:
  1678 0000088B 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1679 0000088E 53                      	push	ebx
  1680 0000088F 56                      	push	esi
  1681 00000890 57                      	push	edi
  1682 00000891 1E                      	push 	ds
  1683 00000892 06                      	push 	es
  1684                                  	;
  1685 00000893 88C3                    	mov	bl, al
  1686                                  	;
  1687 00000895 B810000000              	mov	eax, KDATA
  1688 0000089A 8ED8                    	mov	ds, ax
  1689 0000089C 8EC0                    	mov	es, ax
  1690                                  	; 19/10/2015
  1691 0000089E FC                      	cld
  1692                                          ; 27/08/2014
  1693 0000089F 8105[886B0000]A000-             add     dword [scr_row], 0A0h
  1694 000008A7 0000               
  1695                                  	;
  1696 000008A9 B417                    	mov	ah, 17h	; blue (1) background, 
  1697                                  			; light gray (7) forecolor
  1698 000008AB 8B3D[886B0000]                  mov     edi, [scr_row]
  1699 000008B1 B049                    	mov	al, 'I'
  1700 000008B3 66AB                    	stosw
  1701 000008B5 B052                    	mov	al, 'R'
  1702 000008B7 66AB                    	stosw
  1703 000008B9 B051                    	mov	al, 'Q'
  1704 000008BB 66AB                    	stosw
  1705 000008BD B020                    	mov	al, ' '
  1706 000008BF 66AB                    	stosw
  1707 000008C1 88D8                    	mov	al, bl
  1708 000008C3 3C0A                    	cmp	al, 10
  1709 000008C5 7208                    	jb	short iix
  1710 000008C7 B031                    	mov	al, '1'
  1711 000008C9 66AB                    	stosw
  1712 000008CB 88D8                    	mov	al, bl
  1713 000008CD 2C0A                    	sub	al, 10
  1714                                  iix:
  1715 000008CF 0430                    	add	al, '0'
  1716 000008D1 66AB                    	stosw
  1717 000008D3 B020                    	mov	al, ' '
  1718 000008D5 66AB                    	stosw
  1719 000008D7 B021                    	mov	al, '!'
  1720 000008D9 66AB                    	stosw
  1721 000008DB B020                    	mov	al, ' '
  1722 000008DD 66AB                    	stosw
  1723                                  	; 23/02/2015
  1724 000008DF 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1725 000008E2 0F868D010000            	jna	iiret
  1726 000008E8 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1727 000008EA E6A0                    	out	0A0h, al ; the 2nd 8259
  1728 000008EC E984010000              	jmp     iiret
  1729                                  	;
  1730                                  	; 22/08/2014
  1731                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1732                                  	;out	20h, al	; 8259 PORT
  1733                                  	;
  1734                                  	;pop	es
  1735                                  	;pop	ds
  1736                                  	;pop	edi
  1737                                  	;pop	esi
  1738                                  	;pop	ebx
  1739                                  	;pop 	eax
  1740                                  	;iret
  1741                                  
  1742                                  	; 02/04/2015
  1743                                  	; 25/08/2014
  1744                                  exc0:
  1745 000008F1 6A00                            push 	dword 0
  1746 000008F3 E990000000                      jmp     cpu_except
  1747                                  exc1:
  1748 000008F8 6A01                            push 	dword 1
  1749 000008FA E989000000                      jmp     cpu_except
  1750                                  exc2:
  1751 000008FF 6A02                            push 	dword 2
  1752 00000901 E982000000                      jmp     cpu_except
  1753                                  exc3:
  1754 00000906 6A03                            push 	dword 3
  1755 00000908 EB7E                            jmp     cpu_except
  1756                                  exc4:
  1757 0000090A 6A04                            push 	dword 4
  1758 0000090C EB7A                            jmp     cpu_except
  1759                                  exc5:
  1760 0000090E 6A05                            push 	dword 5
  1761 00000910 EB76                            jmp     cpu_except
  1762                                  exc6:
  1763 00000912 6A06                            push 	dword 6
  1764 00000914 EB72                            jmp     cpu_except
  1765                                  exc7:
  1766 00000916 6A07                            push 	dword 7
  1767 00000918 EB6E                            jmp     cpu_except
  1768                                  exc8:
  1769                                  	; [esp] = Error code
  1770 0000091A 6A08                            push 	dword 8
  1771 0000091C EB5C                            jmp     cpu_except_en
  1772                                  exc9:
  1773 0000091E 6A09                            push 	dword 9
  1774 00000920 EB66                            jmp     cpu_except
  1775                                  exc10:
  1776                                  	; [esp] = Error code
  1777 00000922 6A0A                            push 	dword 10
  1778 00000924 EB54                            jmp     cpu_except_en
  1779                                  exc11:
  1780                                  	; [esp] = Error code
  1781 00000926 6A0B                            push 	dword 11
  1782 00000928 EB50                            jmp     cpu_except_en
  1783                                  exc12:
  1784                                  	; [esp] = Error code
  1785 0000092A 6A0C                            push 	dword 12
  1786 0000092C EB4C                            jmp     cpu_except_en
  1787                                  exc13:
  1788                                  	; [esp] = Error code
  1789 0000092E 6A0D                            push 	dword 13
  1790 00000930 EB48                            jmp     cpu_except_en
  1791                                  exc14:
  1792                                  	; [esp] = Error code
  1793 00000932 6A0E                            push 	dword 14
  1794 00000934 EB44                    	jmp	short cpu_except_en
  1795                                  exc15:
  1796 00000936 6A0F                            push 	dword 15
  1797 00000938 EB4E                            jmp     cpu_except
  1798                                  exc16:
  1799 0000093A 6A10                            push 	dword 16
  1800 0000093C EB4A                            jmp     cpu_except
  1801                                  exc17:
  1802                                  	; [esp] = Error code
  1803 0000093E 6A11                            push 	dword 17
  1804 00000940 EB38                    	jmp	short cpu_except_en
  1805                                  exc18:
  1806 00000942 6A12                            push 	dword 18
  1807 00000944 EB42                    	jmp	short cpu_except
  1808                                  exc19:
  1809 00000946 6A13                            push 	dword 19
  1810 00000948 EB3E                    	jmp	short cpu_except
  1811                                  exc20:
  1812 0000094A 6A14                            push 	dword 20
  1813 0000094C EB3A                    	jmp	short cpu_except
  1814                                  exc21:
  1815 0000094E 6A15                            push 	dword 21
  1816 00000950 EB36                    	jmp	short cpu_except
  1817                                  exc22:
  1818 00000952 6A16                            push 	dword 22
  1819 00000954 EB32                    	jmp	short cpu_except
  1820                                  exc23:
  1821 00000956 6A17                            push 	dword 23
  1822 00000958 EB2E                    	jmp	short cpu_except
  1823                                  exc24:
  1824 0000095A 6A18                            push 	dword 24
  1825 0000095C EB2A                    	jmp	short cpu_except
  1826                                  exc25:
  1827 0000095E 6A19                            push 	dword 25
  1828 00000960 EB26                    	jmp	short cpu_except
  1829                                  exc26:
  1830 00000962 6A1A                            push 	dword 26
  1831 00000964 EB22                    	jmp	short cpu_except
  1832                                  exc27:
  1833 00000966 6A1B                            push 	dword 27
  1834 00000968 EB1E                    	jmp	short cpu_except
  1835                                  exc28:
  1836 0000096A 6A1C                            push 	dword 28
  1837 0000096C EB1A                    	jmp	short cpu_except
  1838                                  exc29:
  1839 0000096E 6A1D                            push 	dword 29
  1840 00000970 EB16                    	jmp	short cpu_except
  1841                                  exc30:
  1842 00000972 6A1E                            push 	dword 30
  1843 00000974 EB04                    	jmp	short cpu_except_en
  1844                                  exc31:
  1845 00000976 6A1F                            push 	dword 31
  1846 00000978 EB0E                            jmp     short cpu_except
  1847                                  
  1848                                  	; 19/10/2015
  1849                                  	; 19/09/2015
  1850                                  	; 01/09/2015
  1851                                  	; 28/08/2015
  1852                                  	; 28/08/2014
  1853                                  cpu_except_en:
  1854 0000097A 87442404                	xchg	eax, [esp+4] ; Error code
  1855 0000097E 36A3[30850000]          	mov	[ss:error_code], eax
  1856 00000984 58                      	pop	eax  ; Exception number
  1857 00000985 870424                  	xchg	eax, [esp]
  1858                                  		; eax = eax before exception
  1859                                  		; [esp] -> exception number
  1860                                  		; [esp+4] -> EIP to return
  1861                                  	; 19/10/2015
  1862                                  	; 19/09/2015
  1863                                  	; 01/09/2015
  1864                                  	; 28/08/2015
  1865                                  	; 29/08/2014
  1866                                  	; 28/08/2014
  1867                                  	; 25/08/2014
  1868                                  	; 21/08/2014
  1869                                  cpu_except:	; CPU Exceptions
  1870 00000988 FC                      	cld
  1871 00000989 870424                  	xchg	eax, [esp] 
  1872                                  		; eax = Exception number
  1873                                  		; [esp] = eax (before exception)	
  1874 0000098C 53                      	push	ebx
  1875 0000098D 56                      	push	esi
  1876 0000098E 57                      	push	edi
  1877 0000098F 1E                      	push 	ds
  1878 00000990 06                      	push 	es
  1879                                  	; 28/08/2015
  1880 00000991 66BB1000                	mov	bx, KDATA
  1881 00000995 8EDB                    	mov	ds, bx
  1882 00000997 8EC3                    	mov	es, bx
  1883 00000999 0F20DB                  	mov	ebx, cr3
  1884 0000099C 53                      	push	ebx ; (*) page directory
  1885                                  	; 19/10/2015
  1886 0000099D FC                      	cld
  1887                                  	; 25/03/2015
  1888 0000099E 8B1D[78700000]          	mov	ebx, [k_page_dir]
  1889 000009A4 0F22DB                  	mov	cr3, ebx
  1890                                  	; 28/08/2015
  1891 000009A7 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1892 000009AA 7512                    	jne	short cpu_except_nfp
  1893 000009AC E816290000              	call	page_fault_handler
  1894 000009B1 21C0                    	and 	eax, eax
  1895 000009B3 0F84B8000000                    jz	iiretp ; 01/09/2015
  1896 000009B9 B80E000000              	mov	eax, 0Eh ; 14
  1897                                  cpu_except_nfp:
  1898                                  	; 02/04/2015
  1899 000009BE BB[E0060000]            	mov	ebx, hang
  1900 000009C3 875C241C                	xchg	ebx, [esp+28]
  1901                                  		; EIP (points to instruction which faults)
  1902                                  	  	; New EIP (hang)
  1903 000009C7 891D[34850000]          	mov	[FaultOffset], ebx
  1904 000009CD C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1905 000009D5 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1906                                  	;
  1907 000009DD 88C4                    	mov	ah, al
  1908 000009DF 240F                    	and	al, 0Fh
  1909 000009E1 3C09                    	cmp	al, 9
  1910 000009E3 7602                    	jna	short h1ok
  1911 000009E5 0407                    	add	al, 'A'-':'
  1912                                  h1ok:
  1913 000009E7 D0EC                    	shr	ah, 1
  1914 000009E9 D0EC                    	shr	ah, 1
  1915 000009EB D0EC                    	shr	ah, 1
  1916 000009ED D0EC                    	shr	ah, 1
  1917 000009EF 80FC09                  	cmp	ah, 9
  1918 000009F2 7603                    	jna	short h2ok
  1919 000009F4 80C407                  	add	ah, 'A'-':'
  1920                                  h2ok:	
  1921 000009F7 86E0                    	xchg 	ah, al	
  1922 000009F9 66053030                	add	ax, '00'
  1923 000009FD 66A3[146C0000]          	mov	[excnstr], ax
  1924                                  	;
  1925                                  	; 29/08/2014
  1926 00000A03 A1[34850000]            	mov	eax, [FaultOffset]
  1927 00000A08 51                      	push	ecx
  1928 00000A09 52                      	push	edx
  1929 00000A0A 89E3                    	mov	ebx, esp
  1930                                  	; 28/08/2015
  1931 00000A0C B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1932                                  			  ; to hexadecimal string
  1933                                  	;mov	ecx, 10	    ; divisor to convert	
  1934                                  			    ; binary number to decimal string
  1935                                  b2d1:
  1936 00000A11 31D2                    	xor	edx, edx
  1937 00000A13 F7F1                    	div	ecx
  1938 00000A15 6652                    	push	dx
  1939 00000A17 39C8                    	cmp	eax, ecx
  1940 00000A19 73F6                    	jnb	short b2d1
  1941 00000A1B BF[1F6C0000]            	mov	edi, EIPstr ; EIP value
  1942                                  			    ; points to instruction which faults	
  1943                                  	; 28/08/2015
  1944 00000A20 89C2                    	mov	edx, eax
  1945                                  b2d2:
  1946                                  	;add	al, '0'
  1947 00000A22 8A82[EF180000]          	mov	al, [edx+hexchrs]
  1948 00000A28 AA                      	stosb		    ; write hexadecimal digit to its place	
  1949 00000A29 39E3                    	cmp	ebx, esp
  1950 00000A2B 7606                    	jna	short b2d3
  1951 00000A2D 6658                    	pop	ax
  1952 00000A2F 88C2                    	mov	dl, al
  1953 00000A31 EBEF                    	jmp	short b2d2
  1954                                  b2d3:
  1955 00000A33 B068                    	mov 	al, 'h' ; 28/08/2015
  1956 00000A35 AA                      	stosb
  1957 00000A36 B020                    	mov	al, 20h	    ; space
  1958 00000A38 AA                      	stosb
  1959 00000A39 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  1960 00000A3B AA                      	stosb
  1961                                  	;
  1962 00000A3C 5A                      	pop	edx
  1963 00000A3D 59                      	pop	ecx
  1964                                  	;
  1965 00000A3E B44F                    	mov	ah, 4Fh	; red (4) background, 
  1966                                  			; white (F) forecolor
  1967 00000A40 BE[046C0000]            	mov	esi, exc_msg ; message offset
  1968                                  	;
  1969 00000A45 EB11                    	jmp	short piemsg
  1970                                  	;
  1971                                          ;add    dword [scr_row], 0A0h
  1972                                          ;mov    edi, [scr_row]
  1973                                          ;
  1974                                  	;call 	printk
  1975                                  	;
  1976                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1977                                  	;out	20h, al	; 8259 PORT
  1978                                  	;
  1979                                  	;pop	es
  1980                                  	;pop	ds
  1981                                  	;pop	edi
  1982                                  	;pop	esi
  1983                                  	;pop 	eax
  1984                                  	;iret
  1985                                  	
  1986                                  	; 28/08/2015
  1987                                  	; 23/02/2015
  1988                                  	; 20/08/2014
  1989                                  ignore_int:
  1990 00000A47 50                      	push	eax
  1991 00000A48 53                      	push	ebx ; 23/02/2015
  1992 00000A49 56                      	push	esi
  1993 00000A4A 57                      	push	edi
  1994 00000A4B 1E                      	push 	ds
  1995 00000A4C 06                      	push 	es
  1996                                  	; 28/08/2015
  1997 00000A4D 0F20D8                  	mov	eax, cr3
  1998 00000A50 50                      	push	eax ; (*) page directory
  1999                                  	;
  2000 00000A51 B467                    	mov	ah, 67h	; brown (6) background, 
  2001                                  			; light gray (7) forecolor
  2002 00000A53 BE[C26B0000]            	mov	esi, int_msg ; message offset
  2003                                  piemsg:
  2004                                          ; 27/08/2014
  2005 00000A58 8105[886B0000]A000-             add     dword [scr_row], 0A0h
  2006 00000A60 0000               
  2007 00000A62 8B3D[886B0000]                  mov     edi, [scr_row]
  2008                                          ;
  2009 00000A68 E8B0FCFFFF              	call 	printk
  2010                                  	;
  2011                                  	; 23/02/2015
  2012 00000A6D B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2013 00000A6F E6A0                    	out	0A0h, al ; the 2nd 8259
  2014                                  iiretp: ; 01/09/2015
  2015                                  	; 28/08/2015
  2016 00000A71 58                      	pop	eax ; (*) page directory
  2017 00000A72 0F22D8                  	mov	cr3, eax
  2018                                  	;
  2019                                  iiret:
  2020                                  	; 22/08/2014
  2021 00000A75 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2022 00000A77 E620                    	out	20h, al	; 8259 PORT
  2023                                  	;
  2024 00000A79 07                      	pop	es
  2025 00000A7A 1F                      	pop	ds
  2026 00000A7B 5F                      	pop	edi
  2027 00000A7C 5E                      	pop	esi
  2028 00000A7D 5B                      	pop	ebx ; 29/08/2014
  2029 00000A7E 58                      	pop 	eax
  2030 00000A7F CF                      	iretd
  2031                                  
  2032                                  	; 26/02/2015
  2033                                  	; 07/09/2014
  2034                                  	; 25/08/2014
  2035                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  2036                                  	; 22/08/2014
  2037 00000A80 50                      	push	eax
  2038 00000A81 53                      	push	ebx ; 29/08/2014
  2039 00000A82 56                      	push	esi
  2040 00000A83 57                      	push	edi
  2041 00000A84 1E                      	push 	ds
  2042 00000A85 06                      	push 	es
  2043                                  	;
  2044 00000A86 B810000000              	mov	eax, KDATA
  2045 00000A8B 8ED8                    	mov	ds, ax
  2046 00000A8D 8EC0                    	mov	es, ax
  2047                                  	;
  2048                                  	; 25/08/2014
  2049 00000A8F E884000000              	call	rtc_p
  2050                                  	;
  2051                                  	; 22/02/2015 - dsectpm.s
  2052                                  	; [ source: http://wiki.osdev.org/RTC ]
  2053                                  	; read status register C to complete procedure
  2054                                  	;(it is needed to get a next IRQ 8) 
  2055 00000A94 B00C                    	mov	al, 0Ch ; 
  2056 00000A96 E670                    	out	70h, al ; select register C
  2057 00000A98 90                      	nop
  2058 00000A99 E471                    	in	al, 71h ; just throw away contents
  2059                                  	; 22/02/2015
  2060 00000A9B B020                    	MOV	AL,EOI		; END OF INTERRUPT
  2061 00000A9D E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  2062                                  	;
  2063 00000A9F EBD4                    	jmp	short iiret	
  2064                                  
  2065                                  	; 22/08/2014
  2066                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  2067                                  	; (INT 1Ah)
  2068                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  2069                                  time_of_day:
  2070 00000AA1 E866010000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  2071 00000AA6 726F                            jc      short rtc_retn 
  2072 00000AA8 B000                    	mov	al, CMOS_SECONDS
  2073 00000AAA E845010000              	call	CMOS_READ
  2074 00000AAF A2[EC700000]            	mov	[time_seconds], al 
  2075 00000AB4 B002                    	mov	al, CMOS_MINUTES
  2076 00000AB6 E839010000              	call	CMOS_READ
  2077 00000ABB A2[ED700000]            	mov	[time_minutes], al 
  2078 00000AC0 B004                    	mov	al, CMOS_HOURS
  2079 00000AC2 E82D010000              	call	CMOS_READ
  2080 00000AC7 A2[EE700000]                    mov     [time_hours], al
  2081 00000ACC B006                    	mov	al, CMOS_DAY_WEEK 
  2082 00000ACE E821010000              	call	CMOS_READ
  2083 00000AD3 A2[EF700000]            	mov	[date_wday], al
  2084 00000AD8 B007                     	mov	al, CMOS_DAY_MONTH
  2085 00000ADA E815010000              	call	CMOS_READ
  2086 00000ADF A2[F0700000]            	mov	[date_day], al
  2087 00000AE4 B008                    	mov	al, CMOS_MONTH
  2088 00000AE6 E809010000              	call	CMOS_READ
  2089 00000AEB A2[F1700000]            	mov	[date_month], al
  2090 00000AF0 B009                    	mov	al, CMOS_YEAR
  2091 00000AF2 E8FD000000              	call	CMOS_READ
  2092 00000AF7 A2[F2700000]            	mov	[date_year], al
  2093 00000AFC B032                    	mov	al, CMOS_CENTURY
  2094 00000AFE E8F1000000              	call	CMOS_READ
  2095 00000B03 A2[F3700000]            	mov	[date_century], al
  2096                                  	;
  2097 00000B08 B000                    	mov	al, CMOS_SECONDS
  2098 00000B0A E8E5000000              	call 	CMOS_READ
  2099 00000B0F 3A05[EC700000]          	cmp	al, [time_seconds]
  2100 00000B15 758A                    	jne	short time_of_day
  2101                                  
  2102                                  rtc_retn:
  2103 00000B17 C3                      	retn
  2104                                  
  2105                                  rtc_p:	
  2106                                  	; 07/09/2014
  2107                                  	; 29/08/2014
  2108                                  	; 27/08/2014
  2109                                  	; 25/08/2014
  2110                                   	; Print Real Time Clock content
  2111                                  	;
  2112                                  	;
  2113 00000B18 E884FFFFFF              	call	time_of_day
  2114 00000B1D 72F8                    	jc	short rtc_retn
  2115                                  	;
  2116 00000B1F 3A05[766C0000]          	cmp	al, [ptime_seconds]
  2117 00000B25 74F0                            je      short rtc_retn ; 29/08/2014
  2118                                  	;
  2119 00000B27 A2[766C0000]            	mov	[ptime_seconds], al
  2120                                  	;
  2121 00000B2C A0[F3700000]            	mov	al, [date_century]
  2122 00000B31 E8F1000000              	call	bcd_to_ascii
  2123 00000B36 66A3[436C0000]          	mov	[datestr+6], ax
  2124 00000B3C A0[F2700000]            	mov	al, [date_year]
  2125 00000B41 E8E1000000              	call	bcd_to_ascii
  2126 00000B46 66A3[456C0000]          	mov	[datestr+8], ax
  2127 00000B4C A0[F1700000]            	mov	al, [date_month]
  2128 00000B51 E8D1000000              	call	bcd_to_ascii
  2129 00000B56 66A3[406C0000]          	mov	[datestr+3], ax
  2130 00000B5C A0[F0700000]            	mov	al, [date_day]
  2131 00000B61 E8C1000000              	call	bcd_to_ascii
  2132 00000B66 66A3[3D6C0000]          	mov	[datestr], ax
  2133                                  	;
  2134 00000B6C 0FB61D[EF700000]        	movzx	ebx, byte [date_wday]
  2135 00000B73 C0E302                  	shl 	bl, 2
  2136 00000B76 81C3[566C0000]          	add	ebx, daytmp
  2137 00000B7C 8B03                    	mov	eax, [ebx]
  2138 00000B7E A3[486C0000]            	mov	[daystr], eax
  2139                                  	;
  2140 00000B83 A0[EE700000]            	mov	al, [time_hours]
  2141 00000B88 E89A000000              	call	bcd_to_ascii
  2142 00000B8D 66A3[4C6C0000]          	mov	[timestr], ax
  2143 00000B93 A0[ED700000]            	mov	al, [time_minutes]
  2144 00000B98 E88A000000              	call	bcd_to_ascii
  2145 00000B9D 66A3[4F6C0000]          	mov	[timestr+3], ax
  2146 00000BA3 A0[EC700000]            	mov	al, [time_seconds]
  2147 00000BA8 E87A000000              	call	bcd_to_ascii
  2148 00000BAD 66A3[526C0000]          	mov	[timestr+6], ax
  2149                                  	;		
  2150 00000BB3 BE[2B6C0000]            	mov	esi, rtc_msg ; message offset
  2151                                  	; 23/02/2015
  2152 00000BB8 52                      	push	edx
  2153 00000BB9 51                      	push	ecx
  2154                                  	; 07/09/2014
  2155 00000BBA 66BB0200                	mov	bx, 2		; Video page 2
  2156                                  prtmsg:
  2157 00000BBE AC                      	lodsb
  2158 00000BBF 08C0                    	or	al, al
  2159 00000BC1 740F                    	jz	short prtmsg_ok
  2160 00000BC3 56                      	push	esi
  2161 00000BC4 6653                    	push	bx
  2162 00000BC6 B43F                            mov	ah, 3Fh	; cyan (6) background, 
  2163                                  			; white (F) forecolor
  2164 00000BC8 E80D090000              	call 	write_tty
  2165 00000BCD 665B                    	pop	bx
  2166 00000BCF 5E                      	pop	esi
  2167 00000BD0 EBEC                    	jmp	short prtmsg
  2168                                  	;
  2169                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  2170                                  	;call	printk
  2171                                  prtmsg_ok:
  2172                                  	; 07/09/2014
  2173 00000BD2 6631D2                  	xor	dx, dx		; column 0, row 0
  2174 00000BD5 E8240A0000              	call	set_cpos	; set curspor position to 0,0 
  2175                                  	; 23/02/2015
  2176 00000BDA 59                      	pop	ecx
  2177 00000BDB 5A                      	pop	edx
  2178 00000BDC C3                      	retn
  2179                                  
  2180                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2181                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2182                                  default_irq7:
  2183 00000BDD 6650                    	push	ax
  2184 00000BDF B00B                    	mov	al, 0Bh  ; In-Service register
  2185 00000BE1 E620                    	out	20h, al
  2186 00000BE3 EB00                            jmp short $+2
  2187 00000BE5 EB00                    	jmp short $+2
  2188 00000BE7 E420                    	in	al, 20h
  2189 00000BE9 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  2190 00000BEB 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  2191 00000BED B020                            mov     al, 20h ; EOI
  2192 00000BEF E620                    	out	20h, al 
  2193                                  irq7_iret:
  2194 00000BF1 6658                    	pop	ax
  2195 00000BF3 CF                      	iretd
  2196                                  	
  2197                                  	; 22/08/2014
  2198                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
  2199                                  CMOS_READ:
  2200 00000BF4 9C                      	pushf		; SAVE INTERRUPT ENABLE STATUS AND FLAGS
  2201 00000BF5 D0C0                    	rol	al, 1	; MOVE NMI BIT TO LOW POSITION
  2202 00000BF7 F9                      	stc		; FORCE NMI BIT ON IN CARRY FLAG
  2203 00000BF8 D0D8                    	rcr	al, 1	; HIGH BIT ON TO DISABLE NMI - OLD IN CY
  2204 00000BFA FA                      	cli		; DISABLE INTERRUPTS
  2205 00000BFB E670                    	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
  2206 00000BFD 90                      	nop		; I/O DELAY
  2207 00000BFE E471                    	in	al, CMOS_DATA	; READ THE REQUESTED CMOS LOCATION
  2208 00000C00 6650                    	push	ax	; SAVE (AH) REGISTER VALUE AND CMOS BYTE
  2209                                  	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
  2210                                  		     ; ----- 10/06/85 (test4.asm)
  2211 00000C02 B01E                    	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
  2212                                  	;mov	al, CMOS_REG_D*2 ; GET ADDRESS OF DEFAULT LOCATION
  2213 00000C04 D0D8                    	rcr	al, 1	; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
  2214 00000C06 E670                    	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
  2215 00000C08 6658                    	pop	ax	; RESTORE (AH) AND (AL), CMOS BYTE
  2216 00000C0A 9D                      	popf	
  2217 00000C0B C3                      	retn		; RETURN WITH FLAGS RESTORED
  2218                                  
  2219                                  	; 22/08/2014
  2220                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
  2221                                  UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
  2222 00000C0C 51                      	push	ecx
  2223 00000C0D B9FFFF0000              	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
  2224                                  		; mov cx, 800	
  2225                                  UPD_10:
  2226 00000C12 B00A                    	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
  2227 00000C14 FA                      	cli				; NO TIMER INTERRUPTS DURING UPDATES
  2228 00000C15 E8DAFFFFFF              	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
  2229 00000C1A A880                    	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
  2230 00000C1C 7406                    	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
  2231 00000C1E FB                      	sti				; ALLOW INTERRUPTS WHILE WAITING
  2232 00000C1F E2F1                    	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
  2233 00000C21 31C0                    	xor	eax, eax		; CLEAR RESULTS IF ERROR
  2234                                  		; xor ax, ax
  2235 00000C23 F9                      	stc				; SET CARRY FOR ERROR
  2236                                  UPD_90:
  2237 00000C24 59                      	pop	ecx			; RESTORE CALLERS REGISTER
  2238 00000C25 FA                      	cli				; INTERRUPTS OFF DURING SET
  2239 00000C26 C3                      	retn				; RETURN WITH CY FLAG SET
  2240                                  
  2241                                  bcd_to_ascii:
  2242                                  	; 25/08/2014
  2243                                  	; INPUT ->
  2244                                  	;	al = Packed BCD number
  2245                                  	; OUTPUT ->
  2246                                  	;	ax  = ASCII word/number
  2247                                  	;
  2248                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  2249                                  	;
  2250 00000C27 D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  2251                                  					; AH = AL / 10h
  2252                                  					; AL = AL MOD 10h
  2253 00000C29 660D3030                	or ax,'00'                      ; Make it ASCII based
  2254                                  
  2255 00000C2D 86E0                            xchg ah, al 
  2256                                  	
  2257 00000C2F C3                      	retn	
  2258                                  	
  2259                                  
  2260                                  %include 'keyboard.inc' ; 07/03/2015
  2261                              <1> ; Retro UNIX 386 v1 Kernel - KEYBOARD.INC
  2262                              <1> ; Last Modification: 17/10/2015
  2263                              <1> ;		    (Keyboard Data is in 'KYBDATA.INC')	
  2264                              <1> ;
  2265                              <1> ; ///////// KEYBOARD FUNCTIONS (PROCEDURES) ///////////////
  2266                              <1> 
  2267                              <1> ; 30/06/2015
  2268                              <1> ; 11/03/2015
  2269                              <1> ; 28/02/2015
  2270                              <1> ; 25/02/2015
  2271                              <1> ; 20/02/2015
  2272                              <1> ; 18/02/2015
  2273                              <1> ; 03/12/2014
  2274                              <1> ; 07/09/2014
  2275                              <1> ; KEYBOARD INTERRUPT HANDLER
  2276                              <1> ; (kb_int - Retro UNIX 8086 v1 - U0.ASM, 30/06/2014)
  2277                              <1> 
  2278                              <1> ;getch:
  2279                              <1> ;	; 18/02/2015
  2280                              <1> ;	; This routine will be replaced with Retro UNIX 386
  2281                              <1> ;	; version of Retro UNIX 8086 getch (tty input)
  2282                              <1> ;	; routine, later... (multi tasking ability)
  2283                              <1> ;	; 28/02/2015
  2284                              <1> ;	sti	; enable interrupts
  2285                              <1> ;	;
  2286                              <1> ;	;push	esi
  2287                              <1> ;	;push	ebx
  2288                              <1> ;	;xor	ebx, ebx
  2289                              <1> ;	;mov	bl, [ptty]  ; active_page
  2290                              <1> ;	;mov	esi, ebx
  2291                              <1> ;	;shl 	si, 1
  2292                              <1> ;	;add	esi, ttychr
  2293                              <1> ;getch_1:
  2294                              <1> ;	;mov	ax, [esi]
  2295                              <1> ;	mov	ax, [ttychr] ; video page 0 (tty0)
  2296                              <1> ;	and	ax, ax
  2297                              <1> ;	jz	short getch_2
  2298                              <1> ;	mov	word [ttychr], 0
  2299                              <1> ;	;mov	word [esi], 0
  2300                              <1> ;	;pop	ebx
  2301                              <1> ;	;pop	esi
  2302                              <1> ;	retn
  2303                              <1> ;getch_2:
  2304                              <1> ;	hlt	; not proper for multi tasking!
  2305                              <1> ;		; (temporary halt for now)
  2306                              <1> ;		; 'sleep' on tty 
  2307                              <1> ;		; will (must) be located here		
  2308                              <1> ;	nop
  2309                              <1> ;	jmp	short getch_1
  2310                              <1> 
  2311                              <1> keyb_int:
  2312                              <1> 	; 30/06/2015
  2313                              <1> 	; 25/02/2015
  2314                              <1> 	; 20/02/2015
  2315                              <1> 	; 03/12/2014 (getc_int - INT 16h modifications)
  2316                              <1> 	; 07/09/2014 - Retro UNIX 386 v1
  2317                              <1> 	; 30/06/2014
  2318                              <1> 	; 10/05/2013	
  2319                              <1>       	; Retro Unix 8086 v1 feature only!
  2320                              <1> 	; 03/03/2014
  2321                              <1> 	
  2322 00000C30 1E                  <1> 	push	ds
  2323 00000C31 53                  <1> 	push	ebx
  2324 00000C32 50                  <1> 	push	eax
  2325                              <1> 	;
  2326 00000C33 66B81000            <1> 	mov	ax, KDATA
  2327 00000C37 8ED8                <1> 	mov	ds, ax
  2328                              <1> 	;
  2329 00000C39 9C                  <1> 	pushfd
  2330 00000C3A 0E                  <1> 	push	cs
  2331 00000C3B E823020000          <1> 	call	kb_int  ; int_09h
  2332                              <1> 	;
  2333 00000C40 B411                <1> 	mov	ah, 11h	 ; 03/12/2014	
  2334                              <1> 	;call	getc
  2335 00000C42 E856000000          <1> 	call	int_16h ; 30/06/2015
  2336 00000C47 7450                <1> 	jz	short keyb_int4
  2337                              <1> 	;
  2338 00000C49 B410                <1> 	mov	ah, 10h	 ; 03/12/2014
  2339                              <1> 	;call	getc
  2340 00000C4B E84D000000          <1> 	call	int_16h ; 30/06/2015
  2341                              <1> 	;
  2342                              <1> 	; 20/02/2015
  2343 00000C50 0FB61D[A6700000]    <1>         movzx   ebx, byte [ptty]  ; active_page
  2344                              <1> 	;
  2345 00000C57 20C0                <1> 	and 	al, al
  2346 00000C59 751E                <1> 	jnz	short keyb_int1
  2347                              <1> 	;
  2348 00000C5B 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  2349 00000C5E 7219                <1> 	jb	short keyb_int1
  2350 00000C60 80FC6F              <1> 	cmp	ah, 6Fh  ; ALT + F8 key	
  2351 00000C63 7714                <1> 	ja	short keyb_int1
  2352                              <1> 	;
  2353 00000C65 88D8                <1> 	mov	al, bl
  2354 00000C67 0468                <1> 	add	al, 68h
  2355 00000C69 38E0                <1> 	cmp	al, ah
  2356 00000C6B 7409                <1> 	je	short keyb_int0
  2357 00000C6D 88E0                <1> 	mov	al, ah
  2358 00000C6F 2C68                <1> 	sub	al, 68h
  2359 00000C71 E8520B0000          <1> 	call	tty_sw
  2360                              <1> 	;movzx	ebx, [ptty]  ; active_page
  2361                              <1> keyb_int0: ; 30/06/2015
  2362 00000C76 6631C0              <1> 	xor	ax, ax
  2363                              <1> keyb_int1:
  2364 00000C79 D0E3                <1> 	shl	bl, 1
  2365 00000C7B 81C3[A8700000]      <1> 	add	ebx, ttychr
  2366                              <1> 	;
  2367 00000C81 6609C0              <1> 	or	ax, ax
  2368 00000C84 7406                <1> 	jz	short keyb_int2
  2369                              <1> 	;
  2370 00000C86 66833B00            <1> 	cmp 	word [ebx], 0
  2371 00000C8A 7703                <1>         ja      short keyb_int3 
  2372                              <1> keyb_int2:
  2373 00000C8C 668903              <1>         mov	[ebx], ax  ; Save ascii code
  2374                              <1> 				; and scan code of the character
  2375                              <1> 				; for current tty (or last tty
  2376                              <1> 				; just before tty switch).
  2377                              <1> keyb_int3:
  2378 00000C8F A0[A6700000]        <1>         mov     al, [ptty]
  2379 00000C94 E826480000          <1> 	call	wakeup
  2380                              <1> 	;
  2381                              <1> keyb_int4:
  2382 00000C99 58                  <1> 	pop	eax
  2383 00000C9A 5B                  <1> 	pop	ebx
  2384 00000C9B 1F                  <1> 	pop	ds
  2385 00000C9C CF                  <1> 	iret
  2386                              <1> 
  2387                              <1> ; 18/02/2015
  2388                              <1> ; REMINDER: Only 'keyb_int' (IRQ 9) must call getc.
  2389                              <1> ; 'keyb_int' always handles 'getc' at 1st and puts the
  2390                              <1> ; scancode and ascii code of the character 
  2391                              <1> ; in the tty input (ttychr) buffer. 
  2392                              <1> ; Test procedures must call 'getch' for tty input
  2393                              <1> ; otherwise, 'getc' will not be able to return to the caller
  2394                              <1> ; due to infinite (key press) waiting loop.
  2395                              <1> ; 
  2396                              <1> ; 03/12/2014
  2397                              <1> ; 26/08/2014
  2398                              <1> ; KEYBOARD I/O
  2399                              <1> ; (INT_16h - Retro UNIX 8086 v1 - U9.ASM, 30/06/2014)
  2400                              <1> 
  2401                              <1> ;NOTE: 'k0' to 'k7' are name of OPMASK registers.
  2402                              <1> ;	(The reason of using '_k' labels!!!) (27/08/2014)    
  2403                              <1> ;NOTE: 'NOT' keyword is '~' unary operator in NASM.
  2404                              <1> ;	('NOT LC_HC' --> '~LC_HC') (bit reversing operator)
  2405                              <1> 
  2406                              <1> int_16h: ; 30/06/2015
  2407                              <1> ;getc:
  2408 00000C9D 9C                  <1> 	pushfd	; 28/08/2014
  2409 00000C9E 0E                  <1> 	push 	cs
  2410 00000C9F E801000000          <1> 	call 	getc_int
  2411 00000CA4 C3                  <1> 	retn	
  2412                              <1> 
  2413                              <1> getc_int:
  2414                              <1> 	; 28/02/2015
  2415                              <1> 	; 03/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2416                              <1> 	;	      instead of pc-at bios - 1985-)
  2417                              <1> 	; 28/08/2014 (_k1d)
  2418                              <1> 	; 30/06/2014
  2419                              <1> 	; 03/03/2014
  2420                              <1> 	; 28/02/2014
  2421                              <1> 	; Derived from "KEYBOARD_IO_1" procedure of IBM "pc-xt-286" 
  2422                              <1> 	; rombios source code (21/04/1986)
  2423                              <1> 	;	 'keybd.asm', INT 16H, KEYBOARD_IO
  2424                              <1> 	;
  2425                              <1> 	; KYBD --- 03/06/86  KEYBOARD BIOS
  2426                              <1> 	;
  2427                              <1> 	;--- INT 16 H -----------------------------------------------------------------
  2428                              <1> 	; KEYBOARD I/O								      :
  2429                              <1> 	;	THESE ROUTINES PROVIDE READ KEYBOARD SUPPORT			      :
  2430                              <1> 	; INPUT									      :
  2431                              <1> 	;	(AH)= 00H  READ THE NEXT ASCII CHARACTER ENTERED FROM THE KEYBOARD,   :
  2432                              <1> 	;		   RETURN THE RESULT IN (AL), SCAN CODE IN (AH).              :
  2433                              <1> 	;		   THIS IS THE COMPATIBLE READ INTERFACE, EQUIVALENT TO THE   :
  2434                              <1> 	;                  STANDARD PC OR PCAT KEYBOARD				      :	
  2435                              <1> 	;-----------------------------------------------------------------------------:
  2436                              <1> 	;	(AH)= 01H  SET THE ZERO FLAG TO INDICATE IF AN ASCII CHARACTER IS     :
  2437                              <1> 	;		   AVAILABLE TO BE READ FROM THE KEYBOARD BUFFER.	      :
  2438                              <1> 	;		   (ZF)= 1 -- NO CODE AVAILABLE			              :
  2439                              <1> 	;		   (ZF)= 0 -- CODE IS AVAILABLE  (AX)= CHARACTER              :
  2440                              <1> 	;		   IF (ZF)= 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS :
  2441                              <1> 	;		   IN (AX), AND THE ENTRY REMAINS IN THE BUFFER.              :
  2442                              <1> 	;		   THIS WILL RETURN ONLY PC/PCAT KEYBOARD COMPATIBLE CODES    :
  2443                              <1> 	;-----------------------------------------------------------------------------:	
  2444                              <1> 	;	(AH)= 02H  RETURN THE CURRENT SHIFT STATUS IN AL REGISTER             :
  2445                              <1> 	;		   THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE        :
  2446                              <1> 	;		   EQUATES FOR @KB_FLAG		                              :
  2447                              <1> 	;-----------------------------------------------------------------------------:	
  2448                              <1> 	;	(AH)= 03H  SET TYPAMATIC RATE AND DELAY                               :
  2449                              <1> 	;	      (AL) = 05H                                                      :
  2450                              <1> 	;	      (BL) = TYPAMATIC RATE (BITS 5 - 7 MUST BE RESET TO 0)           :
  2451                              <1> 	;		       							      :
  2452                              <1> 	;                     REGISTER     RATE      REGISTER     RATE                :
  2453                              <1> 	;                      VALUE     SELECTED     VALUE     SELECTED              :
  2454                              <1> 	;                     --------------------------------------------            :
  2455                              <1> 	;			00H        30.0        10H        7.5                 :
  2456                              <1> 	;			01H        26.7        11H        6.7                 :
  2457                              <1> 	;			02H        24.0        12H        6.0                 :
  2458                              <1> 	;			03H        21.8        13H        5.5                 :
  2459                              <1> 	;			04H        20.0        14H        5.0                 :
  2460                              <1> 	;			05H        18.5        15H        4.6                 :
  2461                              <1> 	;			06H        17.1        16H        4.3                 :
  2462                              <1> 	;			07H        16.0        17H        4.0                 :
  2463                              <1> 	;			08H        15.0        18H        3.7                 :
  2464                              <1> 	;			09H        13.3        19H        3.3                 :
  2465                              <1> 	;			0AH        12.0        1AH        3.0                 :
  2466                              <1> 	;			0BH        10.9        1BH        2.7                 :
  2467                              <1>         ;			0CH        10.0        1CH        2.5                 :
  2468                              <1> 	;			0DH         9.2        1DH        2.3                 :
  2469                              <1> 	;			0EH         8.6        1EH        2.1                 :
  2470                              <1> 	;			0FH         8.0        1FH        2.0                 :
  2471                              <1> 	;									      :
  2472                              <1> 	;	      (BH) = TYPAMATIC DELAY  (BITS 2 - 7 MUST BE RESET TO 0)         :
  2473                              <1> 	;		       							      :
  2474                              <1> 	;                     REGISTER     DELAY                                      :
  2475                              <1> 	;                      VALUE       VALUE                                      :
  2476                              <1> 	;                     ------------------                                      :
  2477                              <1> 	;			00H        250 ms                                     :
  2478                              <1> 	;			01H        500 ms                                     :
  2479                              <1> 	;			02H        750 ms                                     :
  2480                              <1> 	;			03H       1000 ms                                     :
  2481                              <1> 	;-----------------------------------------------------------------------------:
  2482                              <1> 	;	(AH)= 05H  PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD    :
  2483                              <1> 	;		   BUFFER AS IF STRUCK FROM KEYBOARD                          :
  2484                              <1> 	;		   ENTRY:  (CL) = ASCII CHARACTER		              :
  2485                              <1> 	;		           (CH) = SCAN CODE                                   :
  2486                              <1> 	;		   EXIT:   (AH) = 00H = SUCCESSFUL OPERATION                  :
  2487                              <1> 	;		           (AL) = 01H = UNSUCCESSFUL - BUFFER FULL            :
  2488                              <1> 	;		   FLAGS:  CARRY IF ERROR                                     :
  2489                              <1> 	;-----------------------------------------------------------------------------:		
  2490                              <1> 	;	(AH)= 10H  EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD,         :
  2491                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=0                            :
  2492                              <1> 	;-----------------------------------------------------------------------------:
  2493                              <1> 	;	(AH)= 11H  EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,           :
  2494                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=1                            :
  2495                              <1> 	;-----------------------------------------------------------------------------:	
  2496                              <1> 	;	(AH)= 12H  RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER            :
  2497                              <1> 	;		   AL = BITS FROM KB_FLAG, AH = BITS FOR LEFT AND RIGHT       :
  2498                              <1> 	;		   CTL AND ALT KEYS FROM KB_FLAG_1 AND KB_FLAG_3              :
  2499                              <1> 	; OUTPUT					                              :
  2500                              <1> 	;	AS NOTED ABOVE, ONLY (AX) AND FLAGS CHANGED	                      :
  2501                              <1> 	;	ALL REGISTERS RETAINED		                                      :
  2502                              <1> 	;------------------------------------------------------------------------------
  2503                              <1> 	
  2504 00000CA5 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2505 00000CA6 1E                  <1> 	push	ds			; SAVE CURRENT DS
  2506 00000CA7 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
  2507                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
  2508 00000CA8 66BB1000            <1>         mov     bx, KDATA 
  2509 00000CAC 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
  2510 00000CAE 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
  2511 00000CB0 7439                <1> 	jz	short _K1		; ASCII_READ
  2512 00000CB2 FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
  2513 00000CB4 7452                <1>         jz      short _K2               ; ASCII_STATUS
  2514 00000CB6 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
  2515 00000CB8 0F8485000000        <1>         jz      _K3                     ; SHIFT STATUS
  2516 00000CBE FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
  2517 00000CC0 0F8484000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
  2518 00000CC6 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
  2519 00000CC9 0F84A1000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
  2520                              <1> _KIO1:	
  2521 00000CCF 80EC0B              <1> 	sub	ah, 11			; AH =  10H
  2522 00000CD2 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
  2523 00000CD4 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
  2524 00000CD6 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
  2525 00000CD8 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
  2526 00000CDA 7449                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
  2527                              <1> _KIO_EXIT:
  2528                              <1> 	;pop	ecx			; RECOVER REGISTER
  2529 00000CDC 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2530 00000CDD 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2531 00000CDE CF                  <1> 	iretd				; INVALID COMMAND, EXIT
  2532                              <1> 
  2533                              <1> 	;-----	ASCII CHARACTER
  2534                              <1> _K1E:	
  2535 00000CDF E8B9000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
  2536 00000CE4 E82E010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2537 00000CE9 EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
  2538                              <1> _K1:	
  2539 00000CEB E8AD000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
  2540 00000CF0 E82D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2541 00000CF5 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
  2542                              <1> _K1A:
  2543 00000CF7 EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
  2544                              <1> 
  2545                              <1> 	;-----	ASCII STATUS
  2546                              <1> _K2E:	
  2547 00000CF9 E8EA000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
  2548 00000CFE 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2549 00000D00 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2550 00000D01 E811010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2551 00000D06 EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
  2552                              <1> _K2:	
  2553 00000D08 E8DB000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
  2554 00000D0D 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2555 00000D0F 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2556 00000D10 E80D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2557 00000D15 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
  2558 00000D17 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
  2559 00000D18 E880000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
  2560 00000D1D EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
  2561                              <1> _K2A:
  2562 00000D1F 9D                  <1> 	popf				; RESTORE ZF FROM TEST
  2563                              <1> _K2B:
  2564                              <1> 	;pop	ecx			; RECOVER REGISTER
  2565 00000D20 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2566 00000D21 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2567 00000D22 CA0400              <1> 	retf	4			; THROW AWAY (e)FLAGS
  2568                              <1> 
  2569                              <1> 	;-----	SHIFT STATUS
  2570                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
  2571 00000D25 8A25[646A0000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2572 00000D2B 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2573                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2574                              <1> 	;shl	ah, cl			; BIT 7 POSITION
  2575 00000D2E C0E405              <1>         shl	ah, 5
  2576 00000D31 A0[646A0000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2577 00000D36 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2578 00000D38 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2579 00000D3A A0[666A0000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2580 00000D3F 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2581 00000D41 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2582                              <1> _K3:
  2583 00000D43 A0[636A0000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2584 00000D48 EB92                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2585                              <1> 
  2586                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
  2587                              <1> _K300:
  2588 00000D4A 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
  2589 00000D4C 758E                <1> 	jne	short _KIO_EXIT		; NO, RETURN
  2590 00000D4E F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
  2591 00000D51 7589                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2592 00000D53 F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
  2593 00000D56 7584                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2594 00000D58 B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
  2595 00000D5A E8B6060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2596                              <1> 	;mov	cx, 5			; SHIFT COUNT
  2597                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
  2598 00000D5F C0E705              <1> 	shl	bh, 5
  2599 00000D62 88D8                <1> 	mov	al, bl			; PUT IN RATE
  2600 00000D64 08F8                <1> 	or	al, bh			; AND DELAY
  2601 00000D66 E8AA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2602 00000D6B E96CFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
  2603                              <1> 
  2604                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
  2605                              <1> _K500:
  2606 00000D70 56                  <1> 	push	esi			; SAVE SI (esi)
  2607 00000D71 FA                  <1> 	cli				; 
  2608 00000D72 8B1D[746A0000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
  2609 00000D78 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
  2610 00000D7A E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
  2611 00000D7F 3B1D[706A0000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
  2612 00000D85 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
  2613 00000D87 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
  2614 00000D8A 891D[746A0000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
  2615 00000D90 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
  2616 00000D92 EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
  2617                              <1> _K502:
  2618 00000D94 B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
  2619                              <1> _K504:
  2620 00000D96 FB                  <1> 	sti				
  2621 00000D97 5E                  <1> 	pop	esi			; RECOVER SI (esi)
  2622 00000D98 E93FFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
  2623                              <1> 
  2624                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
  2625                              <1> _K1S:
  2626 00000D9D FA                  <1> 	cli	; 03/12/2014
  2627 00000D9E 8B1D[706A0000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2628 00000DA4 3B1D[746A0000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2629                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
  2630 00000DAA 750F                <1> 	jne	short _k1x ; 03/12/2014
  2631                              <1> 	;
  2632                              <1> 	; 03/12/2014
  2633                              <1> 	; 28/08/2014
  2634                              <1> 	; PERFORM OTHER FUNCTION ?? here !
  2635                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
  2636                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
  2637                              <1> _K1T:                                   ; ASCII READ
  2638 00000DAC FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
  2639 00000DAD 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
  2640                              <1> _K1U:	
  2641 00000DAE FA                  <1> 	cli				; INTERRUPTS BACK OFF
  2642 00000DAF 8B1D[706A0000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2643 00000DB5 3B1D[746A0000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2644                              <1> _k1x:
  2645 00000DBB 53                  <1> 	push	ebx			; SAVE ADDRESS		
  2646 00000DBC 9C                  <1> 	pushf				; SAVE FLAGS
  2647 00000DBD E80B070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2648 00000DC2 8A1D[656A0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2649 00000DC8 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2650 00000DCA 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
  2651 00000DCD 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
  2652 00000DCF E8A5060000          <1> 	call	SND_LED1
  2653 00000DD4 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2654                              <1> _K1V:
  2655 00000DD5 9D                  <1> 	popf				; RESTORE FLAGS
  2656 00000DD6 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2657 00000DD7 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
  2658                              <1> 	;
  2659 00000DD9 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
  2660 00000DDC E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
  2661 00000DE1 891D[706A0000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
  2662 00000DE7 C3                  <1> 	retn				; RETURN
  2663                              <1> 
  2664                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
  2665                              <1> _K2S:
  2666 00000DE8 FA                  <1> 	cli				; INTERRUPTS OFF
  2667 00000DE9 8B1D[706A0000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
  2668 00000DEF 3B1D[746A0000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
  2669 00000DF5 668B03              <1> 	mov	ax, [ebx]
  2670 00000DF8 9C                  <1> 	pushf				; SAVE FLAGS
  2671 00000DF9 6650                <1> 	push	ax			; SAVE CODE
  2672 00000DFB E8CD060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2673 00000E00 8A1D[656A0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2674 00000E06 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2675 00000E08 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
  2676 00000E0B 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
  2677 00000E0D E850060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2678                              <1> _K2T:
  2679 00000E12 6658                <1> 	pop	ax			; RESTORE CODE
  2680 00000E14 9D                  <1> 	popf				; RESTORE FLAGS
  2681 00000E15 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2682 00000E16 C3                  <1> 	retn				; RETURN
  2683                              <1> 
  2684                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
  2685                              <1> _KIO_E_XLAT:
  2686 00000E17 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2687 00000E19 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
  2688 00000E1B 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
  2689 00000E1D 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
  2690 00000E1F 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
  2691                              <1> _KIO_E_RET:				
  2692 00000E21 C3                  <1> 	retn				; GO BACK
  2693                              <1> 
  2694                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
  2695                              <1> _KIO_S_XLAT:
  2696 00000E22 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
  2697 00000E25 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
  2698 00000E27 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
  2699 00000E29 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
  2700 00000E2B 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
  2701 00000E2D 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
  2702 00000E2F B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
  2703                              <1> _kio_ret: ; 03/12/2014
  2704 00000E31 F8                  <1> 	clc
  2705 00000E32 C3                  <1> 	retn
  2706                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2707                              <1> _KIO_S1:				
  2708 00000E33 B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
  2709                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2710 00000E35 C3                  <1> 	retn
  2711                              <1> _KIO_S2:		
  2712 00000E36 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
  2713 00000E39 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
  2714 00000E3B 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2715 00000E3D 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
  2716 00000E3F 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2717 00000E41 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
  2718 00000E43 EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
  2719                              <1> _KIO_S3:
  2720 00000E45 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
  2721                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
  2722 00000E47 75E8                <1> 	jne	short _kio_ret
  2723 00000E49 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2724 00000E4B 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
  2725 00000E4D 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
  2726                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
  2727                              <1> _KIO_USE:
  2728                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
  2729 00000E4F C3                  <1> 	retn				; RETURN	
  2730                              <1> _KIO_DIS:
  2731 00000E50 F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
  2732 00000E51 C3                  <1> 	retn				; RETURN
  2733                              <1> 
  2734                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
  2735                              <1> _K4:    
  2736 00000E52 43                  <1> 	inc     ebx
  2737 00000E53 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
  2738 00000E54 3B1D[6C6A0000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
  2739                              <1>         ;jne    short _K5               ; NO, CONTINUE
  2740 00000E5A 7206                <1> 	jb	short _K5
  2741 00000E5C 8B1D[686A0000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
  2742                              <1> _K5:
  2743 00000E62 C3                  <1> 	retn
  2744                              <1> 
  2745                              <1> ; 20/02/2015
  2746                              <1> ; 05/12/2014
  2747                              <1> ; 26/08/2014
  2748                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
  2749                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
  2750                              <1> ;
  2751                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
  2752                              <1> ; rombios source code (06/10/1985)
  2753                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
  2754                              <1> 
  2755                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
  2756                              <1> ENA_KBD		equ	0AEh	; ENABLE KEYBOARD COMMAND
  2757                              <1> DIS_KBD		equ	0ADh	; DISABLE KEYBOARD COMMAND
  2758                              <1> SHUT_CMD	equ	0FEh	; CAUSE A SHUTDOWN COMMAND
  2759                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  2760                              <1> STATUS_PORT	equ	064h	; 8042 STATUS PORT
  2761                              <1> INPT_BUF_FULL	equ	00000010b ; 1 = +INPUT BUFFER FULL
  2762                              <1> PORT_A		equ	060h	; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  2763                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
  2764                              <1> KB_ACK		equ	0FAh	; ACKNOWLEDGE PROM TRANSMISSION
  2765                              <1> KB_RESEND	equ	0FEh	; RESEND REQUEST
  2766                              <1> KB_OVER_RUN	equ	0FFh	; OVER RUN SCAN CODE
  2767                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
  2768                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
  2769                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
  2770                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
  2771                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
  2772                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
  2773                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
  2774                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
  2775                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
  2776                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
  2777                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
  2778                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
  2779                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
  2780                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
  2781                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
  2782                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
  2783                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
  2784                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
  2785                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
  2786                              <1> F11_M		equ	87		; F11 KEY MAKE
  2787                              <1> F12_M		equ	88		; F12 KEY MAKE
  2788                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
  2789                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
  2790                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
  2791                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
  2792                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
  2793                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
  2794                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
  2795                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
  2796                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
  2797                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
  2798                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
  2799                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
  2800                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
  2801                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
  2802                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
  2803                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
  2804                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
  2805                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
  2806                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
  2807                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
  2808                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
  2809                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
  2810                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
  2811                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
  2812                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
  2813                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
  2814                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
  2815                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
  2816                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
  2817                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
  2818                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
  2819                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
  2820                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
  2821                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
  2822                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
  2823                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
  2824                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
  2825                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
  2826                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
  2827                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
  2828                              <1> ;
  2829                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
  2830                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
  2831                              <1> INTA00		equ	020h		; 8259 PORT
  2832                              <1> 
  2833                              <1> 
  2834                              <1> kb_int:
  2835                              <1> 
  2836                              <1> ; 17/10/2015 ('ctrlbrk') 
  2837                              <1> ; 05/12/2014
  2838                              <1> ; 04/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2839                              <1> 	;	      instead of pc-at bios - 1985-)
  2840                              <1> ; 26/08/2014
  2841                              <1> ;
  2842                              <1> ; 03/06/86  KEYBOARD BIOS
  2843                              <1> ;
  2844                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
  2845                              <1> ;										;
  2846                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
  2847                              <1> ;										;
  2848                              <1> ;--------------------------------------------------------------------------------
  2849                              <1> 
  2850                              <1> KB_INT_1:
  2851 00000E63 FB                  <1> 	sti				; ENABLE INTERRUPTS
  2852                              <1> 	;push	ebp
  2853 00000E64 50                  <1> 	push	eax
  2854 00000E65 53                  <1> 	push	ebx
  2855 00000E66 51                  <1> 	push	ecx
  2856 00000E67 52                  <1> 	push	edx
  2857 00000E68 56                  <1> 	push	esi
  2858 00000E69 57                  <1> 	push	edi
  2859 00000E6A 1E                  <1> 	push	ds
  2860 00000E6B 06                  <1> 	push	es
  2861 00000E6C FC                  <1> 	cld				; FORWARD DIRECTION
  2862 00000E6D 66B81000            <1> 	mov	ax, KDATA
  2863 00000E71 8ED8                <1> 	mov	ds, ax
  2864 00000E73 8EC0                <1> 	mov	es, ax
  2865                              <1> 	;
  2866                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
  2867 00000E75 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
  2868 00000E77 E885050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
  2869 00000E7C FA                  <1> 	cli				; DISABLE INTERRUPTS
  2870 00000E7D B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
  2871                              <1> KB_INT_01:
  2872 00000E82 E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
  2873 00000E84 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
  2874 00000E86 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
  2875                              <1> 	;
  2876                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
  2877 00000E88 E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
  2878                              <1> 	;
  2879                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
  2880                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
  2881                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
  2882                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
  2883                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
  2884                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
  2885                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
  2886                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
  2887                              <1> 	;
  2888                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
  2889                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
  2890 00000E8A FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  2891 00000E8B 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
  2892 00000E8D 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
  2893                              <1> 	;
  2894                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
  2895 00000E8F 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
  2896 00000E91 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
  2897                              <1> 	;
  2898                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
  2899 00000E93 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2900 00000E94 800D[656A0000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
  2901 00000E9B E97A020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
  2902                              <1> 	;
  2903                              <1> 	;-----	RESEND THE LAST BYTE
  2904                              <1> KB_INT_4:
  2905 00000EA0 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2906 00000EA1 800D[656A0000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
  2907 00000EA8 E96D020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
  2908                              <1> 	;
  2909                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
  2910                              <1> KB_INT_2:
  2911 00000EAD 6650                <1> 	push 	ax			; SAVE DATA IN
  2912 00000EAF E819060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2913 00000EB4 8A1D[656A0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2914 00000EBA 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2915 00000EBC 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
  2916 00000EBF 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
  2917 00000EC1 E89C050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2918                              <1> UP0:
  2919 00000EC6 6658                <1> 	pop	ax			; RESTORE DATA IN
  2920                              <1> ;------------------------------------------------------------------------
  2921                              <1> ;	START OF KEY PROCESSING						;
  2922                              <1> ;------------------------------------------------------------------------
  2923 00000EC8 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
  2924                              <1> 	;
  2925                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
  2926 00000ECA 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
  2927 00000ECC 0F841B050000        <1>         je      K62			; BUFFER_FULL_BEEP
  2928                              <1> 	;
  2929                              <1> K16:	
  2930 00000ED2 8A3D[666A0000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
  2931                              <1> 	;
  2932                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
  2933 00000ED8 F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
  2934 00000EDB 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
  2935 00000EDD 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
  2936 00000EDF 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
  2937 00000EE1 7507                <1> 	jne	short RST_RD_ID
  2938 00000EE3 800D[666A0000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
  2939                              <1> RST_RD_ID:
  2940 00000EEA 8025[666A0000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
  2941                              <1>         ;jmp    short ID_EX		; AND EXIT
  2942 00000EF1 E924020000          <1> 	jmp	K26
  2943                              <1> 	;
  2944                              <1> TST_ID_2:
  2945 00000EF6 8025[666A0000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
  2946 00000EFD 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
  2947 00000EFF 7419                <1>         je	short KX_BIT		; JUMP IF SO
  2948 00000F01 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
  2949                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
  2950 00000F03 0F8511020000        <1> 	jne	K26
  2951                              <1> 	;
  2952                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
  2953 00000F09 F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
  2954 00000F0C 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
  2955 00000F0E 800D[636A0000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
  2956 00000F15 E848050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
  2957                              <1> KX_BIT:
  2958 00000F1A 800D[666A0000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
  2959 00000F21 E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
  2960                              <1> 	;
  2961                              <1> NOT_ID:
  2962 00000F26 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
  2963 00000F28 750C                <1> 	jne	short TEST_E1
  2964 00000F2A 800D[666A0000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
  2965                              <1> 	;jmp	short EXIT		; THROW AWAY THIS CODE
  2966 00000F31 E9EB010000          <1> 	jmp	K26A	
  2967                              <1> TEST_E1:	
  2968 00000F36 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
  2969 00000F38 750C                <1> 	jne	short NOT_HC
  2970 00000F3A 800D[666A0000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
  2971 00000F41 E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
  2972                              <1> 	;
  2973                              <1> NOT_HC:
  2974 00000F46 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
  2975 00000F48 F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
  2976 00000F4B 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
  2977                              <1> 	;
  2978 00000F4D BF[4E690000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
  2979 00000F52 AE                  <1> 	scasb
  2980 00000F53 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
  2981 00000F59 AE                  <1> 	scasb
  2982 00000F5A 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
  2983                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
  2984 00000F5C E9B9010000          <1> 	jmp	K26
  2985                              <1> 	;
  2986                              <1> NOT_LC_E0:
  2987 00000F61 F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
  2988 00000F64 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
  2989 00000F66 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
  2990 00000F6B BF[4C690000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
  2991 00000F70 F2AE                <1> 	repne	scasb			; CHECK IT
  2992                              <1> 	;je	short EXIT		; THROW AWAY IF SO
  2993 00000F72 0F84A9010000        <1> 	je	K26A			
  2994                              <1> 	;
  2995 00000F78 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
  2996                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
  2997 00000F7A 0F859A010000        <1> 	jne	K26
  2998 00000F80 F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
  2999                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
  3000 00000F83 0F8591010000        <1> 	jnz	K26
  3001                              <1>         ; 20/02/2015 
  3002 00000F89 F605[646A0000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
  3003                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
  3004 00000F90 0F8584010000        <1> 	jnz	K26
  3005 00000F96 E9E1020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
  3006                              <1> 	;
  3007                              <1> 	;-----	TEST FOR SYSTEM KEY
  3008                              <1> T_SYS_KEY:
  3009 00000F9B 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
  3010 00000F9D 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
  3011                              <1> 	;
  3012 00000F9F F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
  3013 00000FA2 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
  3014                              <1> 	;
  3015 00000FA4 F605[646A0000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
  3016                              <1>         ;jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
  3017 00000FAB 0F8569010000        <1> 	jnz     K26			
  3018                              <1> 	;
  3019 00000FB1 800D[646A0000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
  3020 00000FB8 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3021 00000FBA E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3022                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3023 00000FBC B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3024 00000FBE E83E040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3025                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
  3026                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
  3027                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  3028                              <1> 	;INT	15H			; USER INTERRUPT	
  3029 00000FC3 E965010000          <1>         jmp     K27A                    ; END PROCESSING
  3030                              <1> 	;
  3031                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
  3032                              <1> 	;
  3033                              <1> K16C:
  3034 00000FC8 8025[646A0000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
  3035 00000FCF B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3036 00000FD1 E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
  3037                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3038                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3039                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3040                              <1> 	;
  3041                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
  3042                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  3043                              <1> 	;INT	15H			; USER INTERRUPT
  3044                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
  3045                              <1> 	;
  3046 00000FD3 E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
  3047                              <1> 	;
  3048                              <1> 	;-----	TEST FOR SHIFT KEYS
  3049                              <1> K16A:
  3050 00000FD8 8A1D[636A0000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
  3051 00000FDE BF[48690000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
  3052 00000FE3 B908000000          <1> 	mov	ecx, _K6L		; LENGTH
  3053 00000FE8 F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
  3054 00000FEA 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
  3055 00000FEC 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
  3056                              <1> 	;
  3057                              <1> 	;------	SHIFT KEY FOUND
  3058                              <1> K17:
  3059 00000FF2 81EF[49690000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
  3060 00000FF8 8AA7[50690000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
  3061 00000FFE B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
  3062 00001000 A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
  3063 00001002 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
  3064                              <1> 	;
  3065                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
  3066                              <1> K17C:
  3067 00001008 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
  3068 0000100B 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
  3069                              <1> 	;
  3070                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
  3071 0000100D 0825[636A0000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
  3072 00001013 A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
  3073                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
  3074 00001015 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
  3075                              <1> K17D:
  3076 0000101B F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
  3077 0000101E 740B                <1> 	jz 	short K17E		; NO, JUMP
  3078 00001020 0825[666A0000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
  3079 00001026 E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
  3080                              <1> K17E:
  3081 0000102B D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
  3082 0000102D 0825[646A0000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
  3083 00001033 E9E2000000          <1> 	jmp	K26
  3084                              <1> 	;
  3085                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
  3086                              <1> K18:					; SHIFT-TOGGLE
  3087 00001038 F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
  3088                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
  3089 0000103B 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
  3090                              <1> K18A:
  3091 00001041 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
  3092 00001043 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
  3093 00001045 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
  3094                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
  3095 00001048 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
  3096                              <1> K18B:
  3097 0000104E F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
  3098 00001051 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
  3099                              <1> K19:	
  3100 00001053 F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
  3101 00001056 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
  3102 00001058 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
  3103 0000105B 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
  3104                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
  3105 0000105D 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
  3106 0000105F E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
  3107                              <1> K21:					; MIGHT BE NUMERIC
  3108 00001064 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
  3109 00001067 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
  3110                              <1> 	;
  3111                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
  3112 00001069 8425[646A0000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
  3113 0000106F 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
  3114                              <1> K22A:
  3115 00001075 0825[646A0000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
  3116 0000107B 3025[636A0000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
  3117                              <1> 	;
  3118                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
  3119 00001081 F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
  3120 00001084 7409                <1> 	jz	short K22B		; GO IF NOT
  3121                              <1> 	;
  3122 00001086 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
  3123 00001088 E8D5030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
  3124 0000108D 6658                <1> 	pop	ax			; RESTORE SCAN CODE
  3125                              <1> K22B:
  3126 0000108F 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
  3127 00001091 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
  3128 00001097 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
  3129 00001099 E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
  3130                              <1> 	;
  3131                              <1> 	;-----	BREAK SHIFT FOUND
  3132                              <1> K23:					; BREAK-SHIFT-FOUND
  3133 0000109E 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
  3134 000010A1 F6D4                <1> 	not	ah			; INVERT MASK
  3135 000010A3 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
  3136 000010A5 2025[636A0000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
  3137 000010AB 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
  3138 000010AE 7730                <1> 	ja	short K23D		; NO, ALL DONE
  3139                              <1> 	;
  3140 000010B0 F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
  3141 000010B3 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
  3142 000010B5 2025[666A0000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
  3143 000010BB EB08                <1> 	jmp	short K23B		; CONTINUE
  3144                              <1> K23A:
  3145 000010BD D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
  3146 000010BF 2025[646A0000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
  3147                              <1> K23B:
  3148 000010C5 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
  3149 000010C7 A0[666A0000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
  3150 000010CC D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
  3151 000010CE 0A05[646A0000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
  3152 000010D4 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
  3153 000010D6 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
  3154 000010D8 0805[636A0000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
  3155 000010DE 88E0                <1> 	mov	al, ah
  3156                              <1> K23D:
  3157 000010E0 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
  3158 000010E2 7536                <1> 	jne	short K26		; INTERRUPT RETURN
  3159                              <1> 	;	
  3160                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
  3161 000010E4 A0[676A0000]        <1> 	mov	al, [ALT_INPUT]
  3162 000010E9 B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
  3163 000010EB 8825[676A0000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
  3164 000010F1 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
  3165 000010F3 7425                <1> 	je	short K26		; INTERRUPT_RETURN
  3166 000010F5 E9D0020000          <1>         jmp     K61                     ; IT WASN'T, SO PUT IN BUFFER
  3167                              <1> 	;
  3168                              <1> K24:					; BREAK-TOGGLE
  3169 000010FA 2025[646A0000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
  3170 00001100 EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
  3171                              <1> 	;
  3172                              <1> 	;-----	TEST FOR HOLD STATE
  3173                              <1> 					; AL, AH = SCAN CODE
  3174                              <1> K25:					; NO-SHIFT-FOUND
  3175 00001102 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
  3176 00001104 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
  3177 00001106 F605[646A0000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
  3178 0000110D 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
  3179 0000110F 3C45                <1> 	cmp	al, NUM_KEY
  3180 00001111 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
  3181 00001113 8025[646A0000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
  3182                              <1> 	;
  3183                              <1> K26:
  3184 0000111A 8025[666A0000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3185                              <1> K26A:					; INTERRUPT-RETURN
  3186 00001121 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3187 00001122 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3188 00001124 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3189                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
  3190 00001126 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3191 00001128 E8D4020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3192                              <1> K27A:
  3193 0000112D FA                  <1> 	cli				; DISABLE INTERRUPTS
  3194 0000112E 07                  <1> 	pop	es			; RESTORE REGISTERS
  3195 0000112F 1F                  <1> 	pop	ds
  3196 00001130 5F                  <1> 	pop	edi
  3197 00001131 5E                  <1> 	pop	esi
  3198 00001132 5A                  <1> 	pop	edx
  3199 00001133 59                  <1> 	pop	ecx
  3200 00001134 5B                  <1> 	pop	ebx
  3201 00001135 58                  <1> 	pop	eax
  3202                              <1> 	;pop	ebp
  3203 00001136 CF                  <1> 	iret				; RETURN
  3204                              <1> 
  3205                              <1> 	;-----	NOT IN	HOLD STATE
  3206                              <1> K28:					; NO-HOLD-STATE
  3207 00001137 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
  3208 00001139 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
  3209                              <1> 	;
  3210 0000113B F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
  3211                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
  3212 0000113E 0F84F1000000        <1>         jz      K38
  3213                              <1> 	;
  3214 00001144 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
  3215 00001147 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  3216                              <1> 	 ;28/02/2015
  3217 00001149 F605[646A0000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
  3218                              <1> 	;jz	short K29		;  NO, ALT STATE IS REAL
  3219 00001150 0F85DF000000        <1> 	jnz	K38			; YES, THIS IS PHONY ALT STATE 
  3220                              <1>         ;				; DUE TO PRESSING SYSREQ	
  3221                              <1> ;K28A:	jmp	short K38
  3222                              <1> 	;
  3223                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
  3224                              <1> K29:					; TEST-RESET
  3225 00001156 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
  3226 00001159 740B                <1> 	jz	short K31		; NO_RESET
  3227 0000115B 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
  3228 0000115D 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
  3229                              <1> 	;
  3230                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
  3231                              <1>  	; 26/08/2014
  3232                              <1> cpu_reset:
  3233                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
  3234                              <1> 	; Send FEh (system reset command) to the keyboard controller.
  3235 0000115F B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
  3236 00001161 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
  3237                              <1> khere:
  3238 00001163 F4                  <1> 	hlt				; WAIT FOR 80286 RESET
  3239 00001164 EBFD                <1> 	jmp 	short khere		; INSURE HALT
  3240                              <1> 
  3241                              <1> 	;
  3242                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
  3243                              <1> K31:					; NO-RESET
  3244 00001166 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
  3245 00001168 7507                <1> 	jne	short K311		; NOT THERE
  3246 0000116A B020                <1> 	mov	al, ' '			; SET SPACE CHAR
  3247 0000116C E948020000          <1>         jmp     K57                     ; BUFFER_FILL
  3248                              <1> K311:
  3249 00001171 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
  3250 00001173 7509                <1> 	jne	short K312		; NOT THERE
  3251 00001175 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
  3252 00001179 E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
  3253                              <1> K312:
  3254 0000117E 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
  3255 00001180 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
  3256 00001186 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
  3257 00001188 0F849A000000        <1>         je      K37B                    ; GO PROCESS
  3258                              <1> 	;
  3259                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
  3260                              <1> K32:					; ALT-KEY-PAD
  3261 0000118E BF[24690000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
  3262 00001193 B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
  3263 00001198 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
  3264 0000119A 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
  3265 0000119C F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
  3266 0000119F 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
  3267 000011A5 81EF[25690000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
  3268 000011AB A0[676A0000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
  3269 000011B0 B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
  3270 000011B2 F6E4                <1> 	mul	ah
  3271 000011B4 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
  3272 000011B7 A2[676A0000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
  3273                              <1> ;K32A:
  3274 000011BC E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
  3275                              <1> 	;
  3276                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
  3277                              <1> K33:					; NO-ALT-KEYPAD
  3278 000011C1 C605[676A0000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
  3279 000011C8 B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
  3280 000011CD F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
  3281 000011CF 7450                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
  3282                              <1> 	;
  3283                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
  3284                              <1> K34:					; ALT-TOP-ROW
  3285 000011D1 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
  3286 000011D3 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
  3287 000011D5 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
  3288 000011D7 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
  3289 000011D9 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
  3290 000011DC EB43                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3291                              <1> 	;
  3292                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
  3293                              <1> K35:					; ALT-FUNCTION
  3294 000011DE 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
  3295 000011E0 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
  3296 000011E2 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
  3297 000011E4 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
  3298 000011E6 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
  3299 000011E9 EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3300                              <1> K35A:
  3301 000011EB F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
  3302 000011EE 7422                <1> 	jz	short K37		; NO, JUMP
  3303 000011F0 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
  3304 000011F2 7509                <1>         jne     short K35B              ; NOT THERE
  3305 000011F4 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
  3306 000011F8 E9BC010000          <1> 	jmp	K57			; BUFFER FILL
  3307                              <1> K35B:
  3308 000011FD 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
  3309 000011FF 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
  3310 00001201 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
  3311                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
  3312 00001203 0F8511FFFFFF        <1>         jne     K26
  3313 00001209 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
  3314 0000120D E9A7010000          <1> 	jmp	K57			; BUFFER FILL
  3315                              <1> K37:
  3316 00001212 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
  3317 00001214 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
  3318 00001216 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
  3319                              <1>         ;ja	short K32A		; IF SO, IGNORE
  3320 00001218 0F87FCFEFFFF        <1>         ja      K26
  3321 0000121E 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
  3322                              <1> K37A:
  3323 00001221 B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  3324 00001223 E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  3325                              <1> K37B:
  3326 00001228 B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  3327 0000122A E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  3328                              <1> K37C:
  3329 0000122F 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  3330 00001231 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  3331 00001233 EBEC                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  3332                              <1> 	;
  3333                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  3334                              <1> K38:					; NOT-ALT-SHIFT
  3335                              <1> 					; BL STILL HAS SHIFT FLAGS
  3336 00001235 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  3337                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
  3338 00001238 0F84B0000000        <1>         jz      K44                     ; NOT-CTL-SHIFT
  3339                              <1> 	;
  3340                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  3341                              <1> 	;-----	TEST FOR BREAK
  3342                              <1> K38A:
  3343 0000123E 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  3344 00001240 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
  3345 00001242 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3346 00001245 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  3347 00001247 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3348 0000124A 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  3349                              <1> K38B:
  3350 0000124C 8B1D[706A0000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  3351 00001252 891D[746A0000]      <1> 	mov	[BUFFER_TAIL], ebx
  3352 00001258 C605[626A0000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  3353                              <1> 	;
  3354                              <1> 	;-----	ENABLE KEYBOARD
  3355 0000125F B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3356 00001261 E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3357                              <1> 	;
  3358                              <1> 	; CTRL+BREAK code here !!!
  3359                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  3360                              <1> 	; 17/10/2015	
  3361 00001266 E89F260000          <1> 	call	ctrlbrk ; control+break subroutine
  3362                              <1> 	;
  3363 0000126B 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
  3364 0000126E E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  3365                              <1> 	;
  3366                              <1> 	;-----	TEST FOR PAUSE
  3367                              <1> K39:					; NO_BREAK
  3368 00001273 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3369 00001276 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  3370 00001278 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  3371 0000127A 7533                <1> 	jne	short K41		; NO-PAUSE
  3372                              <1> K39P:
  3373 0000127C 800D[646A0000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  3374                              <1> 	;
  3375                              <1> 	;-----	ENABLE KEYBOARD
  3376 00001283 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3377 00001285 E877010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3378                              <1> K39A:
  3379 0000128A B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  3380 0000128C E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  3381                              <1> 	;
  3382                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  3383 0000128E 803D[606A0000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  3384 00001295 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  3385 00001297 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  3386 0000129B A0[616A0000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  3387 000012A0 EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  3388                              <1> 	;
  3389                              <1> K40:					; PAUSE-LOOP
  3390 000012A1 F605[646A0000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  3391 000012A8 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  3392                              <1> 	;
  3393 000012AA E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  3394                              <1>         ;
  3395                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  3396                              <1> K41:					; NO-PAUSE
  3397 000012AF 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  3398 000012B1 7513                <1> 	jne	short K42		; NOT-KEY-55
  3399 000012B3 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3400 000012B6 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  3401 000012B8 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3402 000012BB 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  3403                              <1> K41A:	
  3404 000012BD 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  3405 000012C1 E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  3406                              <1> 	;
  3407                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  3408                              <1> K42:					; NOT-KEY-55
  3409 000012C6 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  3410 000012C8 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  3411 000012CA 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  3412 000012CC 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  3413 000012CE F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  3414 000012D1 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  3415 000012D3 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  3416 000012D7 E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  3417                              <1> K42A: 
  3418                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3419 000012DC 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  3420                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  3421                              <1> 	;;jb	K56 ; 20/02/2015
  3422                              <1> 	;;jmp	K64 ; 20/02/2015
  3423                              <1> K42B:
  3424 000012DE BB[58690000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3425 000012E3 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  3426 000012E9 E9B9000000          <1> 	jmp	K64	
  3427                              <1>         ;
  3428                              <1> 	;-----	NOT IN CONTROL SHIFT
  3429                              <1> K44:					; NOT-CTL-SHIFT
  3430 000012EE 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  3431 000012F0 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  3432 000012F2 F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  3433 000012F5 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  3434 000012F7 F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  3435 000012FA 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  3436 000012FC EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3437                              <1> K44A:
  3438 000012FE F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  3439 00001301 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3440                              <1> 	;
  3441                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  3442                              <1> K44B:
  3443 00001303 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3444 00001305 E8F7000000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3445 0000130A B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  3446 0000130C E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  3447                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  3448                              <1> 	;PUSH 	BP			; SAVE POINTER
  3449                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  3450                              <1> 	;POP	BP			; RESTORE POINTER
  3451 0000130E 8025[666A0000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  3452 00001315 E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  3453                              <1> 	;
  3454                              <1> 	;-----	HANDLE IN-CORE KEYS
  3455                              <1> K45:					; NOT-PRINT-SCREEN
  3456 0000131A 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  3457 0000131C 7734                <1> 	ja	short K46		; JUMP IF NOT
  3458 0000131E 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  3459 00001320 7505                <1> 	jne	short K45A		; NO, JUMP
  3460 00001322 F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  3461 00001325 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  3462                              <1> K45A:
  3463 00001327 B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  3464 0000132C BF[2E690000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  3465 00001331 F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  3466                              <1> 		; 20/02/2015
  3467 00001333 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  3468                              <1> 	;
  3469 00001335 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  3470 00001338 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  3471                              <1> K45B:
  3472 0000133A F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3473 0000133D 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  3474                              <1> 					; NO, LOWERCASE
  3475                              <1> K45C:
  3476 0000133F BB[B0690000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  3477 00001344 EB51                <1> 	jmp	short K56	
  3478                              <1> K45D:					; ALMOST-CAPS-STATE
  3479 00001346 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  3480 00001349 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  3481                              <1> K45E:
  3482 0000134B BB[086A0000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  3483 00001350 EB45                <1> K45F:	jmp	short K56
  3484                              <1> 	;
  3485                              <1> 	;-----	TEST FOR KEYS F1 - F10
  3486                              <1> K46:					; NOT IN-CORE AREA
  3487 00001352 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  3488                              <1> 	;ja	short K47		; JUMP IF NOT
  3489                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  3490 00001354 7635                <1> 	jna	short K53		
  3491                              <1> 	;
  3492                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  3493                              <1> K47:					; NOT F1 - F10
  3494 00001356 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  3495 00001358 772D                <1> 	ja	short K52		; JUMP IF NOT
  3496                              <1> 	;
  3497                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  3498                              <1> K48:
  3499 0000135A 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  3500 0000135C 74ED                <1> 	je	short K45E		; GO TRANSLATE
  3501 0000135E 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  3502 00001360 74E9                <1> 	je	short K45E		; GO TRANSLATE
  3503 00001362 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  3504 00001365 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  3505                              <1> 	;		
  3506 00001367 F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  3507 0000136A 7514                <1> 	jnz	short K50		; TEST FOR SURE
  3508 0000136C F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3509                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  3510 0000136F 75DA                <1> 	jnz	short K45E
  3511                              <1> 	;
  3512                              <1> 	;-----	BASE CASE FOR KEYPAD
  3513                              <1> K49:					
  3514 00001371 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  3515 00001373 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  3516 00001375 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  3517 00001377 EB40                <1> 	jmp	short K57		; BUFFER FILL
  3518                              <1> K49A:
  3519 00001379 BB[B0690000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  3520 0000137E EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  3521                              <1> 	;
  3522                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  3523                              <1> K50:					; ALMOST-NUM-STATE
  3524 00001380 F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  3525 00001383 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  3526 00001385 EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  3527                              <1> 	;
  3528                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  3529                              <1> K52:					; NOT A NUMPAD KEY
  3530 00001387 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  3531                              <1> 	;jne	short K53		; JUMP IF NOT
  3532                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  3533 00001389 74AF                <1> 	je	short K45B		
  3534                              <1> 	;
  3535                              <1> 	;-----	MUST BE F11 OR F12 
  3536                              <1> K53:					; F1 - F10 COME HERE, TOO
  3537 0000138B F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  3538 0000138E 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  3539                              <1> 		; 20/02/2015 
  3540 00001390 BB[086A0000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  3541 00001395 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  3542                              <1> 	;
  3543                              <1> 	;-----	TRANSLATE THE CHARACTER
  3544                              <1> K56:					; TRANSLATE-CHAR
  3545 00001397 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3546 00001399 D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  3547 0000139A F605[666A0000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3548 000013A1 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3549 000013A3 B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  3550 000013A5 EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  3551                              <1> 	;
  3552                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  3553                              <1> K64:					; TRANSLATE-SCAN-ORGD
  3554 000013A7 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3555 000013A9 D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  3556 000013AA 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  3557 000013AC B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  3558 000013AE F605[666A0000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3559 000013B5 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3560 000013B7 B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  3561                              <1> 	;
  3562                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  3563                              <1> K57:					; BUFFER_FILL
  3564 000013B9 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  3565                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  3566 000013BB 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  3567 000013C1 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  3568                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  3569 000013C4 0F8450FDFFFF        <1> 	je      K26			; INTERRUPT_RETURN
  3570                              <1> ;K59:					; NEAR_INTERRUPT_RETURN
  3571                              <1> ;	jmp	K26			; INTERRUPT_RETURN
  3572                              <1> K61:					; NOT-CAPS-STATE
  3573 000013CA 8B1D[746A0000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  3574 000013D0 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  3575 000013D2 E87BFAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  3576 000013D7 3B1D[706A0000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  3577 000013DD 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  3578 000013DF 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  3579 000013E2 891D[746A0000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  3580 000013E8 E92DFDFFFF          <1> 	jmp	K26
  3581                              <1> 	;;cli				; TURN OFF INTERRUPTS
  3582                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  3583                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  3584                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3585                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3586                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  3587                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  3588                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3589                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  3590                              <1> 	;;jmp   K27                    
  3591                              <1> 	;
  3592                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  3593                              <1> K62:
  3594 000013ED B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  3595 000013EF E620                <1> 	out	INTA00, al
  3596 000013F1 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  3597 000013F5 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  3598 000013F7 E8A1010000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  3599 000013FC E925FDFFFF          <1> 	jmp     K27			; EXIT   
  3600                              <1> 
  3601                              <1> SHIP_IT:
  3602                              <1> 	;---------------------------------------------------------------------------------
  3603                              <1> 	; SHIP_IT
  3604                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3605                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  3606                              <1> 	;---------------------------------------------------------------------------------
  3607                              <1> 	;
  3608 00001401 6650                <1> 	push	ax			; SAVE DATA TO SEND
  3609                              <1> 
  3610                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  3611 00001403 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  3612                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  3613 00001404 B900000100          <1> 	mov	ecx, 10000h			
  3614                              <1> S10:
  3615 00001409 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  3616 0000140B A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  3617 0000140D E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  3618                              <1> 
  3619 0000140F 6658                <1> 	pop	ax			; GET DATA TO SEND
  3620 00001411 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  3621 00001413 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3622 00001414 C3                  <1> 	retn				; RETURN TO CALLER
  3623                              <1> 
  3624                              <1> SND_DATA:
  3625                              <1> 	; ---------------------------------------------------------------------------------
  3626                              <1> 	; SND_DATA
  3627                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3628                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  3629                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  3630                              <1> 	; ---------------------------------------------------------------------------------
  3631                              <1> 	;
  3632 00001415 6650                <1> 	push	ax			; SAVE REGISTERS
  3633 00001417 6653                <1> 	push	bx
  3634 00001419 51                  <1> 	push	ecx
  3635 0000141A 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  3636 0000141C B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  3637                              <1> SD0:
  3638 0000141E FA                  <1> 	cli				; DISABLE INTERRUPTS
  3639 0000141F 8025[656A0000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  3640                              <1> 	;
  3641                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  3642 00001426 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  3643                              <1> SD5:
  3644 0000142B E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  3645 0000142D A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  3646 0000142F E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  3647                              <1> 	;
  3648 00001431 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  3649 00001433 E660                <1> 	out	PORT_A, al		; SEND BYTE
  3650 00001435 FB                  <1> 	sti				; ENABLE INTERRUPTS
  3651                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  3652 00001436 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  3653                              <1> SD1:
  3654 0000143B F605[656A0000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  3655 00001442 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  3656 00001444 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  3657                              <1> SD2:
  3658 00001446 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  3659 00001448 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  3660 0000144A 800D[656A0000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  3661 00001451 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  3662                              <1> SD3:
  3663 00001453 F605[656A0000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  3664 0000145A 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  3665                              <1> SD4:	
  3666 0000145C 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  3667 0000145D 665B                <1> 	pop	bx
  3668 0000145F 6658                <1> 	pop	ax
  3669 00001461 C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  3670                              <1> 
  3671                              <1> SND_LED:
  3672                              <1> 	; ---------------------------------------------------------------------------------
  3673                              <1> 	; SND_LED
  3674                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  3675                              <1> 	;
  3676                              <1> 	;----------------------------------------------------------------------------------
  3677                              <1> 	;
  3678 00001462 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3679 00001463 F605[656A0000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3680 0000146A 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3681                              <1> 	;
  3682 0000146C 800D[656A0000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3683 00001473 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3684 00001475 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3685 00001477 EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  3686                              <1> SND_LED1:
  3687 00001479 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3688 0000147A F605[656A0000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3689 00001481 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3690                              <1> 	;
  3691 00001483 800D[656A0000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3692                              <1> SL0:
  3693 0000148A B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  3694 0000148C E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3695 00001491 FA                  <1> 	cli
  3696 00001492 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  3697 00001497 8025[656A0000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  3698 0000149E 0805[656A0000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  3699 000014A4 F605[656A0000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3700 000014AB 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  3701                              <1> 	;
  3702 000014AD E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3703 000014B2 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3704 000014B3 F605[656A0000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3705 000014BA 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  3706                              <1> SL2:
  3707 000014BC B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  3708 000014BE E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3709 000014C3 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3710                              <1> SL3:
  3711 000014C4 8025[656A0000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  3712                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  3713 000014CB FB                  <1> 	sti				; ENABLE INTERRUPTS
  3714 000014CC C3                  <1> 	retn				; RETURN TO CALLER
  3715                              <1> 
  3716                              <1> MAKE_LED:
  3717                              <1> 	;---------------------------------------------------------------------------------
  3718                              <1> 	; MAKE_LED
  3719                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  3720                              <1> 	;	THE MODE INDICATORS.
  3721                              <1> 	;---------------------------------------------------------------------------------
  3722                              <1> 	;
  3723                              <1> 	;push 	cx			; SAVE CX
  3724 000014CD A0[636A0000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  3725 000014D2 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  3726                              <1> 	;mov	cl, 4			; SHIFT COUNT
  3727                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  3728 000014D4 C0C004              <1> 	rol	al, 4 ; 20/02/2015
  3729 000014D7 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  3730                              <1> 	;pop	cx
  3731 000014D9 C3                  <1> 	retn				; RETURN TO CALLER
  3732                              <1> 
  3733                              <1> ; % include 'kybdata.inc'   ; KEYBOARD DATA ; 11/03/2015
  3734                              <1> 
  3735                              <1> 
  3736                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  3737                                  
  3738                                  %include 'video.inc' ; 07/03/2015
  3739                              <1> ; Retro UNIX 386 v1 Kernel - VIDEO.INC
  3740                              <1> ; Last Modification: 16/01/2016
  3741                              <1> ;		  (Video Data is in 'VIDATA.INC')
  3742                              <1> ;
  3743                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
  3744                              <1> 
  3745                              <1> ; 30/06/2015
  3746                              <1> ; 27/06/2015
  3747                              <1> ; 11/03/2015
  3748                              <1> ; 02/09/2014
  3749                              <1> ; 30/08/2014
  3750                              <1> ; VIDEO FUNCTIONS
  3751                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  3752                              <1> 
  3753                              <1> write_tty:
  3754                              <1> 	; 13/08/2015
  3755                              <1> 	; 02/09/2014
  3756                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  3757                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  3758                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  3759                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  3760                              <1> 	;
  3761                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  3762                              <1> 	;	   AL = Character to be written
  3763                              <1> 	;	   EBX = Video Page (0 to 7)
  3764                              <1> 	;	   (BH = 0 --> Video Mode 3)
  3765                              <1> 
  3766                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  3767                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  3768                              <1> 
  3769                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  3770                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  3771                              <1> ;
  3772                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  3773                              <1> ;
  3774                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  3775                              <1> ;										:
  3776                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  3777                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  3778                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  3779                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  3780                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  3781                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  3782                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  3783                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  3784                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  3785                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  3786                              <1> ;   THE 0 COLOR IS USED.							:
  3787                              <1> ;   ENTRY --									:
  3788                              <1> ;     (AH) = CURRENT CRT MODE							:
  3789                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  3790                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  3791                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  3792                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  3793                              <1> ;   EXIT -- 									:
  3794                              <1> ;     ALL REGISTERS SAVED							:
  3795                              <1> ;--------------------------------------------------------------------------------
  3796                              <1> 
  3797 000014DA FA                  <1> 	cli
  3798                              <1> 	;
  3799                              <1> 	; READ CURSOR (04/12/2013)
  3800                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  3801 000014DB 08FF                <1> 	or	bh, bh
  3802 000014DD 0F85AB000000        <1> 	jnz	beeper
  3803                              <1> 	; 01/09/2014
  3804 000014E3 803D[606A0000]03    <1> 	cmp	byte [CRT_MODE], 3
  3805 000014EA 7405                <1> 	je	short m3
  3806                              <1> 	;
  3807 000014EC E887020000          <1> 	call	set_mode
  3808                              <1> m3:
  3809 000014F1 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  3810 000014F3 66D1E6              <1> 	shl	si, 1
  3811 000014F6 81C6[96700000]      <1> 	add	esi, cursor_posn
  3812 000014FC 668B16              <1> 	mov	dx, [esi]
  3813                              <1> 	;
  3814                              <1> 	; dx now has the current cursor position
  3815                              <1> 	;
  3816 000014FF 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  3817 00001501 764D                <1> 	jbe	short u8
  3818                              <1> 	;
  3819                              <1> 	; write the char to the screen
  3820                              <1> u0:	
  3821                              <1> 	; ah = attribute/color
  3822                              <1> 	; al = character
  3823                              <1> 	; bl = video page number (0 to 7)
  3824                              <1> 	; bh = 0
  3825                              <1> 	;
  3826 00001503 E83F020000          <1> 	call	write_c_current
  3827                              <1> 	;
  3828                              <1> 	; position the cursor for next char
  3829 00001508 FEC2                <1> 	inc	dl		; next column
  3830                              <1> 	;cmp	dl, [CRT_COLS]
  3831 0000150A 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  3832 0000150D 0F85EB000000        <1>         jne     set_cpos
  3833 00001513 B200                <1> 	mov	dl, 0		; column = 0
  3834                              <1> u10:				; (line feed found)
  3835 00001515 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  3836 00001518 722F                <1> 	jb 	short u6
  3837                              <1> 	;
  3838                              <1> 	; scroll required
  3839                              <1> u1:	
  3840                              <1> 	; SET CURSOR POSITION (04/12/2013)
  3841 0000151A E8DF000000          <1> 	call	set_cpos
  3842                              <1> 	;
  3843                              <1> 	; determine value to fill with during scroll
  3844                              <1> u2:
  3845                              <1> 	; READ_AC_CURRENT		:
  3846                              <1> 	;   THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER
  3847                              <1> 	;    AT THE CURRENT CURSOR POSITION
  3848                              <1> 	;
  3849                              <1> 	; INPUT				
  3850                              <1> 	;	(AH) = CURRENT CRT MODE
  3851                              <1> 	;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )
  3852                              <1> 	;	(DS) = DATA SEGMENT
  3853                              <1> 	;	(ES) = REGEN SEGMENT
  3854                              <1> 	; OUTPUT			
  3855                              <1> 	;	(AL) = CHARACTER READ
  3856                              <1> 	;	(AH) = ATTRIBUTE READ
  3857                              <1> 	;
  3858                              <1> 	; mov	ah, [CRT_MODE] ; move current mode into ah
  3859                              <1> 	;
  3860                              <1> 	; bl = video page number
  3861                              <1> 	;
  3862 0000151F E837010000          <1> 	call	find_position	; get regen location and port address
  3863                              <1> 	; dx = status port
  3864                              <1> 	; esi = cursor location/address
  3865                              <1> p11:
  3866 00001524 FB                  <1> 	sti			; enable interrupts
  3867 00001525 90                  <1> 	nop			; allow for small interupts window
  3868 00001526 FA                  <1> 	cli			; blocks interrupts for single loop
  3869 00001527 EC                  <1> 	in	al, dx		; get status from adapter
  3870 00001528 A801                <1> 	test	al, RHRZ	; is horizontal retrace low
  3871 0000152A 75F8                <1> 	jnz	short p11	; wait until it is
  3872                              <1> p12:				; now wait for either retrace high
  3873 0000152C EC                  <1> 	in	al, dx		; get status
  3874 0000152D A809                <1> 	test	al, RVRT+RHRZ	; is horizontal or vertical retrace high
  3875 0000152F 74FB                <1> 	jz	short p12	; wait until either is active	
  3876                              <1> p13:
  3877 00001531 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
  3878 00001537 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
  3879                              <1> 	;
  3880                              <1> 	; al = character, ah = attribute
  3881                              <1> 	;
  3882 0000153A FB                  <1> 	sti
  3883                              <1> 	; bl = video page number 	
  3884                              <1> u3:
  3885                              <1> 	;;mov	ax, 0601h 	; scroll one line
  3886                              <1> 	;;sub	cx, cx		; upper left corner
  3887                              <1> 	;;mov	dh, 25-1 	; lower right row
  3888                              <1> 	;;;mov	dl, [CRT_COLS]
  3889                              <1> 	;mov	dl, 80		; lower right column	
  3890                              <1> 	;;dec	dl
  3891                              <1> 	;;mov	dl, 79
  3892                              <1> 
  3893                              <1> 	;;call	scroll_up	; 04/12/2013
  3894                              <1> 	;;; 11/03/2015
  3895                              <1> 	; 02/09/2014
  3896                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  3897                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  3898                              <1> 	; 11/03/2015
  3899 0000153B 6629C9              <1> 	sub	cx, cx
  3900 0000153E 66BA4F18            <1> 	mov	dx, 184Fh ; dl= 79 (column), dh = 24 (row)
  3901                              <1> 	;
  3902 00001542 B001                <1> 	mov	al, 1		; scroll 1 line up
  3903                              <1> 		; ah = attribute
  3904 00001544 E93E010000          <1> 	jmp	scroll_up
  3905                              <1> ;u4:
  3906                              <1> 	;;int	10h		; video-call return
  3907                              <1> 				; scroll up the screen
  3908                              <1> 				; tty return
  3909                              <1> ;u5:
  3910                              <1> 	;retn			; return to the caller
  3911                              <1> 
  3912                              <1> u6:				; set-cursor-inc
  3913 00001549 FEC6                <1> 	inc	dh		; next row
  3914                              <1> 				; set cursor
  3915                              <1> ;u7:					
  3916                              <1> 	;;mov	ah, 02h
  3917                              <1> 	;;jmp	short u4 	; establish the new cursor
  3918                              <1> 	;call	set_cpos
  3919                              <1> 	;jmp 	short u5
  3920 0000154B E9AE000000          <1> 	jmp     set_cpos
  3921                              <1> 
  3922                              <1> 	; check for control characters
  3923                              <1> u8:
  3924 00001550 7438                <1> 	je	short u9
  3925 00001552 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  3926 00001554 74BF                <1> 	je	short u10
  3927 00001556 3C07                <1> 	cmp	al, 07h 	; is it a bell
  3928 00001558 7434                <1> 	je	short u11
  3929 0000155A 3C08                <1> 	cmp	al, 08h		; is it a backspace
  3930                              <1> 	;jne	short u0
  3931 0000155C 7424                <1> 	je	short bs	; 12/12/2013
  3932                              <1> 	; 12/12/2013 (tab stop)
  3933 0000155E 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  3934 00001560 75A1                <1> 	jne	short u0
  3935 00001562 88D0                <1> 	mov	al, dl
  3936 00001564 6698                <1> 	cbw
  3937 00001566 B108                <1> 	mov	cl, 8
  3938 00001568 F6F1                <1> 	div	cl
  3939 0000156A 28E1                <1> 	sub	cl, ah
  3940                              <1> ts:
  3941                              <1> 	; 02/09/2014
  3942                              <1> 	; 01/09/2014
  3943 0000156C B020                <1> 	mov	al, 20h
  3944                              <1> tsloop:
  3945 0000156E 6651                <1> 	push	cx
  3946 00001570 6650                <1> 	push	ax
  3947 00001572 30FF                <1> 	xor 	bh, bh
  3948                              <1> 	;mov	bl, [active_page]
  3949 00001574 E878FFFFFF          <1> 	call	m3
  3950 00001579 6658                <1> 	pop	ax  ; ah = attribute/color
  3951 0000157B 6659                <1> 	pop	cx
  3952 0000157D FEC9                <1> 	dec	cl
  3953 0000157F 75ED                <1> 	jnz	short tsloop
  3954 00001581 C3                  <1> 	retn
  3955                              <1> bs:	
  3956                              <1> 	; back space found
  3957                              <1> 
  3958 00001582 08D2                <1> 	or	dl, dl 		; is it already at start of line
  3959                              <1> 	;je	short u7 	; set_cursor
  3960 00001584 7478                <1> 	jz	short set_cpos
  3961 00001586 664A                <1> 	dec	dx     		; no -- just move it back
  3962                              <1> 	;jmp	short u7
  3963 00001588 EB74                <1> 	jmp	short set_cpos
  3964                              <1> 
  3965                              <1> 	; carriage return found
  3966                              <1> u9:
  3967 0000158A B200                <1> 	mov	dl, 0 		; move to first column
  3968                              <1> 	;jmp	short u7
  3969 0000158C EB70                <1> 	jmp	short set_cpos
  3970                              <1> 
  3971                              <1> 	; line feed found
  3972                              <1> ;u10:
  3973                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  3974                              <1> ;	jne	short u6 	; no, just set the cursor
  3975                              <1> ;       jmp     u1              ; yes, scroll the screen
  3976                              <1> 
  3977                              <1> beeper: 
  3978                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  3979                              <1> 	; 18/01/2014
  3980                              <1> 	; 03/12/2013
  3981                              <1> 	; bell found
  3982                              <1> u11:
  3983 0000158E FB                  <1> 	sti
  3984 0000158F 3A1D[A6700000]      <1> 	cmp	bl, [active_page]
  3985 00001595 7551                <1> 	jne	short u12	; Do not sound the beep 
  3986                              <1> 				; if it is not written on the active page
  3987 00001597 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  3988 0000159B B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  3989                              <1> 	;call	beep		; sound the pod bell
  3990                              <1> 	;jmp	short u5 	; tty_return
  3991                              <1> 	;retn
  3992                              <1> 	
  3993                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  3994                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  3995                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  3996                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  3997                              <1> 
  3998                              <1> beep:
  3999                              <1> 	; 07/02/2015
  4000                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4001                              <1> 	; 18/01/2014
  4002                              <1> 	; 03/12/2013
  4003                              <1> 	;
  4004                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  4005                              <1> 	;
  4006                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  4007                              <1> 	;
  4008                              <1> 	; ENTRY:
  4009                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  4010                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  4011                              <1> 	; EXIT:				:
  4012                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  4013                              <1> 
  4014 0000159D 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  4015 0000159E FA                  <1> 	cli			; block interrupts during update
  4016 0000159F B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  4017 000015A1 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  4018 000015A3 EB00                <1> 	jmp	$+2		; I/O delay
  4019 000015A5 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  4020 000015A7 E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  4021 000015A9 EB00                <1> 	jmp	$+2		; I/O delay
  4022 000015AB 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  4023 000015AD E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  4024 000015AF E461                <1> 	in	al, PORT_B	; get current setting of port
  4025 000015B1 88C4                <1> 	mov	ah, al		; save that setting
  4026 000015B3 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  4027 000015B5 E661                <1> 	out	PORT_B, al	; and restore interrupt status
  4028                              <1> 	;popf	; 18/01/2014
  4029 000015B7 FB                  <1> 	sti
  4030                              <1> g7:				; 1/64 second per count (bl)
  4031 000015B8 B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  4032 000015BD E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  4033 000015C2 FECB                <1> 	dec	bl		; (bl) length count expired?
  4034 000015C4 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  4035                              <1> 	;
  4036                              <1> 	;pushf			; save interrupt status
  4037 000015C6 FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  4038 000015C7 E461                <1> 	in	al, PORT_B	; get current port value
  4039                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  4040 000015C9 0CFC                <1>         or      al, ~(GATE2+SPK2)
  4041 000015CB 20C4                <1>         and	ah, al		; someone turned them off during beep
  4042 000015CD 88E0                <1> 	mov	al, ah		; recover value of port
  4043                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  4044 000015CF 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  4045 000015D1 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  4046                              <1> 	;popf			; restore interrupt flag state
  4047 000015D3 FB                  <1> 	sti
  4048 000015D4 B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  4049 000015D9 E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  4050                              <1> 	;pushf			; save interrupt status
  4051 000015DE FA                  <1> 	cli			; block interrupts during update
  4052 000015DF E461                <1> 	in	al, PORT_B	; get current port value in case	
  4053 000015E1 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  4054 000015E3 08E0                <1> 	or	al, ah		; recover value of port_b
  4055 000015E5 E661                <1> 	out	PORT_B, al	; restore speaker status
  4056 000015E7 9D                  <1> 	popf			; restore interrupt flag state
  4057                              <1> u12:	
  4058 000015E8 C3                  <1> 	retn
  4059                              <1> 
  4060                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  4061                              <1> 
  4062                              <1> WAITF:
  4063                              <1> waitf:
  4064                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4065                              <1> 	; 03/12/2013
  4066                              <1> 	;
  4067                              <1> ;	push ax			; save work register (ah)	
  4068                              <1> ;waitf1:
  4069                              <1> 				; use timer 1 output bits
  4070                              <1> ;	in	al, PORT_B	; read current counter output status
  4071                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  4072                              <1> ;	cmp	al, ah		; did it just change
  4073                              <1> ;	je	short waitf1	; wait for a change in output line
  4074                              <1> ;	;
  4075                              <1> ;	mov	ah, al		; save new lflag state
  4076                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  4077                              <1> ;	;
  4078                              <1> ;	pop	ax		; restore (ah)
  4079                              <1> ;	retn			; return (cx)=0
  4080                              <1> 
  4081                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  4082                              <1> ; 17/12/2014 (dsectrm2.s)
  4083                              <1> ; WAITF
  4084                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  4085                              <1> ;
  4086                              <1> ;---WAITF-----------------------------------------------------------------------
  4087                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  4088                              <1> ; ENTRY:
  4089                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  4090                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  4091                              <1> ; EXIT:
  4092                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  4093                              <1> ;	(CX) = 0	
  4094                              <1> ;-------------------------------------------------------------------------------
  4095                              <1> 
  4096                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  4097                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  4098                              <1> 
  4099                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  4100 000015E9 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  4101                              <1> 	; 16/12/2014
  4102                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  4103 000015EB D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  4104                              <1> ;17/12/2014	
  4105                              <1> ;WAITF1:
  4106                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  4107                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  4108                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  4109                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  4110                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  4111                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  4112                              <1> 	;
  4113                              <1> 	; 17/12/2014
  4114                              <1> 	;
  4115                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  4116                              <1> 	;
  4117                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  4118                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  4119                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  4120                              <1> WR_STATE_0:
  4121 000015ED E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4122 000015EF A810                <1> 	TEST	AL,010H
  4123 000015F1 74FA                <1> 	JZ	SHORT WR_STATE_0
  4124                              <1> WR_STATE_1:
  4125 000015F3 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4126 000015F5 A810                <1> 	TEST	AL,010H
  4127 000015F7 75FA                <1> 	JNZ	SHORT WR_STATE_1
  4128 000015F9 E2F2                <1>         LOOP    WR_STATE_0
  4129                              <1> 	;
  4130 000015FB 6658                <1> 	POP	AX			; RESTORE (AH)
  4131 000015FD C3                  <1> 	RETn				; (CX) = 0
  4132                              <1> 
  4133                              <1> set_cpos:
  4134                              <1> 	; 27/06/2015
  4135                              <1> 	; 01/09/2014
  4136                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  4137                              <1> 	;
  4138                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  4139                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  4140                              <1> 	;
  4141                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4142                              <1> 	;
  4143                              <1> 	; SET_CPOS
  4144                              <1> 	;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  4145                              <1> 	;	NEW X-Y VALUES PASSED
  4146                              <1> 	; INPUT
  4147                              <1> 	;	DX - ROW,COLUMN OF NEW CURSOR
  4148                              <1> 	;	BH - DISPLAY PAGE OF CURSOR
  4149                              <1> 	; OUTPUT
  4150                              <1> 	;	CURSOR IS SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  4151                              <1> 	;
  4152 000015FE 0FB6C3              <1>         movzx   eax, bl  ; BL = video page number ; 27/06/2015 (movzx)
  4153 00001601 D0E0                <1>         shl     al, 1   ; word offset
  4154 00001603 BE[96700000]        <1> 	mov	esi, cursor_posn
  4155 00001608 01C6                <1>         add     esi, eax
  4156 0000160A 668916              <1> 	mov	[esi], dx ; save the pointer
  4157 0000160D 381D[A6700000]      <1> 	cmp	[active_page], bl
  4158 00001613 7532                <1> 	jne	short m17
  4159                              <1> 	;call	m18	; CURSOR SET
  4160                              <1> ;m17:			; SET_CPOS_RETURN
  4161                              <1> 	; 01/09/2014
  4162                              <1> ;	retn
  4163                              <1> 		; DX  = row/column
  4164                              <1> m18:
  4165 00001615 E832000000          <1> 	call	position ; determine location in regen buffer	
  4166 0000161A 668B0D[94700000]    <1> 	mov	cx, [CRT_START]
  4167 00001621 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  4168                              <1> 			; to the start address (offset) for this page
  4169 00001624 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  4170 00001627 B40E                <1> 	mov	ah, 14	; register number for cursor
  4171                              <1> 	;call	m16	; output value to the 6845	
  4172                              <1> 	;retn
  4173                              <1> 
  4174                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  4175                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  4176                              <1> m16:
  4177 00001629 FA                  <1> 	cli
  4178                              <1> 	;mov	dx, [addr_6845] ; address register
  4179 0000162A 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  4180 0000162E 88E0                <1> 	mov	al, ah	; get value
  4181 00001630 EE                  <1> 	out	dx, al	; register set
  4182 00001631 6642                <1> 	inc	dx	; data register
  4183 00001633 EB00                <1> 	jmp	$+2	; i/o delay
  4184 00001635 88E8                <1> 	mov	al, ch	; data
  4185 00001637 EE                  <1> 	out	dx, al	
  4186 00001638 664A                <1> 	dec	dx	
  4187 0000163A 88E0                <1> 	mov	al, ah
  4188 0000163C FEC0                <1> 	inc	al	; point to other data register
  4189 0000163E EE                  <1> 	out	dx, al	; set for second register
  4190 0000163F 6642                <1> 	inc	dx
  4191 00001641 EB00                <1> 	jmp	$+2	; i/o delay
  4192 00001643 88C8                <1> 	mov	al, cl	; second data value
  4193 00001645 EE                  <1> 	out	dx, al
  4194 00001646 FB                  <1> 	sti
  4195                              <1> m17:
  4196 00001647 C3                  <1> 	retn
  4197                              <1> 
  4198                              <1> 
  4199                              <1> set_ctype:
  4200                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4201                              <1> 	;
  4202                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4203                              <1> 
  4204                              <1> ;	CH) = BITS 4-0 = START LINE FOR CURSOR
  4205                              <1> ;       ** HARDWARE WILL ALWAYS CAUSE BLINK
  4206                              <1> ;       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
  4207                              <1> ;          OR NO CURSOR AT ALL
  4208                              <1> ;	(CL) = BITS 4-0 = END LINE FOR CURSOR
  4209                              <1> 
  4210                              <1> ;------------------------------------------------
  4211                              <1> ; SET_CTYPE
  4212                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
  4213                              <1> ; INPUT
  4214                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
  4215                              <1> ; OUTPUT	
  4216                              <1> ;	NONE
  4217                              <1> ;------------------------------------------------
  4218                              <1> 
  4219 00001648 B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  4220                              <1> 	;mov	[CURSOR_MODE], cx ; save in data area
  4221                              <1> 	;call	m16	; output cx register
  4222                              <1> 	;retn
  4223 0000164A EBDD                <1> 	jmp	m16
  4224                              <1> 
  4225                              <1> 
  4226                              <1> position:
  4227                              <1> 	; 27/06/2015
  4228                              <1> 	; 02/09/2014
  4229                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4230                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
  4231                              <1> 	;
  4232                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4233                              <1> 	;
  4234                              <1> 	; POSITION
  4235                              <1> 	;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
  4236                              <1> 	;	OF A CHARACTER IN THE ALPHA MODE
  4237                              <1> 	; INPUT
  4238                              <1> 	;	AX = ROW, COLUMN POSITION
  4239                              <1> 	; OUTPUT
  4240                              <1> 	;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
  4241                              <1> 
  4242                              <1> 		; DX = ROW, COLUMN POSITION
  4243                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
  4244 0000164C 31C0                <1> 	xor	eax, eax ; 02/09/2014
  4245 0000164E B050                <1> 	mov	al, 80   ; determine bytes to row	
  4246 00001650 F6E6                <1> 	mul	dh ;	 row value
  4247 00001652 30F6                <1> 	xor	dh, dh   ; 0	
  4248 00001654 6601D0              <1> 	add	ax, dx	 ; add column value to the result
  4249 00001657 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
  4250                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
  4251 0000165A C3                  <1> 	retn
  4252                              <1> 
  4253                              <1> find_position:
  4254                              <1> 	; 27/06/2015
  4255                              <1> 	; 07/09/2014
  4256                              <1> 	; 02/09/2014
  4257                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4258                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4259 0000165B 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
  4260 0000165E 89CE                <1> 	mov	esi, ecx
  4261 00001660 66D1E6              <1> 	shl	si, 1
  4262 00001663 668B96[96700000]    <1> 	mov	dx, [esi + cursor_posn]
  4263 0000166A 740A                <1> 	jz	short p21
  4264 0000166C 6631F6              <1> 	xor	si, si
  4265                              <1> p20:
  4266                              <1> 	;add	si, [CRT_LEN]
  4267 0000166F 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
  4268 00001674 E2F9                <1> 	loop	p20
  4269                              <1> p21:
  4270 00001676 6621D2              <1> 	and	dx, dx
  4271 00001679 7407                <1> 	jz	short p22
  4272 0000167B E8CCFFFFFF          <1> 	call 	position ; determine location in regen in page
  4273 00001680 01C6                <1> 	add	esi, eax ; add location to start of regen page
  4274                              <1> p22:	
  4275                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
  4276                              <1> 	;mov	dx, 03D4h ; I/O address of color card
  4277                              <1> 	;add	dx, 6	; point at status port
  4278 00001682 66BADA03            <1> 	mov	dx, 03DAh ; status port
  4279                              <1> 	; cx = 0
  4280 00001686 C3                  <1> 	retn
  4281                              <1> 
  4282                              <1> scroll_up:
  4283                              <1> 	; 16/01/2016
  4284                              <1> 	; 07/09/2014
  4285                              <1> 	; 02/09/2014
  4286                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
  4287                              <1> 	; 04/04/2014
  4288                              <1> 	; 04/12/2013
  4289                              <1> 	;
  4290                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4291                              <1> 	;
  4292                              <1> 	; SCROLL UP
  4293                              <1> 	;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
  4294                              <1> 	;	ON THE SCREEN
  4295                              <1> 	; INPUT
  4296                              <1> 	;	(AH) = CURRENT CRT MODE
  4297                              <1> 	;	(AL) = NUMBER OF ROWS TO SCROLL
  4298                              <1> 	;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
  4299                              <1> 	;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
  4300                              <1> 	;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
  4301                              <1> 	;	(DS) = DATA SEGMENT
  4302                              <1> 	;	(ES) = REGEN BUFFER SEGMENT
  4303                              <1> 	; OUTPUT
  4304                              <1> 	;	NONE -- THE REGEN BUFFER IS MODIFIED
  4305                              <1> 	;
  4306                              <1> 	;	bh = 0  (02/09/2014)
  4307                              <1> 	;
  4308                              <1> 	; ((ah = 3))
  4309                              <1> 	; cl = left upper column
  4310                              <1> 	; ch = left upper row
  4311                              <1> 	; dl = right lower column
  4312                              <1> 	; dh = right lower row
  4313                              <1> 	;
  4314                              <1> 	; al = line count 
  4315                              <1> 	; ah = attribute to be used on blanked line	
  4316                              <1> 	; bl = video page number (0 to 7)
  4317                              <1> 	; 
  4318                              <1> 
  4319                              <1> 	; Test	Line Count
  4320 00001687 08C0                <1> 	or	al, al
  4321 00001689 740C                <1> 	jz	short al_set
  4322 0000168B 88F7                <1> 	mov	bh, dh	; subtract lower row from upper row
  4323 0000168D 28EF                <1> 	sub	bh, ch
  4324 0000168F FEC7                <1> 	inc	bh	; adjust difference by 1
  4325 00001691 38C7                <1> 	cmp	bh, al 	; line count = amount of rows in window?
  4326 00001693 7502                <1> 	jne	short al_set ; if not the we're all set
  4327 00001695 30C0                <1> 	xor	al, al	; otherwise set al to zero
  4328                              <1> al_set:
  4329 00001697 30FF                <1> 	xor	bh, bh	; 0
  4330 00001699 6650                <1> 	push	ax
  4331                              <1> 	;mov 	esi, [crt_base]
  4332 0000169B BE00800B00          <1>         mov     esi, 0B8000h  
  4333 000016A0 3A1D[A6700000]      <1>         cmp     bl, [active_page]
  4334 000016A6 750B                <1> 	jne	short n0
  4335                              <1> 	;
  4336 000016A8 66A1[94700000]      <1>         mov     ax, [CRT_START]
  4337 000016AE 6601C6              <1>         add     si, ax
  4338 000016B1 EB0F                <1>         jmp     short n1
  4339                              <1> n0:
  4340 000016B3 20DB                <1>         and     bl, bl
  4341 000016B5 740B                <1> 	jz	short n1
  4342 000016B7 88D8                <1> 	mov	al, bl
  4343                              <1> n0x:
  4344                              <1>         ;add    si, [CRT_LEN]
  4345                              <1>         ;add    esi, 80*25*2 
  4346 000016B9 6681C6A00F          <1>         add     si, 80*25*2
  4347 000016BE FEC8                <1>         dec	al
  4348 000016C0 75F7                <1> 	jnz	short n0x
  4349                              <1> n1:	
  4350                              <1>         ;Scroll position
  4351 000016C2 6652                <1> 	push	dx
  4352 000016C4 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
  4353 000016C7 E880FFFFFF          <1> 	call	position
  4354 000016CC 01C6                <1> 	add	esi, eax
  4355 000016CE 89F7                <1> 	mov	edi, esi
  4356 000016D0 665A                <1> 	pop	dx	; lower right position in DX
  4357 000016D2 6629CA              <1> 	sub	dx, cx
  4358 000016D5 FEC6                <1> 	inc	dh	; dh = #rows 
  4359 000016D7 FEC2                <1> 	inc	dl	; dl = #cols in block
  4360 000016D9 6658                <1> 	pop	ax	; al = line count, ah = attribute
  4361 000016DB 31C9                <1> 	xor	ecx, ecx
  4362 000016DD 6689C1              <1> 	mov	cx, ax
  4363                              <1> 	;mov	ah, [CRT_COLS]
  4364 000016E0 B450                <1> 	mov	ah, 80
  4365 000016E2 F6E4                <1> 	mul	ah	; determine offset to from address
  4366 000016E4 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
  4367                              <1> 	;
  4368 000016E7 6650                <1> 	push	ax	; offset 
  4369 000016E9 6652                <1> 	push	dx
  4370                              <1> 	;
  4371                              <1> 	; 04/04/2014
  4372 000016EB 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
  4373                              <1> n8:                      ; wait_display_enable
  4374 000016EF EC                  <1>         in      al, dx   ; get port
  4375 000016F0 A808                <1> 	test	al, RVRT ; wait for vertical retrace	
  4376 000016F2 74FB                <1> 	jz	short n8 ; wait_display_enable
  4377 000016F4 B025                <1> 	mov	al, 25h
  4378 000016F6 B2D8                <1> 	mov	dl, 0D8h ; address control port
  4379 000016F8 EE                  <1> 	out	dx, al	; turn off video during vertical retrace
  4380 000016F9 665A                <1> 	pop	dx	; #rows, #cols
  4381 000016FB 6658                <1>        	pop	ax	; offset
  4382 000016FD 6691                <1> 	xchg	ax, cx	; 
  4383                              <1> 	; ecx = offset, al = line count, ah = attribute
  4384                              <1> ;n9:
  4385 000016FF 08C0                <1> 	or	al, al
  4386 00001701 7420                <1>         jz      short n3 
  4387 00001703 01CE                <1>         add     esi, ecx ; from address for scroll
  4388 00001705 88F7                <1> 	mov	bh, dh  ; #rows in block
  4389 00001707 28C7                <1> 	sub	bh, al	; #rows to be moved
  4390                              <1> n2:
  4391                              <1> 	; Move rows
  4392 00001709 88D1                <1> 	mov	cl, dl	; get # of cols to move
  4393 0000170B 56                  <1> 	push	esi
  4394 0000170C 57                  <1> 	push	edi	; save start address
  4395                              <1> n10:
  4396 0000170D 66A5                <1> 	movsw		; move that line on screen
  4397 0000170F FEC9                <1> 	dec	cl
  4398 00001711 75FA                <1>         jnz     short n10
  4399 00001713 5F                  <1> 	pop	edi
  4400 00001714 5E                  <1> 	pop	esi	; recover addresses
  4401                              <1>         ;mov    cl, [CRT_COLS] 
  4402                              <1> 	;add	cl, cl
  4403                              <1>         ;mov    ecx, 80*2
  4404 00001715 66B9A000            <1>         mov     cx, 80*2
  4405 00001719 01CE                <1>         add     esi, ecx  ; next line
  4406 0000171B 01CF                <1>         add     edi, ecx
  4407 0000171D FECF                <1> 	dec	bh	 ; count of lines to move
  4408 0000171F 75E8                <1> 	jnz	short n2 ; row loop
  4409                              <1> 	; bh = 0
  4410 00001721 88C6                <1> 	mov	dh, al	 ; #rows	
  4411                              <1> n3:
  4412                              <1> 	; attribute in ah
  4413 00001723 B020                <1> 	mov	al, ' '	 ; fill with blanks
  4414                              <1> n3x:
  4415                              <1> 	; Clear rows
  4416                              <1>                 ; dh =  #rows
  4417 00001725 88D1                <1>         mov	cl, dl	; get # of cols to clear
  4418 00001727 57                  <1>         push    edi     ; save address
  4419                              <1> n11:
  4420 00001728 66AB                <1>         stosw           ; store fill character
  4421 0000172A FEC9                <1> 	dec	cl
  4422 0000172C 75FA                <1>         jnz     short n11
  4423 0000172E 5F                  <1>         pop     edi     ; recover address
  4424                              <1> 	;mov	cl, [CRT_COLS]
  4425                              <1> 	;add	cl, cl
  4426                              <1>         ;mov    ecx, 80*2
  4427 0000172F B1A0                <1>         mov	cl, 80*2
  4428 00001731 01CF                <1>         add     edi, ecx
  4429 00001733 FECE                <1> 	dec	dh
  4430 00001735 75EE                <1> 	jnz	short n3x ; 16/01/2016
  4431                              <1> 	;
  4432 00001737 3A1D[A6700000]      <1> 	cmp	bl, [active_page]
  4433 0000173D 7507                <1> 	jne	short n6
  4434                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
  4435 0000173F B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
  4436 00001741 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
  4437 00001745 EE                  <1> 	out	dx, al
  4438                              <1> n6:
  4439 00001746 C3                  <1> 	retn
  4440                              <1> 
  4441                              <1> 
  4442                              <1> write_c_current:
  4443                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4444                              <1> 	; 18/01/2014
  4445                              <1> 	; 04/12/2013
  4446                              <1> 	;
  4447                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4448                              <1> 	;
  4449                              <1> 	; WRITE_C_CURRENT
  4450                              <1> 	;	THIS ROUTINE WRITES THE CHARACTER AT
  4451                              <1> 	;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED
  4452                              <1> 	; INPUT	
  4453                              <1> 	;	(AH) = CURRENT CRT MODE
  4454                              <1> 	;	(BH) = DISPLAY PAGE
  4455                              <1> 	;	(CX) = COUNT OF CHARACTERS TO WRITE
  4456                              <1> 	;	(AL) = CHAR TO WRITE
  4457                              <1> 	;	(DS) = DATA SEGMENT
  4458                              <1> 	;	(ES) = REGEN SEGMENT
  4459                              <1> 	; OUTPUT
  4460                              <1> 	;	DISPLAY REGEN BUFFER UPDATED
  4461                              <1> 
  4462 00001747 FA                  <1> 	cli		
  4463                              <1> 	; bl = video page
  4464                              <1> 	; al = character
  4465                              <1> 	; ah = color/attribute
  4466 00001748 6652                <1> 	push	dx
  4467 0000174A 6650                <1> 	push	ax	; save character & attribute/color
  4468 0000174C E80AFFFFFF          <1> 	call 	find_position  ; get regen location and port address
  4469                              <1> 	; esi = regen location
  4470                              <1> 	; dx = status port
  4471                              <1> 	;
  4472                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  4473                              <1> 	;
  4474                              <1> p41:			; wait for horizontal retrace is low or vertical
  4475 00001751 FB                  <1> 	sti		; enable interrupts first
  4476 00001752 3A1D[A6700000]      <1>         cmp     bl, [active_page]
  4477 00001758 7510                <1> 	jne	short p44 
  4478 0000175A FA                  <1> 	cli 		; block interrupts for single loop
  4479 0000175B EC                  <1> 	in	al, dx	; get status from the adapter
  4480 0000175C A808                <1> 	test	al, RVRT ; check for vertical retrace first
  4481 0000175E 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  4482 00001760 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  4483 00001762 75ED                <1> 	jnz	short p41 ; wait until it is
  4484                              <1> p42:			;  wait for either retrace high
  4485 00001764 EC                  <1> 	in	al, dx ; get status again
  4486 00001765 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  4487 00001767 74FB                <1> 	jz	short p42 ; wait until either retrace active
  4488                              <1> p43:	
  4489 00001769 FB                  <1> 	sti
  4490                              <1> p44:
  4491 0000176A 6658                <1> 	pop	ax	; restore the character (al) & attribute (ah)
  4492 0000176C 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  4493                              <1> 				; Retro UNIX 386 v1 feature only!
  4494 00001772 668906              <1> 	mov	[esi], ax
  4495 00001775 665A                <1> 	pop	dx
  4496 00001777 C3                  <1> 	retn
  4497                              <1> 
  4498                              <1> set_mode:
  4499                              <1> 	; 16/01/2016
  4500                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4501                              <1> 	;
  4502                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4503                              <1> 
  4504                              <1> ;------------------------------------------------------
  4505                              <1> ; SET MODE					      :
  4506                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
  4507                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
  4508                              <1> ; INPUT						      :
  4509                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
  4510                              <1> ; OUTPUT					      :
  4511                              <1> ;	NONE					      :
  4512                              <1> ;------------------------------------------------------
  4513                              <1> 
  4514 00001778 57                  <1> 	push	edi ; 16/01/2016
  4515 00001779 53                  <1> 	push	ebx
  4516 0000177A 52                  <1> 	push	edx
  4517 0000177B 51                  <1> 	push	ecx ; 16/01/2016
  4518 0000177C 50                  <1>         push    eax
  4519                              <1> 
  4520                              <1> 	;mov	dx, 03D4h 	; address or color card
  4521 0000177D B003                <1> 	mov	al, 3
  4522                              <1> ;M8:
  4523 0000177F A2[606A0000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
  4524 00001784 B029                <1> 	mov	al, 29h
  4525                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
  4526 00001786 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
  4527                              <1> 	;push	dx  		; save port value
  4528                              <1> 	;add	dx, 4		; point to control register
  4529 00001788 66BAD803            <1> 	mov	dx, 3D8h
  4530 0000178C EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
  4531                              <1> 	;pop	dx
  4532                              <1> ;M9:
  4533 0000178D BB[986A0000]        <1> 	mov	ebx, video_params ; initialization table
  4534                              <1> 	;mov	ax, [ebx+10]      ; get the cursor mode from the table	
  4535                              <1> 	;xchg 	ah, al
  4536                              <1> 	;mov	[CURSOR_MODE], ax ; save cursor mode
  4537 00001792 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
  4538                              <1> 	
  4539                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
  4540 00001794 B910000000          <1> 	mov	ecx, 16 ; 16/01/2016
  4541                              <1> M10:			;  initialization loop
  4542 00001799 88E0                <1> 	mov	al, ah 	; get 6845 register number
  4543 0000179B EE                  <1> 	out	dx, al
  4544 0000179C 6642                <1> 	inc	dx      ; point to data port
  4545 0000179E FEC4                <1> 	inc	ah	; next register value
  4546 000017A0 8A03                <1> 	mov	al, [ebx] ; get table value
  4547 000017A2 EE                  <1> 	out	dx, al	; out to chip
  4548 000017A3 43                  <1> 	inc	ebx	; next in table
  4549 000017A4 664A                <1> 	dec	dx	; back to pointer register
  4550 000017A6 E2F1                <1> 	loop	M10	; do the whole table
  4551                              <1> 	
  4552                              <1> ;-----	FILL REGEN AREA WITH BLANK
  4553                              <1> 	;xor	ax, ax  
  4554                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
  4555                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
  4556                              <1> 	;mov	ecx, 8192 ; number of words in color card
  4557                              <1> 	; black background, light gray characeter color, space character
  4558                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
  4559                              <1> ;M13:			  ; clear buffer
  4560                              <1> 	;add	edi, 0B8000h ; [crt_base]
  4561                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
  4562                              <1> 
  4563                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
  4564                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
  4565                              <1> 			 ; prepare to output to video enable port
  4566                              <1> 	;add	dx,4	 ; point to the mode control gerister
  4567 000017A8 66BAD803            <1> 	mov	dx, 3D8h
  4568                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
  4569 000017AC B029                <1> 	mov	al, 29h
  4570 000017AE EE                  <1> 	out	dx, al	 ; set video enable port
  4571                              <1> 
  4572                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
  4573                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
  4574                              <1> 	;
  4575                              <1> 	;mov byte [CRT_COLS], 80h ; initialize number of columns count
  4576                              <1> 	;
  4577                              <1> ;-----	SET CURSOR POSITIONS
  4578                              <1> 	;push	edi
  4579                              <1> 	;mov	word [CRT_LEN], 80*25*2
  4580 000017AF BF[96700000]        <1> 	mov	edi, cursor_posn
  4581 000017B4 B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
  4582 000017B9 31C0                <1> 	xor	eax, eax
  4583 000017BB F3AB                <1> 	rep 	stosd	; fill with zeroes
  4584                              <1> 	;pop	edi
  4585                              <1> 
  4586                              <1> ;-----	SET UP OVERSCAN REGISTER
  4587 000017BD 6642                <1> 	inc	dx	; set overscan port to a default
  4588 000017BF B030                <1> 	mov	al, 30h	; 30H valuye for all modes except 640X200 bw
  4589                              <1> ;M14:
  4590 000017C1 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
  4591                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
  4592                              <1> 
  4593                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  4594                              <1> 	;
  4595 000017C2 58                  <1> 	pop	eax
  4596 000017C3 59                  <1> 	pop	ecx ; 16/01/2016
  4597 000017C4 5A                  <1> 	pop	edx
  4598 000017C5 5B                  <1> 	pop	ebx
  4599 000017C6 5F                  <1> 	pop	edi ; 16/01/2016
  4600 000017C7 C3                  <1> 	retn
  4601                              <1> 	
  4602                              <1> tty_sw:
  4603                              <1> 	; 30/06/2015
  4604                              <1> 	; 27/06/2015 
  4605                              <1> 	; 07/09/2014
  4606                              <1> 	; 02/09/2014 (Retro UNIX 386 v1 - beginning)
  4607                              <1> 	;
  4608                              <1> 	; (Modified registers : EAX)
  4609                              <1> 	;
  4610                              <1>         ;mov     byte [u.quant], 0  ; 04/03/2014
  4611                              <1> 	;
  4612                              <1> ;act_disp_page:
  4613                              <1> 	; 30/06/2015
  4614                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
  4615                              <1> 	; 10/12/2013
  4616                              <1> 	; 04/12/2013
  4617                              <1> 	;
  4618                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4619                              <1> 	;
  4620                              <1> 	; ACT_DISP_PAGE
  4621                              <1> 	;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
  4622                              <1> 	;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
  4623                              <1> 	; INPUT
  4624                              <1> 	;	AL HAS THE NEW ACTIVE DISPLAY PAGE
  4625                              <1> 	; OUTPUT
  4626                              <1> 	;	THE 6845 IS RESET TO DISPLAY THAT PAGE
  4627                              <1> 
  4628                              <1> 	;cli
  4629                              <1> 
  4630 000017C8 53                  <1> 	push	ebx
  4631 000017C9 6651                <1> 	push	cx
  4632 000017CB 6652                <1> 	push	dx
  4633                              <1> 	;
  4634 000017CD A2[A6700000]        <1> 	mov	[active_page], al ; save active page value ; [ptty]
  4635                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
  4636 000017D2 66B9A00F            <1> 	mov	cx, 25*80*2
  4637                              <1> 	; 27/06/2015
  4638 000017D6 0FB6D8              <1> 	movzx	ebx, al
  4639                              <1> 	;
  4640 000017D9 6698                <1> 	cbw	; 07/09/2014 (ah=0)
  4641 000017DB 66F7E1              <1> 	mul 	cx	; display page times regen length
  4642                              <1> 	; 10/12/2013
  4643 000017DE 66A3[94700000]      <1> 	mov	[CRT_START], ax ; save start address for later
  4644 000017E4 6689C1              <1> 	mov	cx, ax ; start address to cx
  4645                              <1> 	;sar	cx, 1
  4646 000017E7 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
  4647 000017EA B40C                <1> 	mov	ah, 12	; 6845 register for start address
  4648 000017EC E838FEFFFF          <1> 	call	m16
  4649                              <1> 	;sal	bx, 1
  4650                              <1> 	; 01/09/2014
  4651 000017F1 D0E3                <1> 	shl	bl, 1	; *2 for word offset
  4652 000017F3 81C3[96700000]      <1> 	add	ebx, cursor_posn
  4653 000017F9 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
  4654 000017FC E814FEFFFF          <1> 	call	m18
  4655                              <1> 	;
  4656 00001801 665A                <1> 	pop	dx
  4657 00001803 6659                <1> 	pop	cx
  4658 00001805 5B                  <1> 	pop	ebx
  4659                              <1> 	;
  4660                              <1> 	;sti
  4661                              <1> 	;
  4662 00001806 C3                  <1> 	retn
  4663                              <1> 
  4664                              <1> ; % include 'vidata.inc' ; VIDEO DATA ; 11/03/2015
  4665                              <1> 
  4666                              <1> 
  4667                              <1> ; /// End Of VIDEO FUNCTIONS ///
  4668                                  
  4669                                  setup_rtc_int:
  4670                                  ; source: http://wiki.osdev.org/RTC
  4671 00001807 FA                      	cli		; disable interrupts
  4672                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  4673                                  	; in order to change this ...
  4674                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  4675                                  	; (rate must be above 2 and not over 15)
  4676                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  4677 00001808 B08A                    	mov	al, 8Ah 
  4678 0000180A E670                    	out	70h, al ; set index to register A, disable NMI
  4679 0000180C 90                      	nop
  4680 0000180D E471                    	in	al, 71h ; get initial value of register A
  4681 0000180F 88C4                    	mov 	ah, al
  4682 00001811 80E4F0                  	and	ah, 0F0h
  4683 00001814 B08A                    	mov	al, 8Ah 
  4684 00001816 E670                    	out	70h, al ; reset index to register A
  4685 00001818 88E0                    	mov	al, ah
  4686 0000181A 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  4687 0000181C E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  4688                                  	; enable RTC interrupt
  4689 0000181E B08B                    	mov	al, 8Bh ;
  4690 00001820 E670                    	out	70h, al ; select register B and disable NMI
  4691 00001822 90                      	nop
  4692 00001823 E471                    	in	al, 71h ; read the current value of register B
  4693 00001825 88C4                    	mov	ah, al  ;
  4694 00001827 B08B                    	mov 	al, 8Bh ;
  4695 00001829 E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  4696 0000182B 88E0                    	mov	al, ah  ;
  4697 0000182D 0C40                    	or	al, 40h ;
  4698 0000182F E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  4699 00001831 FB                      	sti
  4700 00001832 C3                      	retn
  4701                                  
  4702                                  ; Write memory information
  4703                                  ; Temporary Code
  4704                                  ; 06/11/2014
  4705                                  ; 14/08/2015 
  4706                                  memory_info:	
  4707 00001833 A1[7C700000]            	mov	eax, [memory_size] ; in pages
  4708 00001838 50                      	push	eax
  4709 00001839 C1E00C                  	shl	eax, 12		   ; in bytes
  4710 0000183C BB0A000000              	mov	ebx, 10
  4711 00001841 89D9                    	mov	ecx, ebx	   ; 10
  4712 00001843 BE[DB6C0000]            	mov	esi, mem_total_b_str	
  4713 00001848 E8B2000000              	call	bintdstr
  4714 0000184D 58                      	pop	eax
  4715 0000184E B107                    	mov	cl, 7
  4716 00001850 BE[FF6C0000]            	mov	esi, mem_total_p_str
  4717 00001855 E8A5000000              	call	bintdstr	
  4718                                  	; 14/08/2015
  4719 0000185A E8BD000000              	call	calc_free_mem
  4720                                  	; edx = calculated free pages
  4721                                  	; ecx = 0
  4722 0000185F A1[80700000]            	mov 	eax, [free_pages]
  4723 00001864 39D0                    	cmp	eax, edx ; calculated free mem value 
  4724                                  		; and initial free mem value are same or not?
  4725 00001866 751D                    	jne 	short pmim ; print mem info with '?' if not
  4726 00001868 52                      	push 	edx ; free memory in pages	
  4727                                  	;mov 	eax, edx
  4728 00001869 C1E00C                  	shl	eax, 12 ; convert page count
  4729                                  			; to byte count
  4730 0000186C B10A                    	mov	cl, 10
  4731 0000186E BE[1F6D0000]            	mov	esi, free_mem_b_str
  4732 00001873 E887000000              	call	bintdstr
  4733 00001878 58                      	pop	eax
  4734 00001879 B107                    	mov	cl, 7
  4735 0000187B BE[436D0000]            	mov	esi, free_mem_p_str
  4736 00001880 E87A000000              	call	bintdstr
  4737                                  pmim:
  4738 00001885 BE[C96C0000]            	mov	esi, msg_memory_info
  4739                                  pmim_nb:	
  4740 0000188A AC                      	lodsb
  4741 0000188B 08C0                    	or	al, al
  4742 0000188D 740D                    	jz	short pmim_ok
  4743 0000188F 56                      	push	esi
  4744 00001890 31DB                    	xor	ebx, ebx ; 0
  4745                                  			; Video page 0 (bl=0)
  4746 00001892 B407                    	mov	ah, 07h ; Black background, 
  4747                                  			; light gray forecolor
  4748 00001894 E841FCFFFF              	call	write_tty
  4749 00001899 5E                      	pop	esi
  4750 0000189A EBEE                    	jmp	short pmim_nb
  4751                                  pmim_ok:
  4752 0000189C C3                      	retn
  4753                                  
  4754                                  ; Convert binary number to hexadecimal string
  4755                                  ; 10/05/2015  
  4756                                  ; dsectpm.s (28/02/2015)
  4757                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  4758                                  ; 01/12/2014
  4759                                  ; 25/11/2014
  4760                                  ;
  4761                                  bytetohex:
  4762                                  	; INPUT ->
  4763                                  	; 	AL = byte (binary number)
  4764                                  	; OUTPUT ->
  4765                                  	;	AX = hexadecimal string
  4766                                  	;
  4767 0000189D 53                      	push	ebx
  4768 0000189E 31DB                    	xor	ebx, ebx
  4769 000018A0 88C3                    	mov	bl, al
  4770 000018A2 C0EB04                  	shr	bl, 4
  4771 000018A5 8A9B[EF180000]          	mov	bl, [ebx+hexchrs] 	 	
  4772 000018AB 86D8                    	xchg	bl, al
  4773 000018AD 80E30F                  	and	bl, 0Fh
  4774 000018B0 8AA3[EF180000]          	mov	ah, [ebx+hexchrs] 
  4775 000018B6 5B                      	pop	ebx	
  4776 000018B7 C3                      	retn
  4777                                  
  4778                                  wordtohex:
  4779                                  	; INPUT ->
  4780                                  	; 	AX = word (binary number)
  4781                                  	; OUTPUT ->
  4782                                  	;	EAX = hexadecimal string
  4783                                  	;
  4784 000018B8 53                      	push	ebx
  4785 000018B9 31DB                    	xor	ebx, ebx
  4786 000018BB 86E0                    	xchg	ah, al
  4787 000018BD 6650                    	push	ax
  4788 000018BF 88E3                    	mov	bl, ah
  4789 000018C1 C0EB04                  	shr	bl, 4
  4790 000018C4 8A83[EF180000]          	mov	al, [ebx+hexchrs] 	 	
  4791 000018CA 88E3                    	mov	bl, ah
  4792 000018CC 80E30F                  	and	bl, 0Fh
  4793 000018CF 8AA3[EF180000]          	mov	ah, [ebx+hexchrs]
  4794 000018D5 C1E010                  	shl	eax, 16
  4795 000018D8 6658                    	pop	ax
  4796 000018DA 5B                      	pop	ebx
  4797 000018DB EBC0                    	jmp	short bytetohex
  4798                                  	;mov	bl, al
  4799                                  	;shr	bl, 4
  4800                                  	;mov	bl, [ebx+hexchrs] 	 	
  4801                                  	;xchg	bl, al	 	
  4802                                  	;and	bl, 0Fh
  4803                                  	;mov	ah, [ebx+hexchrs] 
  4804                                  	;pop	ebx	
  4805                                  	;retn
  4806                                  
  4807                                  dwordtohex:
  4808                                  	; INPUT ->
  4809                                  	; 	EAX = dword (binary number)
  4810                                  	; OUTPUT ->
  4811                                  	;	EDX:EAX = hexadecimal string
  4812                                  	;
  4813 000018DD 50                      	push	eax
  4814 000018DE C1E810                  	shr	eax, 16
  4815 000018E1 E8D2FFFFFF              	call	wordtohex
  4816 000018E6 89C2                    	mov	edx, eax
  4817 000018E8 58                      	pop	eax
  4818 000018E9 E8CAFFFFFF              	call	wordtohex
  4819 000018EE C3                      	retn
  4820                                  
  4821                                  ; 10/05/2015
  4822                                  hex_digits:
  4823                                  hexchrs:
  4824 000018EF 303132333435363738-     	db '0123456789ABCDEF'
  4825 000018F8 39414243444546     
  4826                                  
  4827                                  ; Convert binary number to decimal/numeric string
  4828                                  ; 06/11/2014
  4829                                  ; Temporary Code
  4830                                  ;
  4831                                  
  4832                                  bintdstr:
  4833                                  	; EAX = binary number
  4834                                  	; ESI = decimal/numeric string address
  4835                                  	; EBX = divisor (10)
  4836                                  	; ECX = string length (<=10)
  4837 000018FF 01CE                    	add	esi, ecx
  4838                                  btdstr0:
  4839 00001901 4E                      	dec	esi
  4840 00001902 31D2                    	xor	edx, edx
  4841 00001904 F7F3                    	div	ebx
  4842 00001906 80C230                  	add	dl, 30h
  4843 00001909 8816                    	mov	[esi], dl
  4844 0000190B FEC9                    	dec	cl
  4845 0000190D 740C                    	jz	btdstr2
  4846 0000190F 09C0                    	or	eax, eax
  4847 00001911 75EE                    	jnz	short btdstr0
  4848                                  btdstr1:
  4849 00001913 4E                      	dec	esi
  4850 00001914 C60620                          mov     byte [esi], 20h ; blank space
  4851 00001917 FEC9                    	dec	cl
  4852 00001919 75F8                    	jnz	short btdstr1
  4853                                  btdstr2:
  4854 0000191B C3                      	retn
  4855                                  
  4856                                  ; Calculate free memory pages on M.A.T.
  4857                                  ; 06/11/2014
  4858                                  ; Temporary Code
  4859                                  ;
  4860                                  
  4861                                  calc_free_mem:
  4862 0000191C 31D2                    	xor	edx, edx
  4863                                  	;xor	ecx, ecx
  4864 0000191E 668B0D[90700000]        	mov	cx, [mat_size] ; in pages
  4865 00001925 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  4866 00001928 BE00001000              	mov	esi, MEM_ALLOC_TBL
  4867                                  cfm0:
  4868 0000192D AD                      	lodsd
  4869 0000192E 51                      	push	ecx
  4870 0000192F B920000000              	mov	ecx, 32
  4871                                  cfm1:
  4872 00001934 D1E8                    	shr	eax, 1
  4873 00001936 7301                    	jnc	short cfm2
  4874 00001938 42                      	inc	edx
  4875                                  cfm2:
  4876 00001939 E2F9                    	loop	cfm1
  4877 0000193B 59                      	pop	ecx
  4878 0000193C E2EF                    	loop	cfm0
  4879 0000193E C3                      	retn
  4880                                  
  4881                                  %include 'diskio.inc'  ; 07/03/2015
  4882                              <1> ; Retro UNIX 386 v1 Kernel - DISKIO.INC
  4883                              <1> ; Last Modification: 04/02/2016
  4884                              <1> ; 	(Initialized Disk Parameters Data is in 'DISKDATA.INC') 
  4885                              <1> ; 	(Uninitialized Disk Parameters Data is in 'DISKBSS.INC') 
  4886                              <1> 
  4887                              <1> ; DISK I/O SYSTEM - Erdogan Tan (Retro UNIX 386 v1 project)
  4888                              <1> 
  4889                              <1> ; ///////// DISK I/O SYSTEM ///////////////
  4890                              <1> 
  4891                              <1> ; 06/02/2015
  4892                              <1> diskette_io:
  4893 0000193F 9C                  <1> 	pushfd
  4894 00001940 0E                  <1> 	push 	cs
  4895 00001941 E809000000          <1> 	call 	DISKETTE_IO_1
  4896 00001946 C3                  <1> 	retn
  4897                              <1> 	
  4898                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
  4899                              <1> ;//////////////////////////////////////////////////////
  4900                              <1> 
  4901                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  4902                              <1> ; 20/02/2015
  4903                              <1> ; 06/02/2015 (unix386.s)
  4904                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
  4905                              <1> ;
  4906                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
  4907                              <1> ;
  4908                              <1> ; ADISK.EQU
  4909                              <1> 
  4910                              <1> ;----- Wait control constants 
  4911                              <1> 
  4912                              <1> ;amount of time to wait while RESET is active.
  4913                              <1> 
  4914                              <1> WAITCPU_RESET_ON	EQU	21		;Reset on must last at least 14us
  4915                              <1> 						;at 250 KBS xfer rate.
  4916                              <1> 						;see INTEL MCS, 1985, pg. 5-456
  4917                              <1> 
  4918                              <1> WAITCPU_FOR_STATUS	EQU	100		;allow 30 microseconds for
  4919                              <1> 						;status register to become valid
  4920                              <1> 						;before re-reading.
  4921                              <1> 
  4922                              <1> ;After sending a byte to NEC, status register may remain
  4923                              <1> ;incorrectly set for 24 us.
  4924                              <1> 
  4925                              <1> WAITCPU_RQM_LOW		EQU	24		;number of loops to check for
  4926                              <1> 						;RQM low.
  4927                              <1> 
  4928                              <1> ; COMMON.MAC
  4929                              <1> ;
  4930                              <1> ;	Timing macros
  4931                              <1> ;
  4932                              <1> 
  4933                              <1> %macro 		SIODELAY 0 			; SHORT IODELAY
  4934                              <1> 		jmp short $+2
  4935                              <1> %endmacro		
  4936                              <1> 
  4937                              <1> %macro		IODELAY  0			; NORMAL IODELAY
  4938                              <1> 		jmp short $+2
  4939                              <1> 		jmp short $+2
  4940                              <1> %endmacro
  4941                              <1> 
  4942                              <1> %macro		NEWIODELAY 0
  4943                              <1> 		out	0ebh,al
  4944                              <1> %endmacro 
  4945                              <1> 
  4946                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
  4947                              <1> ;;; WAIT_FOR_MEM
  4948                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
  4949                              <1> ;WAIT_FDU_INT_HI	equ	1
  4950                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
  4951                              <1> ;;; WAIT_FOR_PORT
  4952                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
  4953                              <1> ;WAIT_FDU_SEND_HI	equ	0
  4954                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
  4955                              <1> ;Time to wait while waiting for each byte of NEC results = .5
  4956                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  4957                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
  4958                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
  4959                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
  4960                              <1> ;;; WAIT_REFRESH
  4961                              <1> ;amount of time to wait for head settle, per unit in parameter
  4962                              <1> ;table = 1 ms.
  4963                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
  4964                              <1> 
  4965                              <1> 
  4966                              <1> ; //////////////// DISKETTE I/O ////////////////
  4967                              <1> 
  4968                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
  4969                              <1> 
  4970                              <1> ;----------------------------------------
  4971                              <1> ;	EQUATES USED BY POST AND BIOS	:
  4972                              <1> ;----------------------------------------
  4973                              <1> 
  4974                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  4975                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  4976                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  4977                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
  4978                              <1> 
  4979                              <1> ;----------------------------------------
  4980                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
  4981                              <1> ;-------------------------------------------------------------------------------
  4982                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
  4983                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
  4984                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
  4985                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
  4986                              <1> 
  4987                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
  4988                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
  4989                              <1> ;		EQU	011H		; - RESERVED			      ;C
  4990                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
  4991                              <1> ;		EQU	013H		; - RESERVED			      ;E
  4992                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
  4993                              <1> 
  4994                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
  4995                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
  4996                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
  4997                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
  4998                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
  4999                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
  5000                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
  5001                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
  5002                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
  5003                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
  5004                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
  5005                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
  5006                              <1> 
  5007                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
  5008                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
  5009                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
  5010                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
  5011                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
  5012                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
  5013                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
  5014                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
  5015                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
  5016                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
  5017                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
  5018                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
  5019                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
  5020                              <1> 
  5021                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
  5022                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
  5023                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
  5024                              <1> 
  5025                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
  5026                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
  5027                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
  5028                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
  5029                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
  5030                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
  5031                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
  5032                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
  5033                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
  5034                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
  5035                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
  5036                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
  5037                              <1> 
  5038                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
  5039                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
  5040                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
  5041                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
  5042                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
  5043                              <1> 
  5044                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
  5045                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
  5046                              <1> ;INTA00		EQU	020H		; 8259 PORT
  5047                              <1> INTA01		EQU	021H		; 8259 PORT
  5048                              <1> INTB00		EQU	0A0H		; 2ND 8259
  5049                              <1> INTB01		EQU	0A1H		;
  5050                              <1> 
  5051                              <1> ;-------------------------------------------------------------------------------
  5052                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
  5053                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
  5054                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
  5055                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
  5056                              <1> ;-------------------------------------------------------------------------------
  5057                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
  5058                              <1> 
  5059                              <1> ;-------------------------------------------------------------------------------
  5060                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
  5061                              <1> 
  5062                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
  5063                              <1> ; (unix386.s <-- dsectrm2.s)
  5064                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
  5065                              <1> 
  5066                              <1> ; 10/12/2014
  5067                              <1> ;
  5068                              <1> ;int40h:
  5069                              <1> ;	pushf
  5070                              <1> ;	push 	cs
  5071                              <1> ;	;cli
  5072                              <1> ;	call 	DISKETTE_IO_1
  5073                              <1> ;	retn
  5074                              <1> 
  5075                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
  5076                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  5077                              <1> ;
  5078                              <1> 
  5079                              <1> ;-- INT13H ---------------------------------------------------------------------
  5080                              <1> ; DISKETTE I/O
  5081                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
  5082                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
  5083                              <1> ; INPUT
  5084                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
  5085                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
  5086                              <1> ;		ON ALL DRIVES
  5087                              <1> ;------------------------------------------------------------------------------- 
  5088                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
  5089                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
  5090                              <1> ;-------------------------------------------------------------------------------
  5091                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
  5092                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5093                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
  5094                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
  5095                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
  5096                              <1> ;		320/360	320/360	    0-39
  5097                              <1> ;		320/360	1.2M	    0-39
  5098                              <1> ;		1.2M	1.2M	    0-79
  5099                              <1> ;		720K	720K	    0-79
  5100                              <1> ;		1.44M	1.44M	    0-79	
  5101                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
  5102                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
  5103                              <1> ;		320/360	320/360	     1-8/9
  5104                              <1> ;		320/360	1.2M	     1-8/9
  5105                              <1> ;		1.2M	1.2M	     1-15
  5106                              <1> ;		720K	720K	     1-9
  5107                              <1> ;		1.44M	1.44M	     1-18		
  5108                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
  5109                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
  5110                              <1> ;		320/360	320/360	        8/9
  5111                              <1> ;		320/360	1.2M	        8/9
  5112                              <1> ;		1.2M	1.2M		15
  5113                              <1> ;		720K	720K		9
  5114                              <1> ;		1.44M	1.44M		18
  5115                              <1> ;
  5116                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
  5117                              <1> ;
  5118                              <1> ;-------------------------------------------------------------------------------
  5119                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
  5120                              <1> ;-------------------------------------------------------------------------------
  5121                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
  5122                              <1> ;-------------------------------------------------------------------------------
  5123                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
  5124                              <1> ;-------------------------------------------------------------------------------
  5125                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
  5126                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
  5127                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
  5128                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
  5129                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
  5130                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
  5131                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
  5132                              <1> ;		READ/WRITE ACCESS.
  5133                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
  5134                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
  5135                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
  5136                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
  5137                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
  5138                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
  5139                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
  5140                              <1> ;
  5141                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
  5142                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
  5143                              <1> ;		---------------------------------------------
  5144                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
  5145                              <1> ;		---------------------------------------------
  5146                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
  5147                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
  5148                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
  5149                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
  5150                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
  5151                              <1> ;		---------------------------------------------
  5152                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
  5153                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
  5154                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
  5155                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
  5156                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
  5157                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
  5158                              <1> ;-------------------------------------------------------------------------------
  5159                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
  5160                              <1> ;	REGISTERS
  5161                              <1> ;	  INPUT
  5162                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5163                              <1> ;	  OUTPUT
  5164                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
  5165                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
  5166                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5167                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5168                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
  5169                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
  5170                              <1> ;	    (BH) - 0
  5171                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
  5172                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
  5173                              <1> ;	    (AX) - 0
  5174                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
  5175                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
  5176                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
  5177                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
  5178                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
  5179                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
  5180                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
  5181                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
  5182                              <1> ;-------------------------------------------------------------------------------
  5183                              <1> ;	(AH)= 15H  READ DASD TYPE
  5184                              <1> ;	OUTPUT REGISTERS
  5185                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
  5186                              <1> ;		00 - DRIVE NOT PRESENT	
  5187                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
  5188                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
  5189                              <1> ;		03 - RESERVED (FIXED DISK)
  5190                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5191                              <1> ;-------------------------------------------------------------------------------
  5192                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
  5193                              <1> ;	OUTPUT REGISTERS
  5194                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
  5195                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
  5196                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5197                              <1> ;-------------------------------------------------------------------------------
  5198                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
  5199                              <1> ;	INPUT REGISTERS
  5200                              <1> ;	(AL) -	00 - NOT USED	
  5201                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
  5202                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
  5203                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
  5204                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
  5205                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
  5206                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
  5207                              <1> ;-------------------------------------------------------------------------------
  5208                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
  5209                              <1> ;	INPUT REGISTERS
  5210                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
  5211                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5212                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5213                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
  5214                              <1> ;	OUTPUT REGISTERS:
  5215                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
  5216                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
  5217                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
  5218                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
  5219                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
  5220                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
  5221                              <1> ;-------------------------------------------------------------------------------
  5222                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
  5223                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
  5224                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
  5225                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
  5226                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
  5227                              <1> ;		CHANGE ERROR CODE
  5228                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
  5229                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
  5230                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
  5231                              <1> ;
  5232                              <1> ; DATA VARIABLE -- @DISK_POINTER
  5233                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
  5234                              <1> ;-------------------------------------------------------------------------------
  5235                              <1> ; OUTPUT FOR ALL FUNCTIONS
  5236                              <1> ;	AH = STATUS OF OPERATION
  5237                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
  5238                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
  5239                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
  5240                              <1> ;		TYPE AH=(15)).
  5241                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
  5242                              <1> ;	FOR READ/WRITE/VERIFY
  5243                              <1> ;		DS,BX,DX,CX PRESERVED
  5244                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
  5245                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
  5246                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
  5247                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
  5248                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
  5249                              <1> ;-------------------------------------------------------------------------------
  5250                              <1> ;
  5251                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
  5252                              <1> ;
  5253                              <1> ;   -----------------------------------------------------------------
  5254                              <1> ;   |       |       |       |       |       |       |       |       |
  5255                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
  5256                              <1> ;   |       |       |       |       |       |       |       |       |
  5257                              <1> ;   -----------------------------------------------------------------
  5258                              <1> ;	|	|	|	|	|	|	|	|
  5259                              <1> ;	|	|	|	|	|	-----------------
  5260                              <1> ;	|	|	|	|	|		|
  5261                              <1> ;	|	|	|	|    RESERVED		|
  5262                              <1> ;	|	|	|	|		  PRESENT STATE
  5263                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
  5264                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
  5265                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
  5266                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
  5267                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
  5268                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
  5269                              <1> ;	|	|	|	|	110: RESERVED
  5270                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
  5271                              <1> ;	|	|	|	|
  5272                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
  5273                              <1> ;	|	|	|
  5274                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
  5275                              <1> ;	|	|			DRIVE)
  5276                              <1> ;	|	|
  5277                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
  5278                              <1> ;
  5279                              <1> ;						00: 500 KBS
  5280                              <1> ;						01: 300 KBS
  5281                              <1> ;						10: 250 KBS
  5282                              <1> ;						11: RESERVED
  5283                              <1> ;
  5284                              <1> ;
  5285                              <1> ;-------------------------------------------------------------------------------
  5286                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
  5287                              <1> ;-------------------------------------------------------------------------------
  5288                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
  5289                              <1> ;-------------------------------------------------------------------------------
  5290                              <1> 
  5291                              <1> struc MD
  5292 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  5293 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  5294 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  5295 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
  5296 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
  5297 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
  5298 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
  5299 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
  5300 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
  5301 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
  5302 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
  5303 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
  5304 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
  5305                              <1> endstruc
  5306                              <1> 
  5307                              <1> BIT7OFF	EQU	7FH
  5308                              <1> BIT7ON	EQU	80H
  5309                              <1> 
  5310                              <1> ;;int13h: ; 16/02/2015
  5311                              <1> ;; 16/02/2015 - 21/02/2015
  5312                              <1> int40h:
  5313 00001947 9C                  <1> 	pushfd
  5314 00001948 0E                  <1> 	push 	cs
  5315 00001949 E801000000          <1> 	call 	DISKETTE_IO_1
  5316 0000194E C3                  <1> 	retn	
  5317                              <1> 
  5318                              <1> DISKETTE_IO_1:
  5319                              <1> 
  5320 0000194F FB                  <1> 	STI				; INTERRUPTS BACK ON
  5321 00001950 55                  <1> 	PUSH	eBP			; USER REGISTER
  5322 00001951 57                  <1> 	PUSH	eDI			; USER REGISTER
  5323 00001952 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
  5324 00001953 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
  5325 00001954 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
  5326 00001955 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
  5327                              <1> 					; [BP]   = SECTOR #
  5328                              <1> 					; [BP+1] = TRACK #
  5329                              <1> 					; [BP+2] = BUFFER OFFSET
  5330                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
  5331                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
  5332                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
  5333                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
  5334                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
  5335                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
  5336                              <1> 					; BH/[BP+3] = 0
  5337                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
  5338                              <1> 					; DH/[BP+5] = MAX HEAD #
  5339                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
  5340 00001957 06                  <1> 	push	es ; 06/02/2015	
  5341 00001958 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
  5342 00001959 56                  <1> 	PUSH	eSI			; USER REGISTERS
  5343                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
  5344                              <1> 	;mov	cx, cs
  5345                              <1> 	;mov	ds, cx
  5346 0000195A 66B91000            <1> 	mov	cx, KDATA
  5347 0000195E 8ED9                <1>         mov     ds, cx
  5348 00001960 8EC1                <1>         mov     es, cx
  5349                              <1> 
  5350                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
  5351 00001962 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4 ; 18/02/2015
  5352 00001965 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
  5353 00001967 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5354                              <1> OK_FUNC:
  5355 00001969 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
  5356 0000196C 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
  5357 0000196E 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
  5358 00001971 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
  5359 00001973 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
  5360 00001976 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
  5361 00001978 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5362                              <1> OK_DRV:
  5363 0000197A 31C9                <1> 	xor	ecx, ecx
  5364                              <1> 	;mov	esi, ecx ; 08/02/2015
  5365 0000197C 89CF                <1> 	mov	edi, ecx ; 08/02/2015
  5366 0000197E 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
  5367                              <1> 	;XOR	CH,CH			; CX = FUNCTION
  5368                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
  5369 00001980 C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
  5370 00001983 BB[BB190000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
  5371 00001988 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
  5372 0000198A 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
  5373 0000198C 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
  5374 0000198E 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
  5375 00001991 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
  5376                              <1> 	;
  5377                              <1> 	; 11/12/2014
  5378 00001994 8815[216B0000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
  5379                              <1> 	;
  5380 0000199A 8A25[FC700000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
  5381 000019A0 C605[FC700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
  5382                              <1> 
  5383                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
  5384                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
  5385                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
  5386                              <1> ;
  5387                              <1> ;		DI	: DRIVE #
  5388                              <1> ;		SI-HI	: HEAD #
  5389                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
  5390                              <1> ;		ES	: BUFFER SEGMENT
  5391                              <1> ;		[BP]	: SECTOR #
  5392                              <1> ;		[BP+1]	: TRACK #
  5393                              <1> ;		[BP+2]	: BUFFER OFFSET
  5394                              <1> ;
  5395                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
  5396                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
  5397                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
  5398                              <1> ;	SPECIFIC ERROR CODE.
  5399                              <1> ;
  5400                              <1> 					; (AH) = @DSKETTE_STATUS
  5401 000019A7 FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
  5402 000019A9 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
  5403 000019AA 1F                  <1> 	POP	DS
  5404 000019AB 07                  <1> 	pop	es	; 06/02/2015
  5405 000019AC 59                  <1> 	POP	eCX
  5406 000019AD 5B                  <1> 	POP	eBX
  5407 000019AE 5A                  <1> 	POP	eDX
  5408 000019AF 5F                  <1> 	POP	eDI
  5409 000019B0 89E5                <1> 	MOV	eBP, eSP
  5410 000019B2 50                  <1> 	PUSH	eAX
  5411 000019B3 9C                  <1> 	PUSHFd
  5412 000019B4 58                  <1> 	POP	eAX
  5413                              <1> 	;MOV	[BP+6], AX
  5414 000019B5 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
  5415 000019B8 58                  <1> 	POP	eAX
  5416 000019B9 5D                  <1> 	POP	eBP
  5417 000019BA CF                  <1> 	IRETd
  5418                              <1> 
  5419                              <1> ;-------------------------------------------------------------------------------
  5420                              <1> ; DW --> dd (06/02/2015)
  5421 000019BB [1F1A0000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
  5422 000019BF [981A0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
  5423 000019C3 [A91A0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
  5424 000019C7 [BA1A0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
  5425 000019CB [CB1A0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
  5426 000019CF [DC1A0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
  5427 000019D3 [611B0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
  5428 000019D7 [611B0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
  5429 000019DB [6E1B0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
  5430 000019DF [611B0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
  5431 000019E3 [611B0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
  5432 000019E7 [611B0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
  5433 000019EB [611B0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
  5434 000019EF [611B0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
  5435 000019F3 [611B0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
  5436 000019F7 [611B0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
  5437 000019FB [611B0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
  5438 000019FF [611B0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
  5439 00001A03 [611B0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
  5440 00001A07 [611B0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
  5441 00001A0B [611B0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
  5442 00001A0F [2F1C0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
  5443 00001A13 [5A1C0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
  5444 00001A17 [941C0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
  5445 00001A1B [171D0000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
  5446                              <1> FNC_TAE EQU     $                       ; END
  5447                              <1> 
  5448                              <1> ;-------------------------------------------------------------------------------
  5449                              <1> ; DISK_RESET	(AH = 00H)	
  5450                              <1> ;		RESET THE DISKETTE SYSTEM.
  5451                              <1> ;
  5452                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5453                              <1> ;-------------------------------------------------------------------------------
  5454                              <1> DSK_RESET:
  5455 00001A1F 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
  5456 00001A23 FA                  <1> 	CLI				; NO INTERRUPTS
  5457 00001A24 A0[FA700000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  5458 00001A29 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
  5459 00001A2B C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
  5460                              <1> 					; DRIVE SELECT TO LOW NIBBLE
  5461 00001A2E 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
  5462 00001A30 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5463 00001A31 C605[F9700000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  5464                              <1> 	;JMP	$+2			; WAIT FOR I/O
  5465                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
  5466                              <1> 					;      PULSE WIDTH)
  5467                              <1> 	; 19/12/2014
  5468                              <1> 	NEWIODELAY
  5469 00001A38 E6EB                <2>  out 0ebh,al
  5470                              <1> 
  5471                              <1> 	; 17/12/2014 
  5472                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
  5473 00001A3A B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
  5474                              <1> wdw1:
  5475                              <1> 	NEWIODELAY   ; 27/02/2015
  5476 00001A3F E6EB                <2>  out 0ebh,al
  5477 00001A41 E2FC                <1> 	loop	wdw1
  5478                              <1> 	;
  5479 00001A43 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
  5480 00001A45 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5481                              <1> 	; 16/12/2014
  5482                              <1> 	IODELAY
  5483 00001A46 EB00                <2>  jmp short $+2
  5484 00001A48 EB00                <2>  jmp short $+2
  5485                              <1> 	;
  5486                              <1> 	;STI				; ENABLE THE INTERRUPTS
  5487 00001A4A E8250C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  5488 00001A4F 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
  5489 00001A51 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
  5490                              <1> NXT_DRV:
  5491 00001A55 6651                <1> 	PUSH	CX			; SAVE FOR CALL
  5492 00001A57 B8[8D1A0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
  5493 00001A5C 50                  <1> 	PUSH	eAX			; "
  5494 00001A5D B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  5495 00001A5F E8030B0000          <1> 	CALL	NEC_OUTPUT
  5496 00001A64 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  5497 00001A65 E83A0C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  5498 00001A6A 6659                <1> 	POP	CX			; RESTORE AFTER CALL
  5499 00001A6C 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
  5500 00001A6E 3A0D[FD700000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
  5501 00001A74 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
  5502 00001A76 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
  5503 00001A78 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
  5504 00001A7B 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
  5505                              <1> 	;
  5506 00001A7D E852030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5507                              <1> RESBAC:
  5508 00001A82 E806090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5509 00001A87 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5510 00001A8A 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5511 00001A8C C3                  <1> 	RETn		
  5512                              <1> DR_POP_ERR:
  5513 00001A8D 6659                <1> 	POP	CX			; CLEAR STACK
  5514                              <1> DR_ERR:
  5515 00001A8F 800D[FC700000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
  5516 00001A96 EBEA                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
  5517                              <1> 
  5518                              <1> ;-------------------------------------------------------------------------------
  5519                              <1> ; DISK_STATUS	(AH = 01H)
  5520                              <1> ;	DISKETTE STATUS.
  5521                              <1> ;
  5522                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
  5523                              <1> ;
  5524                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
  5525                              <1> ;-------------------------------------------------------------------------------
  5526                              <1> DSK_STATUS:
  5527 00001A98 8825[FC700000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
  5528 00001A9E E8EA080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5529 00001AA3 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5530 00001AA6 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5531 00001AA8 C3                  <1> 	RETn		
  5532                              <1> 
  5533                              <1> ;-------------------------------------------------------------------------------
  5534                              <1> ; DISK_READ	(AH = 02H)	
  5535                              <1> ;	DISKETTE READ.
  5536                              <1> ;
  5537                              <1> ; ON ENTRY:	DI	: DRIVE #
  5538                              <1> ;		SI-HI	: HEAD #
  5539                              <1> ;		SI-LOW	: # OF SECTORS
  5540                              <1> ;		ES	: BUFFER SEGMENT
  5541                              <1> ;		[BP]	: SECTOR #
  5542                              <1> ;		[BP+1]	: TRACK #
  5543                              <1> ;		[BP+2]	: BUFFER OFFSET
  5544                              <1> ;
  5545                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5546                              <1> ;-------------------------------------------------------------------------------
  5547                              <1> 
  5548                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5549                              <1> 
  5550                              <1> DSK_READ:
  5551 00001AA9 8025[FA700000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5552 00001AB0 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
  5553 00001AB4 E825040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5554 00001AB9 C3                  <1> 	RETn
  5555                              <1> 
  5556                              <1> ;-------------------------------------------------------------------------------
  5557                              <1> ; DISK_WRITE	(AH = 03H)
  5558                              <1> ;	DISKETTE WRITE.
  5559                              <1> ;
  5560                              <1> ; ON ENTRY:	DI	: DRIVE #
  5561                              <1> ;		SI-HI	: HEAD #
  5562                              <1> ;		SI-LOW	: # OF SECTORS
  5563                              <1> ;		ES	: BUFFER SEGMENT
  5564                              <1> ;		[BP]	: SECTOR #
  5565                              <1> ;		[BP+1]	: TRACK #
  5566                              <1> ;		[BP+2]	: BUFFER OFFSET
  5567                              <1> ;
  5568                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5569                              <1> ;-------------------------------------------------------------------------------
  5570                              <1> 
  5571                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5572                              <1> 
  5573                              <1> DSK_WRITE:
  5574 00001ABA 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
  5575 00001ABE 800D[FA700000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
  5576 00001AC5 E814040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5577 00001ACA C3                  <1> 	RETn
  5578                              <1> 
  5579                              <1> ;-------------------------------------------------------------------------------
  5580                              <1> ; DISK_VERF	(AH = 04H)
  5581                              <1> ;	DISKETTE VERIFY.
  5582                              <1> ;
  5583                              <1> ; ON ENTRY:	DI	: DRIVE #
  5584                              <1> ;		SI-HI	: HEAD #
  5585                              <1> ;		SI-LOW	: # OF SECTORS
  5586                              <1> ;		ES	: BUFFER SEGMENT
  5587                              <1> ;		[BP]	: SECTOR #
  5588                              <1> ;		[BP+1]	: TRACK #
  5589                              <1> ;		[BP+2]	: BUFFER OFFSET
  5590                              <1> ;
  5591                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5592                              <1> ;-------------------------------------------------------------------------------
  5593                              <1> DSK_VERF:
  5594 00001ACB 8025[FA700000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5595 00001AD2 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
  5596 00001AD6 E803040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5597 00001ADB C3                  <1> 	RETn
  5598                              <1> 
  5599                              <1> ;-------------------------------------------------------------------------------
  5600                              <1> ; DISK_FORMAT	(AH = 05H)
  5601                              <1> ;	DISKETTE FORMAT.
  5602                              <1> ;
  5603                              <1> ; ON ENTRY:	DI	: DRIVE #
  5604                              <1> ;		SI-HI	: HEAD #
  5605                              <1> ;		SI-LOW	: # OF SECTORS
  5606                              <1> ;		ES	: BUFFER SEGMENT
  5607                              <1> ;		[BP]	: SECTOR #
  5608                              <1> ;		[BP+1]	: TRACK #
  5609                              <1> ;		[BP+2]	: BUFFER OFFSET
  5610                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
  5611                              <1> ;
  5612                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5613                              <1> ;-------------------------------------------------------------------------------
  5614                              <1> DSK_FORMAT:
  5615 00001ADC E83C030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5616 00001AE1 E838050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
  5617 00001AE6 800D[FA700000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
  5618 00001AED E880050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
  5619 00001AF2 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
  5620 00001AF4 E8DB020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5621 00001AF9 E8E6050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
  5622 00001AFE 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
  5623 00001B00 E8BD050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
  5624                              <1> FM_WR:
  5625 00001B05 E873060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
  5626 00001B0A 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
  5627 00001B0C B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
  5628 00001B0E E8D0060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
  5629 00001B13 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
  5630 00001B15 B8[511B0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
  5631 00001B1A 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  5632 00001B1B B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
  5633 00001B1D E83F090000          <1> 	CALL	GET_PARM
  5634 00001B22 E8400A0000          <1> 	CALL	NEC_OUTPUT
  5635 00001B27 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
  5636 00001B29 E833090000          <1> 	CALL	GET_PARM
  5637 00001B2E E8340A0000          <1> 	CALL	NEC_OUTPUT
  5638 00001B33 B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
  5639 00001B35 E827090000          <1> 	CALL	GET_PARM
  5640 00001B3A E8280A0000          <1> 	CALL	NEC_OUTPUT
  5641 00001B3F B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
  5642 00001B41 E81B090000          <1> 	CALL	GET_PARM
  5643 00001B46 E81C0A0000          <1> 	CALL	NEC_OUTPUT
  5644 00001B4B 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  5645 00001B4C E810070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
  5646                              <1> FM_DON:
  5647 00001B51 E8F8020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5648 00001B56 E832080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5649 00001B5B 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5650 00001B5E 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5651 00001B60 C3                  <1> 	RETn
  5652                              <1> 
  5653                              <1> ;-------------------------------------------------------------------------------
  5654                              <1> ; FNC_ERR
  5655                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
  5656                              <1> ;	SET BAD COMMAND IN STATUS.
  5657                              <1> ;
  5658                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5659                              <1> ;-------------------------------------------------------------------------------
  5660                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
  5661 00001B61 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
  5662 00001B64 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  5663 00001B66 8825[FC700000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
  5664 00001B6C F9                  <1> 	STC				; SET CARRY INDICATING ERROR
  5665 00001B6D C3                  <1> 	RETn
  5666                              <1> 
  5667                              <1> ;-------------------------------------------------------------------------------
  5668                              <1> ; DISK_PARMS	(AH = 08H)	
  5669                              <1> ;	READ DRIVE PARAMETERS.
  5670                              <1> ;
  5671                              <1> ; ON ENTRY:	DI : DRIVE #
  5672                              <1> ;
  5673                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
  5674                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
  5675                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
  5676                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
  5677                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
  5678                              <1> ;		BH/[BP+3] = 0
  5679                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
  5680                              <1> ;		DH/[BP+5] = MAX HEAD #
  5681                              <1> ;		DI/[BP+6] = OFFSET TO DISK_BASE
  5682                              <1> ;		ES        = SEGMENT OF DISK_BASE
  5683                              <1> ;		AX        = 0
  5684                              <1> ;
  5685                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
  5686                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
  5687                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
  5688                              <1> ;		       CALLER.
  5689                              <1> ;-------------------------------------------------------------------------------
  5690                              <1> DSK_PARMS:
  5691 00001B6E E8AA020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  5692                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
  5693 00001B73 29D2                <1> 	sub     edx, edx ; 20/02/2015
  5694 00001B75 895504              <1>         mov	[ebp+4], edx ; 20/02/2015
  5695                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
  5696                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
  5697                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
  5698                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
  5699                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
  5700                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
  5701                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
  5702                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
  5703                              <1> 	;sub	edx, edx
  5704 00001B78 66A1[2E6B0000]      <1> 	mov     ax, [fd0_type]
  5705 00001B7E 6621C0              <1> 	and     ax, ax
  5706 00001B81 7474                <1> 	jz      short NON_DRV
  5707 00001B83 FEC2                <1> 	inc     dl
  5708 00001B85 20E4                <1> 	and     ah, ah
  5709 00001B87 7402                <1> 	jz      short STO_DL
  5710 00001B89 FEC2                <1> 	inc     dl
  5711                              <1> STO_DL:
  5712                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
  5713 00001B8B 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
  5714 00001B8E 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
  5715 00001B92 7766                <1> 	JA	short NON_DRV1		; DRIVE INVALID
  5716                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
  5717 00001B94 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
  5718 00001B98 E8BB080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  5719                              <1> 	;;20/02/2015
  5720                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
  5721                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
  5722 00001B9D 7412                <1> 	JZ	short CHK_EST		; JUMP IF SO
  5723 00001B9F E805020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5724 00001BA4 720B                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
  5725                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
  5726 00001BA6 884504              <1>         mov	[ebp+4], al ; 06/02/2015
  5727 00001BA9 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
  5728 00001BAC 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
  5729 00001BAF EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
  5730                              <1> CHK_EST:
  5731 00001BB1 8AA7[09710000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
  5732 00001BB7 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
  5733 00001BBA 743E                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
  5734                              <1> USE_EST:
  5735 00001BBC 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
  5736 00001BBF 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  5737 00001BC2 7557                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
  5738                              <1> 
  5739                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
  5740                              <1> 
  5741 00001BC4 B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
  5742 00001BC6 E8DE010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5743 00001BCB 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5744 00001BCE 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5745 00001BD1 F687[09710000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
  5746 00001BD8 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
  5747                              <1> 
  5748                              <1> ;-----	IT IS 1.44 MB DRIVE
  5749                              <1> 
  5750                              <1> PARM144:
  5751 00001BDA B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
  5752 00001BDC E8C8010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5753 00001BE1 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5754 00001BE4 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5755                              <1> STO_CX:
  5756 00001BE7 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
  5757                              <1> ES_DI:
  5758                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
  5759 00001BEA 895D0C              <1> 	mov	[ebp+12], ebx ; 06/02/2015
  5760                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
  5761                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  5762                              <1> DP_OUT:
  5763 00001BED E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5764 00001BF2 6631C0              <1> 	XOR	AX,AX			; CLEAR
  5765 00001BF5 F8                  <1> 	CLC
  5766 00001BF6 C3                  <1> 	RETn
  5767                              <1> 
  5768                              <1> ;-----	NO DRIYE PRESENT HANDLER
  5769                              <1> 
  5770                              <1> NON_DRV:
  5771                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
  5772 00001BF7 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
  5773                              <1> NON_DRV1:
  5774 00001BFA 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
  5775 00001BFF 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
  5776                              <1> 
  5777                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
  5778                              <1> 	
  5779 00001C01 E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
  5780 00001C06 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
  5781 00001C09 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  5782 00001C0B F9                  <1> 	STC
  5783 00001C0C C3                  <1> 	RETn
  5784                              <1> 
  5785                              <1> NON_DRV2:
  5786                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
  5787 00001C0D 31C0                <1> 	xor	eax, eax	
  5788 00001C0F 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
  5789                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
  5790 00001C13 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
  5791                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
  5792 00001C16 89450C              <1> 	mov	[ebp+12], eax
  5793                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  5794 00001C19 EBD2                <1> 	JMP	SHORT DP_OUT
  5795                              <1> 
  5796                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
  5797                              <1> 
  5798                              <1> USE_EST2:
  5799 00001C1B B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
  5800 00001C1D E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5801 00001C22 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5802 00001C25 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5803 00001C28 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  5804 00001C2B 74BA                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
  5805 00001C2D EBAB                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
  5806                              <1> 
  5807                              <1> ;-------------------------------------------------------------------------------
  5808                              <1> ; DISK_TYPE (AH = 15H)	
  5809                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
  5810                              <1> ;
  5811                              <1> ;  ON ENTRY:	DI = DRIVE #
  5812                              <1> ;
  5813                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
  5814                              <1> ;-------------------------------------------------------------------------------
  5815                              <1> DSK_TYPE:
  5816 00001C2F E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5817 00001C34 8A87[09710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
  5818 00001C3A 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
  5819 00001C3C 7418                <1> 	JZ	short NO_DRV
  5820 00001C3E B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
  5821 00001C40 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
  5822 00001C42 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
  5823 00001C44 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
  5824                              <1> DT_BACK:
  5825 00001C46 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
  5826 00001C48 E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5827 00001C4D 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
  5828 00001C4F F8                  <1> 	CLC				; NO ERROR
  5829 00001C50 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5830 00001C53 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5831 00001C55 C3                  <1> 	RETn
  5832                              <1> NO_DRV:	
  5833 00001C56 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
  5834 00001C58 EBEC                <1> 	JMP	SHORT DT_BACK
  5835                              <1> 
  5836                              <1> ;-------------------------------------------------------------------------------
  5837                              <1> ; DISK_CHANGE	(AH = 16H)
  5838                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
  5839                              <1> ;
  5840                              <1> ; ON ENTRY:	DI = DRIVE #
  5841                              <1> ;
  5842                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
  5843                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
  5844                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
  5845                              <1> ;-------------------------------------------------------------------------------
  5846                              <1> DSK_CHANGE:
  5847 00001C5A E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5848 00001C5F 8A87[09710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  5849 00001C65 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  5850 00001C67 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  5851 00001C69 A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  5852 00001C6B 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  5853                              <1> DC0:
  5854 00001C6D E88D0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  5855 00001C72 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  5856                              <1> 
  5857 00001C74 C605[FC700000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  5858                              <1> 
  5859 00001C7B E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5860 00001C80 E808070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5861 00001C85 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5862 00001C88 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5863 00001C8A C3                  <1> 	RETn
  5864                              <1> DC_NON:
  5865 00001C8B 800D[FC700000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  5866 00001C92 EBE7                <1> 	JMP	SHORT FINIS
  5867                              <1> 
  5868                              <1> ;-------------------------------------------------------------------------------
  5869                              <1> ; FORMAT_SET	(AH = 17H)
  5870                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  5871                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  5872                              <1> ;
  5873                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  5874                              <1> ;		DI     = DRIVE #
  5875                              <1> ;
  5876                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  5877                              <1> ;		AH = @DSKETTE_STATUS
  5878                              <1> ;		CY = 1 IF ERROR
  5879                              <1> ;-------------------------------------------------------------------------------
  5880                              <1> FORMAT_SET:
  5881 00001C94 E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5882 00001C99 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  5883 00001C9B 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  5884 00001C9E 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  5885 00001CA0 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  5886 00001CA3 80A7[09710000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  5887 00001CAA 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  5888 00001CAC 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  5889 00001CAE 808F[09710000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  5890 00001CB5 EB48                <1> 	JMP	SHORT S0
  5891                              <1> 
  5892                              <1> NOT_320:
  5893 00001CB7 E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  5894 00001CBC 803D[FC700000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  5895 00001CC3 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  5896                              <1> S3:
  5897 00001CC5 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  5898 00001CC7 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  5899 00001CC9 808F[09710000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  5900 00001CD0 EB2D                <1> 	JMP	SHORT S0
  5901                              <1> 
  5902                              <1> NOT_320_12:
  5903 00001CD2 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  5904 00001CD4 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  5905 00001CD6 808F[09710000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  5906 00001CDD EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  5907                              <1> 
  5908                              <1> NOT_12:	
  5909 00001CDF 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  5910 00001CE1 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  5911                              <1> 
  5912 00001CE3 F687[09710000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  5913 00001CEA 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  5914 00001CEC B050                <1> 	MOV	AL,MED_DET+RATE_300
  5915 00001CEE F687[09710000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  5916 00001CF5 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  5917                              <1> 
  5918                              <1> ASSUME:
  5919 00001CF7 B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  5920                              <1> 
  5921                              <1> OR_IT_IN:
  5922 00001CF9 0887[09710000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  5923                              <1> S0:
  5924 00001CFF E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5925 00001D04 E884060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5926 00001D09 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  5927 00001D0B 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5928 00001D0D C3                  <1> 	RETn
  5929                              <1> 
  5930                              <1> FS_ERR:
  5931 00001D0E C605[FC700000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  5932 00001D15 EBE8                <1> 	JMP	SHORT S0
  5933                              <1> 
  5934                              <1> ;-------------------------------------------------------------------------------
  5935                              <1> ; SET_MEDIA	(AH = 18H)
  5936                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  5937                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  5938                              <1> ;
  5939                              <1> ; ON ENTRY:
  5940                              <1> ;	[BP]	= SECTOR PER TRACK
  5941                              <1> ;	[BP+1]	= TRACK #
  5942                              <1> ;	DI	= DRIVE #
  5943                              <1> ;
  5944                              <1> ; ON EXIT:
  5945                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  5946                              <1> ;	IF NO ERROR:
  5947                              <1> ;		AH = 0
  5948                              <1> ;		CY = 0
  5949                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  5950                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  5951                              <1> ;	IF ERROR:	
  5952                              <1> ;		AH = @DSKETTE_STATUS
  5953                              <1> ;		CY = 1
  5954                              <1> ;-------------------------------------------------------------------------------
  5955                              <1> SET_MEDIA:
  5956 00001D17 E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5957 00001D1C F687[09710000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  5958 00001D23 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  5959 00001D25 E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  5960 00001D2A 803D[FC700000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  5961 00001D31 746B                <1> 	JE	short SM_RTN
  5962 00001D33 C605[FC700000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  5963                              <1> SM_CMOS:
  5964 00001D3A E819070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  5965                              <1> 	;;20/02/2015
  5966                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  5967                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  5968 00001D3F 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  5969 00001D41 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5970 00001D46 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  5971 00001D48 57                  <1> 	PUSH	eDI			; SAVE REG.
  5972 00001D49 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  5973 00001D4B B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  5974                              <1> DR_SEARCH:
  5975 00001D50 8AA3[AC6A0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  5976 00001D56 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  5977 00001D59 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  5978 00001D5B 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  5979                              <1> DR_FND:
  5980 00001D5D 8BBB[AD6A0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  5981                              <1> MD_SEARCH:
  5982 00001D63 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5983 00001D66 386500              <1> 	CMP	[eBP],AH		; MATCH?
  5984 00001D69 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  5985 00001D6B 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  5986 00001D6E 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  5987 00001D71 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  5988                              <1> NXT_MD:
  5989                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  5990 00001D73 83C305              <1>         add	ebx, 5 ; 18/02/2015
  5991 00001D76 E2D8                <1> 	LOOP    DR_SEARCH
  5992 00001D78 5F                  <1> 	POP	eDI			; RESTORE REG.
  5993                              <1> MD_NOT_FND:
  5994 00001D79 C605[FC700000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  5995 00001D80 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  5996                              <1> MD_FND:
  5997 00001D82 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  5998 00001D85 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  5999 00001D87 7502                <1> 	JNE	short MD_SET
  6000 00001D89 0C20                <1> 	OR	AL,DBL_STEP
  6001                              <1> MD_SET:
  6002                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  6003 00001D8B 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  6004 00001D8E 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  6005 00001D90 5F                  <1> 	POP	eDI
  6006 00001D91 80A7[09710000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  6007 00001D98 0887[09710000]      <1> 	OR	[DSK_STATE+eDI], AL
  6008                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  6009                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  6010                              <1> SM_RTN:
  6011 00001D9E E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6012 00001DA3 E8E5050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6013 00001DA8 C3                  <1> 	RETn
  6014                              <1> 
  6015                              <1> ;----------------------------------------------------------------
  6016                              <1> ; DR_TYPE_CHECK							:
  6017                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  6018                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  6019                              <1> ; ON ENTRY:							:
  6020                              <1> ;	AL = DRIVE TYPE						:
  6021                              <1> ; ON EXIT:							:
  6022                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  6023                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  6024                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  6025                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  6026                              <1> ; REGISTERS ALTERED: eBX						:
  6027                              <1> ;----------------------------------------------------------------		
  6028                              <1> DR_TYPE_CHECK:
  6029 00001DA9 6650                <1> 	PUSH	AX			
  6030 00001DAB 51                  <1> 	PUSH	eCX
  6031 00001DAC 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6032 00001DAE B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6033                              <1> TYPE_CHK:	
  6034 00001DB3 8AA3[AC6A0000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  6035 00001DB9 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6036 00001DBB 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  6037                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6038 00001DBD 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  6039 00001DC0 E2F1                <1> 	LOOP    TYPE_CHK
  6040                              <1> 	;
  6041 00001DC2 BB[0B6B0000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  6042                              <1> 					; Default for GET_PARM (11/12/2014)
  6043                              <1> 	;
  6044 00001DC7 F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  6045 00001DC8 EB06                <1> 	JMP	SHORT TYPE_RTN
  6046                              <1> DR_TYPE_VALID:
  6047 00001DCA 8B9B[AD6A0000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  6048                              <1> TYPE_RTN:
  6049 00001DD0 59                  <1> 	POP	eCX
  6050 00001DD1 6658                <1> 	POP	AX
  6051 00001DD3 C3                  <1> 	RETn	
  6052                              <1> 		
  6053                              <1> ;----------------------------------------------------------------
  6054                              <1> ; SEND_SPEC							:
  6055                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6056                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  6057                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  6058                              <1> ; ON EXIT:	NONE						:	
  6059                              <1> ; REGISTERS ALTERED: CX, DX					:
  6060                              <1> ;----------------------------------------------------------------		
  6061                              <1> SEND_SPEC:
  6062 00001DD4 50                  <1> 	PUSH	eAX			; SAVE AX
  6063 00001DD5 B8[FB1D0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  6064 00001DDA 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6065 00001DDB B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6066 00001DDD E885070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6067 00001DE2 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  6068 00001DE4 E878060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6069 00001DE9 E879070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6070 00001DEE B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  6071 00001DF0 E86C060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6072 00001DF5 E86D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6073 00001DFA 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6074                              <1> SPECBAC:
  6075 00001DFB 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6076 00001DFC C3                  <1> 	RETn
  6077                              <1> 
  6078                              <1> ;----------------------------------------------------------------
  6079                              <1> ; SEND_SPEC_MD							:
  6080                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6081                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  6082                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  6083                              <1> ; ON EXIT:	NONE						:	
  6084                              <1> ; REGISTERS ALTERED: AX						:
  6085                              <1> ;----------------------------------------------------------------		
  6086                              <1> SEND_SPEC_MD:
  6087 00001DFD 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  6088 00001DFE B8[1B1E0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  6089 00001E03 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6090 00001E04 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6091 00001E06 E85C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6092 00001E0B 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  6093 00001E0D E855070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6094 00001E12 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  6095 00001E15 E84D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6096 00001E1A 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6097                              <1> SPEC_ESBAC:
  6098 00001E1B 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6099 00001E1C C3                  <1> 	RETn
  6100                              <1> 
  6101                              <1> ;-------------------------------------------------------------------------------
  6102                              <1> ; XLAT_NEW  
  6103                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  6104                              <1> ;	MODE TO NEW ARCHITECTURE.
  6105                              <1> ;
  6106                              <1> ; ON ENTRY:	DI = DRIVE #
  6107                              <1> ;-------------------------------------------------------------------------------
  6108                              <1> XLAT_NEW:
  6109 00001E1D 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  6110 00001E20 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  6111 00001E22 80BF[09710000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  6112 00001E29 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  6113 00001E2B 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  6114 00001E2E C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  6115 00001E31 A0[08710000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  6116 00001E36 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  6117 00001E38 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  6118 00001E3A 80A7[09710000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  6119 00001E41 0887[09710000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  6120                              <1> XN_OUT:
  6121 00001E47 C3                  <1> 	RETn
  6122                              <1> DO_DET:
  6123 00001E48 E8BF080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  6124 00001E4D C3                  <1> 	RETn
  6125                              <1> 
  6126                              <1> ;-------------------------------------------------------------------------------
  6127                              <1> ; XLAT_OLD 
  6128                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  6129                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  6130                              <1> ;
  6131                              <1> ; ON ENTRY:	DI = DRIVE
  6132                              <1> ;-------------------------------------------------------------------------------
  6133                              <1> XLAT_OLD:
  6134 00001E4E 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  6135                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  6136 00001E51 0F8786000000        <1>         ja      XO_OUT
  6137 00001E57 80BF[09710000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  6138 00001E5E 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  6139                              <1> 
  6140                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  6141                              <1> 
  6142 00001E60 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  6143 00001E63 C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  6144 00001E66 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  6145 00001E68 D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  6146 00001E6A 8425[08710000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  6147 00001E70 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  6148                              <1> 
  6149                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  6150                              <1> 
  6151 00001E72 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  6152 00001E74 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  6153 00001E76 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  6154 00001E78 2025[08710000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  6155                              <1> 
  6156                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  6157                              <1> 
  6158 00001E7E 8A87[09710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  6159 00001E84 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  6160 00001E86 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  6161 00001E88 0805[08710000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  6162                              <1> 
  6163                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  6164                              <1> 
  6165                              <1> SAVE_SET:
  6166 00001E8E 8AA7[09710000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  6167 00001E94 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  6168 00001E96 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  6169 00001E99 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  6170 00001E9C 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  6171 00001E9E B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  6172 00001EA0 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  6173 00001EA3 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  6174 00001EA5 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  6175 00001EA8 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  6176                              <1> UNKNO:
  6177 00001EAA B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  6178 00001EAC EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  6179                              <1> CHK_144:
  6180 00001EAE E8A5050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6181                              <1> 	;;20/02/2015
  6182                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  6183 00001EB3 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  6184 00001EB5 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  6185 00001EB7 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  6186 00001EB9 B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  6187 00001EBB EB0C                <1> 	JMP	SHORT TST_DET
  6188                              <1> CHK_250:
  6189 00001EBD B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  6190 00001EBF 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  6191 00001EC2 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  6192 00001EC4 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  6193 00001EC7 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  6194                              <1> TST_DET:
  6195 00001EC9 F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  6196 00001ECC 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  6197 00001ECE 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  6198                              <1> AL_SET:
  6199 00001ED0 80A7[09710000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  6200 00001ED7 0887[09710000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  6201                              <1> XO_OUT:
  6202 00001EDD C3                  <1> 	RETn
  6203                              <1> 
  6204                              <1> ;-------------------------------------------------------------------------------
  6205                              <1> ; RD_WR_VF
  6206                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  6207                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  6208                              <1> ;
  6209                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  6210                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  6211                              <1> ;
  6212                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6213                              <1> ;-------------------------------------------------------------------------------
  6214                              <1> RD_WR_VF:
  6215 00001EDE 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  6216 00001EE0 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6217 00001EE5 E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  6218 00001EEA 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  6219                              <1> DO_AGAIN:
  6220 00001EEC 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6221 00001EEE E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  6222 00001EF3 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  6223 00001EF5 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  6224                              <1> RWV:
  6225 00001EFB 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6226 00001EFD 8AB7[09710000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6227 00001F03 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  6228 00001F06 E84D050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  6229                              <1> 	;;20/02/2015
  6230                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  6231 00001F0B 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  6232 00001F0D 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  6233 00001F0F 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  6234 00001F11 F687[09710000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  6235 00001F18 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  6236 00001F1A B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  6237 00001F1C EB0F                <1> 	JMP	SHORT RWV_2
  6238                              <1> RWV_1:
  6239 00001F1E 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  6240 00001F20 F687[09710000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  6241 00001F27 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  6242 00001F29 B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  6243 00001F2B EB04                <1> 	jmp	short rwv_3
  6244                              <1> RWV_2:
  6245 00001F2D 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  6246 00001F2F 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  6247                              <1> rwv_3:
  6248 00001F31 E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  6249 00001F36 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  6250                              <1> 
  6251                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  6252                              <1> 
  6253 00001F38 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  6254 00001F39 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6255 00001F3B B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6256                              <1> RWV_DR_SEARCH:
  6257 00001F40 8AA3[AC6A0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  6258 00001F46 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  6259 00001F49 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6260 00001F4B 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  6261                              <1> RWV_DR_FND:
  6262 00001F4D 8BBB[AD6A0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  6263                              <1> RWV_MD_SEARH:
  6264 00001F53 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  6265 00001F56 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  6266                              <1> RWV_NXT_MD:
  6267                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6268 00001F58 83C305              <1> 	add	eBX, 5
  6269 00001F5B E2E3                <1> 	LOOP	RWV_DR_SEARCH
  6270 00001F5D 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6271                              <1> 
  6272                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  6273                              <1> 
  6274                              <1> RWV_ASSUME:
  6275 00001F5E BB[CA6A0000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  6276 00001F63 F687[09710000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  6277 00001F6A 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  6278 00001F6C BB[E46A0000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  6279 00001F71 EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  6280                              <1> 
  6281                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  6282                              <1> 	 			
  6283                              <1> RWV_MD_FND:
  6284 00001F73 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  6285 00001F75 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6286                              <1> 	
  6287                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  6288                              <1> 
  6289                              <1> RWV_MD_FND1:
  6290 00001F76 E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  6291 00001F7B E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  6292 00001F80 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  6293 00001F82 E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  6294                              <1> RWV_DBL:
  6295 00001F87 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6296 00001F88 E822040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  6297 00001F8D 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6298 00001F8E 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  6299 00001F90 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  6300 00001F92 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6301 00001F94 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6302 00001F95 E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  6303 00001F9A 5B                  <1> 	POP	eBX 
  6304 00001F9B 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  6305 00001F9D 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  6306 00001F9F 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6307 00001FA1 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6308 00001FA2 E83C020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  6309 00001FA7 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6310 00001FA8 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6311 00001FAA E866020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  6312 00001FAF 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6313 00001FB1 E8AB020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  6314                              <1> CHK_RET:
  6315 00001FB6 E84A030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  6316 00001FBB 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  6317 00001FBD 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  6318 00001FBF E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  6319                              <1> RWV_END:
  6320 00001FC4 E8F4020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  6321 00001FC9 E887030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  6322                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  6323 00001FCE 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  6324 00001FD0 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6325 00001FD5 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  6326 00001FD7 E8B1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6327 00001FDC C3                  <1> 	RETn
  6328                              <1> 
  6329                              <1> ;-------------------------------------------------------------------------------
  6330                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  6331                              <1> ;-------------------------------------------------------------------------------
  6332                              <1> SETUP_STATE:
  6333 00001FDD F687[09710000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  6334 00001FE4 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  6335 00001FE6 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  6336 00001FEA F687[09710000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  6337 00001FF1 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  6338 00001FF3 F687[09710000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  6339 00001FFA 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  6340 00001FFC 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  6341                              <1> AX_SET:	
  6342 00002000 80A7[09710000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  6343 00002007 08A7[09710000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  6344 0000200D 8025[04710000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  6345 00002014 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  6346 00002017 0805[04710000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  6347                              <1> J1C:	
  6348 0000201D C3                  <1> 	RETn
  6349                              <1> 
  6350                              <1> ;-------------------------------------------------------------------------------
  6351                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  6352                              <1> ;-------------------------------------------------------------------------------
  6353                              <1> FMT_INIT:
  6354 0000201E F687[09710000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  6355 00002025 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  6356 00002027 E82C040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  6357                              <1> 	;; 20/02/2015
  6358                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  6359 0000202C 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  6360 0000202E FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  6361                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  6362 00002030 8AA7[09710000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  6363 00002036 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  6364 00002039 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  6365 0000203B 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  6366 0000203D 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  6367 00002040 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6368                              <1> N_360:	
  6369 00002042 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  6370 00002044 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  6371                              <1> F1_RATE:
  6372 00002046 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  6373 00002049 EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6374                              <1> N_12:	
  6375 0000204B FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  6376 0000204D 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  6377 0000204F F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  6378 00002052 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  6379 00002054 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  6380 00002057 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  6381 00002059 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  6382 0000205C EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  6383                              <1> N_720:
  6384 0000205E FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  6385 00002060 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  6386 00002062 EBE2                <1> 	JMP	SHORT F1_RATE
  6387                              <1> ISNT_12: 
  6388 00002064 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  6389                              <1> 
  6390                              <1> SKP_STATE:
  6391 00002067 88A7[09710000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  6392                              <1> F1_OUT:
  6393 0000206D C3                  <1> 	RETn
  6394                              <1> CL_DRV:	
  6395 0000206E 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  6396 00002070 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  6397                              <1> 
  6398                              <1> ;-------------------------------------------------------------------------------
  6399                              <1> ; MED_CHANGE	
  6400                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  6401                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  6402                              <1> ;
  6403                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  6404                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  6405                              <1> ;-------------------------------------------------------------------------------
  6406                              <1> MED_CHANGE:
  6407 00002072 E888060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  6408 00002077 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  6409 00002079 80A7[09710000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  6410                              <1> 
  6411                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  6412                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  6413                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  6414                              <1> 
  6415 00002080 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  6416 00002083 B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  6417 00002085 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  6418 00002087 F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  6419 00002089 FA                  <1> 	CLI				; NO INTERRUPTS
  6420 0000208A 2005[FA700000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  6421 00002090 FB                  <1> 	STI				; INTERRUPTS ENABLED
  6422 00002091 E810040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  6423                              <1> 
  6424                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  6425                              <1> 
  6426 00002096 E884F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  6427 0000209B B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  6428 0000209D E8FF040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6429 000020A2 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  6430 000020A4 E8F8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6431 000020A9 C605[FC700000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  6432                              <1> OK1:
  6433 000020B0 E84A060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  6434 000020B5 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  6435                              <1> OK4:
  6436 000020B7 C605[FC700000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  6437                              <1> OK2:		
  6438 000020BE F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  6439 000020BF C3                  <1> 	RETn
  6440                              <1> MC_OUT:
  6441 000020C0 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  6442 000020C1 C3                  <1> 	RETn
  6443                              <1> 
  6444                              <1> ;-------------------------------------------------------------------------------
  6445                              <1> ; SEND_RATE
  6446                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  6447                              <1> ; ON ENTRY:	DI = DRIVE #
  6448                              <1> ; ON EXIT:	NONE
  6449                              <1> ; REGISTERS ALTERED: DX
  6450                              <1> ;-------------------------------------------------------------------------------
  6451                              <1> SEND_RATE:
  6452 000020C2 6650                <1> 	PUSH	AX			; SAVE REG.
  6453 000020C4 8025[04710000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  6454 000020CB 8A87[09710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6455 000020D1 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  6456 000020D3 0805[04710000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  6457 000020D9 C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  6458 000020DC 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  6459 000020E0 EE                  <1> 	OUT	DX,AL
  6460 000020E1 6658                <1> 	POP	AX			; RESTORE REG.
  6461 000020E3 C3                  <1> 	RETn
  6462                              <1> 
  6463                              <1> ;-------------------------------------------------------------------------------
  6464                              <1> ; CHK_LASTRATE
  6465                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  6466                              <1> ; ON ENTRY:
  6467                              <1> ;	DI = DRIVE #
  6468                              <1> ; ON EXIT:
  6469                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  6470                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  6471                              <1> ; REGISTERS ALTERED: DX
  6472                              <1> ;-------------------------------------------------------------------------------
  6473                              <1> CHK_LASTRATE:
  6474 000020E4 6650                <1> 	PUSH	AX			; SAVE REG
  6475 000020E6 2225[04710000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  6476 000020EC 8A87[09710000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6477 000020F2 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  6478 000020F6 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  6479                              <1> 					; ZF = 1 RATE IS THE SAME
  6480 000020F8 6658                <1> 	POP	AX			; RESTORE REG.
  6481 000020FA C3                  <1> 	RETn
  6482                              <1> 
  6483                              <1> ;-------------------------------------------------------------------------------
  6484                              <1> ; DMA_SETUP
  6485                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  6486                              <1> ;
  6487                              <1> ; ON ENTRY:	AL = DMA COMMAND
  6488                              <1> ;
  6489                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6490                              <1> ;-------------------------------------------------------------------------------
  6491                              <1> 
  6492                              <1> ; SI = Head #, # of Sectors or DASD Type
  6493                              <1> 
  6494                              <1> ; 22/08/2015
  6495                              <1> ; 08/02/2015 - Protected Mode Modification
  6496                              <1> ; 06/02/2015 - 07/02/2015
  6497                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  6498                              <1> ; (DMA Addres = Physical Address)
  6499                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  6500                              <1> ;
  6501                              <1> 
  6502                              <1> ; 04/02/2016 (clc)
  6503                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  6504                              <1> ; 16/12/2014 (IODELAY)
  6505                              <1> 
  6506                              <1> DMA_SETUP:
  6507                              <1> 
  6508                              <1> ;; 20/02/2015
  6509 000020FB 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6510 000020FE F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  6511 00002104 756E                <1> 	jnz	short dma_bnd_err_stc
  6512                              <1> 	;
  6513 00002106 6650                <1> 	push	ax			; DMA command
  6514 00002108 52                  <1> 	push	edx			; *
  6515 00002109 B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  6516 0000210B E851030000          <1> 	call	GET_PARM		; 
  6517 00002110 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6518 00002112 6689F0              <1> 	mov	ax, si			; Sector count
  6519 00002115 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  6520 00002117 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  6521 00002119 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  6522 0000211C 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  6523 0000211F 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  6524 00002121 6689C1              <1> 	mov	cx, ax
  6525 00002124 5A                  <1> 	pop	edx			; *
  6526 00002125 6658                <1> 	pop	ax
  6527 00002127 3C42                <1> 	cmp	al, 42h
  6528 00002129 7507                <1>         jne     short NOT_VERF
  6529 0000212B BA0000FF00          <1> 	mov	edx, 0FF0000h
  6530 00002130 EB08                <1> 	jmp	short J33
  6531                              <1> NOT_VERF:
  6532 00002132 6601CA              <1> 	add	dx, cx			; check for overflow
  6533 00002135 723E                <1> 	jc	short dma_bnd_err
  6534                              <1> 	;
  6535 00002137 6629CA              <1> 	sub	dx, cx			; Restore start address
  6536                              <1> J33:
  6537 0000213A FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6538 0000213B E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6539                              <1> 	IODELAY				; WAIT FOR I/O
  6540 0000213D EB00                <2>  jmp short $+2
  6541 0000213F EB00                <2>  jmp short $+2
  6542 00002141 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6543 00002143 89D0                <1> 	mov	eax, edx		; Buffer address
  6544 00002145 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6545                              <1> 	IODELAY				; WAIT FOR I/O
  6546 00002147 EB00                <2>  jmp short $+2
  6547 00002149 EB00                <2>  jmp short $+2
  6548 0000214B 88E0                <1> 	MOV	AL,AH
  6549 0000214D E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6550 0000214F C1E810              <1> 	shr	eax, 16
  6551                              <1> 	IODELAY				; I/O WAIT STATE
  6552 00002152 EB00                <2>  jmp short $+2
  6553 00002154 EB00                <2>  jmp short $+2
  6554 00002156 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6555                              <1> 	IODELAY
  6556 00002158 EB00                <2>  jmp short $+2
  6557 0000215A EB00                <2>  jmp short $+2
  6558 0000215C 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  6559 0000215F E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6560                              <1> 	IODELAY				; WAIT FOR I/O
  6561 00002161 EB00                <2>  jmp short $+2
  6562 00002163 EB00                <2>  jmp short $+2
  6563 00002165 88E0                <1> 	MOV	AL, AH
  6564 00002167 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6565                              <1> 	IODELAY
  6566 00002169 EB00                <2>  jmp short $+2
  6567 0000216B EB00                <2>  jmp short $+2
  6568 0000216D FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6569 0000216E B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  6570 00002170 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6571                              <1> 
  6572 00002172 F8                  <1> 	clc	; 04/02/2016
  6573 00002173 C3                  <1> 	retn
  6574                              <1> 
  6575                              <1> dma_bnd_err_stc:
  6576 00002174 F9                  <1> 	stc
  6577                              <1> dma_bnd_err:
  6578 00002175 C605[FC700000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6579 0000217C C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  6580                              <1> 
  6581                              <1> ;; 16/12/2014
  6582                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6583                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6584                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6585                              <1> ;;	IODELAY
  6586                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6587                              <1> ;;	;SIODELAY
  6588                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  6589                              <1> ;;      ;JNE	short NOT_VERF		; NO
  6590                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  6591                              <1> ;;      ;JMP	SHORT J33
  6592                              <1> ;;;NOT_VERF:	
  6593                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  6594                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  6595                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  6596                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  6597                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  6598                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  6599                              <1> ;;	;JNC	short J33
  6600                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  6601                              <1> ;;;J33:
  6602                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  6603                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6604                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6605                              <1> ;;	IODELAY
  6606                              <1> ;;	MOV	AL,AH
  6607                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6608                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  6609                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  6610                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  6611                              <1> ;;	IODELAY
  6612                              <1> ;;	;AND	AL,00001111B
  6613                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  6614                              <1> ;;	;SIODELAY
  6615                              <1> ;;
  6616                              <1> ;;;----- DETERMINE COUNT
  6617                              <1> ;;	sub	eax, eax ; 08/02/2015
  6618                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  6619                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  6620                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  6621                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  6622                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  6623                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  6624                              <1> ;;	CALL	GET_PARM		; "
  6625                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6626                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  6627                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  6628                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  6629                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  6630                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6631                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6632                              <1> ;;	IODELAY
  6633                              <1> ;;	MOV	AL, AH
  6634                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6635                              <1> ;;	;IODELAY
  6636                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  6637                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  6638                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  6639                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  6640                              <1> ;;	add	ecx, eax ; 08/02/2015
  6641                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  6642                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6643                              <1> ;;	SIODELAY
  6644                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6645                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  6646                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  6647                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  6648                              <1> ;;	jz	short NO_BAD
  6649                              <1> ;;dma_bnd_err:
  6650                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6651                              <1> ;;NO_BAD:
  6652                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  6653                              <1> 
  6654                              <1> ;-------------------------------------------------------------------------------
  6655                              <1> ; FMTDMA_SET
  6656                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  6657                              <1> ;
  6658                              <1> ; ON ENTRY:	NOTHING REQUIRED
  6659                              <1> ;
  6660                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6661                              <1> ;-------------------------------------------------------------------------------
  6662                              <1> 
  6663                              <1> FMTDMA_SET:
  6664                              <1> ;; 20/02/2015 modification	
  6665 0000217D 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6666 00002180 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  6667 00002186 75EC                <1> 	jnz	short dma_bnd_err_stc
  6668                              <1> 	;
  6669 00002188 6652                <1> 	push	dx			; *
  6670 0000218A B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  6671 0000218C E8D0020000          <1> 	call	GET_PARM		; "
  6672 00002191 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  6673 00002193 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  6674 00002195 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  6675 00002199 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  6676 0000219B 6689C1              <1> 	mov	cx, ax
  6677 0000219E 665A                <1> 	pop	dx			; *
  6678 000021A0 6601CA              <1> 	add	dx, cx			; check for overflow
  6679 000021A3 72D0                <1> 	jc	short dma_bnd_err
  6680                              <1> 	;
  6681 000021A5 6629CA              <1> 	sub	dx, cx			; Restore start address
  6682                              <1> 	;
  6683 000021A8 B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  6684 000021AA FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6685 000021AB E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6686                              <1> 	IODELAY				; WAIT FOR I/O
  6687 000021AD EB00                <2>  jmp short $+2
  6688 000021AF EB00                <2>  jmp short $+2
  6689 000021B1 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6690 000021B3 89D0                <1> 	mov	eax, edx		; Buffer address
  6691 000021B5 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6692                              <1> 	IODELAY				; WAIT FOR I/O
  6693 000021B7 EB00                <2>  jmp short $+2
  6694 000021B9 EB00                <2>  jmp short $+2
  6695 000021BB 88E0                <1> 	MOV	AL,AH
  6696 000021BD E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6697 000021BF C1E810              <1> 	shr	eax, 16
  6698                              <1> 	IODELAY				; I/O WAIT STATE
  6699 000021C2 EB00                <2>  jmp short $+2
  6700 000021C4 EB00                <2>  jmp short $+2
  6701 000021C6 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6702                              <1> 	IODELAY
  6703 000021C8 EB00                <2>  jmp short $+2
  6704 000021CA EB00                <2>  jmp short $+2
  6705 000021CC 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  6706 000021CF E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6707                              <1> 	IODELAY				; WAIT FOR I/O
  6708 000021D1 EB00                <2>  jmp short $+2
  6709 000021D3 EB00                <2>  jmp short $+2
  6710 000021D5 88E0                <1> 	MOV	AL, AH
  6711 000021D7 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6712                              <1> 	IODELAY
  6713 000021D9 EB00                <2>  jmp short $+2
  6714 000021DB EB00                <2>  jmp short $+2
  6715 000021DD FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6716 000021DE B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  6717 000021E0 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6718 000021E2 C3                  <1> 	retn
  6719                              <1> 
  6720                              <1> ;; 08/02/2015 - Protected Mode Modification
  6721                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  6722                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6723                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6724                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6725                              <1> ;;	IODELAY
  6726                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6727                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  6728                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  6729                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  6730                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  6731                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  6732                              <1> ;;	;JNC	short J33A
  6733                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  6734                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  6735                              <1> ;;;J33A:
  6736                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  6737                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6738                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6739                              <1> ;;	IODELAY
  6740                              <1> ;;	MOV	AL,AH
  6741                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6742                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  6743                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  6744                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  6745                              <1> ;;	IODELAY
  6746                              <1> ;;	;AND	AL,00001111B
  6747                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  6748                              <1> ;;
  6749                              <1> ;;;----- DETERMINE COUNT
  6750                              <1> ;;	sub	eax, eax ; 08/02/2015
  6751                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  6752                              <1> ;;	CALL	GET_PARM		; "
  6753                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  6754                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  6755                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  6756                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  6757                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  6758                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6759                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6760                              <1> ;;	IODELAY
  6761                              <1> ;;	MOV	AL, AH
  6762                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6763                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  6764                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  6765                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  6766                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  6767                              <1> ;;	add	ecx, eax ; 08/02/2015
  6768                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  6769                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6770                              <1> ;;	SIODELAY
  6771                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6772                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  6773                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  6774                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  6775                              <1> ;;	jz	short FMTDMA_OK
  6776                              <1> ;;	stc	; 20/02/2015
  6777                              <1> ;;fmtdma_bnd_err:
  6778                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6779                              <1> ;;FMTDMA_OK:
  6780                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  6781                              <1> 
  6782                              <1> ;-------------------------------------------------------------------------------
  6783                              <1> ; NEC_INIT	
  6784                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  6785                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  6786                              <1> ;
  6787                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  6788                              <1> ;
  6789                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6790                              <1> ;-------------------------------------------------------------------------------
  6791                              <1> NEC_INIT:
  6792 000021E3 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6793 000021E5 E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  6794                              <1> 
  6795                              <1> ;-----	DO THE SEEK OPERATION
  6796                              <1> 
  6797 000021EA 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  6798 000021ED E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  6799 000021F2 6658                <1> 	POP	AX			; RECOVER COMMAND
  6800 000021F4 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  6801 000021F6 BB[14220000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  6802 000021FB 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  6803                              <1> 
  6804                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  6805                              <1> 
  6806 000021FC E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  6807 00002201 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  6808 00002204 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  6809 00002206 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  6810 00002209 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  6811 0000220C 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  6812 0000220E E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  6813 00002213 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  6814                              <1> ER_1:
  6815 00002214 C3                  <1> 	RETn
  6816                              <1> 
  6817                              <1> ;-------------------------------------------------------------------------------
  6818                              <1> ; RWV_COM
  6819                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  6820                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  6821                              <1> ;
  6822                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  6823                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6824                              <1> ;-------------------------------------------------------------------------------
  6825                              <1> RWV_COM:
  6826 00002215 B8[60220000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  6827 0000221A 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6828 0000221B 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  6829 0000221E E844030000          <1> 	CALL	NEC_OUTPUT
  6830 00002223 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  6831 00002226 E83C030000          <1> 	CALL	NEC_OUTPUT
  6832 0000222B 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  6833 0000222E E834030000          <1> 	CALL	NEC_OUTPUT
  6834 00002233 B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  6835 00002235 E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  6836 0000223A E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6837 0000223F B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  6838 00002241 E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  6839 00002246 E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6840 0000224B 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  6841                              <1> _R15:
  6842 0000224E E814030000          <1> 	CALL	NEC_OUTPUT
  6843 00002253 B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  6844 00002255 E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  6845 0000225A E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6846 0000225F 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  6847                              <1> ER_2:
  6848 00002260 C3                  <1> 	RETn
  6849                              <1> 
  6850                              <1> ;-------------------------------------------------------------------------------
  6851                              <1> ; NEC_TERM
  6852                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  6853                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  6854                              <1> ;
  6855                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6856                              <1> ;-------------------------------------------------------------------------------
  6857                              <1> NEC_TERM:
  6858                              <1> 
  6859                              <1> ;-----	LET THE OPERATION HAPPEN
  6860                              <1> 
  6861 00002261 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  6862 00002262 E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  6863 00002267 9C                  <1> 	PUSHF
  6864 00002268 E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  6865 0000226D 724B                <1> 	JC	short SET_END_POP
  6866 0000226F 9D                  <1> 	POPF
  6867 00002270 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  6868                              <1> 
  6869                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  6870                              <1> 
  6871 00002272 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  6872 00002273 BE[FD700000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  6873 00002278 AC                  <1> 	lodsb				; GET ST0
  6874 00002279 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  6875 0000227B 7433                <1> 	JZ	short SET_END
  6876 0000227D 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  6877 0000227F 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  6878                              <1> 
  6879                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  6880                              <1> 
  6881 00002281 AC                  <1> 	lodsb				; GET ST1
  6882 00002282 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  6883 00002284 B404                <1> 	MOV	AH,RECORD_NOT_FND
  6884 00002286 7222                <1> 	JC	short J19
  6885 00002288 C0E002              <1> 	SAL	AL,2
  6886 0000228B B410                <1> 	MOV	AH,BAD_CRC
  6887 0000228D 721B                <1> 	JC	short J19
  6888 0000228F D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  6889 00002291 B408                <1> 	MOV	AH,BAD_DMA
  6890 00002293 7215                <1> 	JC	short J19
  6891 00002295 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  6892 00002298 B404                <1> 	MOV	AH,RECORD_NOT_FND
  6893 0000229A 720E                <1> 	JC	short J19
  6894 0000229C D0E0                <1> 	SAL	AL,1
  6895 0000229E B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  6896 000022A0 7208                <1> 	JC	short J19
  6897 000022A2 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  6898 000022A4 B402                <1> 	MOV	AH,BAD_ADDR_MARK
  6899 000022A6 7202                <1> 	JC	short J19
  6900                              <1> 
  6901                              <1> ;----- 	NEC MUST HAVE FAILED
  6902                              <1> J18:
  6903 000022A8 B420                <1> 	MOV	AH,BAD_NEC
  6904                              <1> J19:
  6905 000022AA 0825[FC700000]      <1> 	OR	[DSKETTE_STATUS], AH
  6906                              <1> SET_END:
  6907 000022B0 803D[FC700000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  6908 000022B7 F5                  <1> 	CMC
  6909 000022B8 5E                  <1> 	POP	eSI
  6910 000022B9 C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  6911                              <1> 
  6912                              <1> SET_END_POP:
  6913 000022BA 9D                  <1> 	POPF
  6914 000022BB EBF3                <1> 	JMP	SHORT SET_END
  6915                              <1> 
  6916                              <1> ;-------------------------------------------------------------------------------
  6917                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  6918                              <1> ;-------------------------------------------------------------------------------
  6919                              <1> DSTATE:
  6920 000022BD 803D[FC700000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  6921 000022C4 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  6922 000022C6 808F[09710000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  6923 000022CD F687[09710000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  6924 000022D4 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  6925 000022D6 8A87[09710000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  6926 000022DC 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  6927 000022DE 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  6928 000022E0 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  6929                              <1> 
  6930                              <1> ;----- 	CHECK IF IT IS 1.44M
  6931                              <1> 
  6932 000022E2 E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6933                              <1> 	;;20/02/2015
  6934                              <1> 	;;JC	short M_12		; CMOS BAD
  6935 000022E7 7414                <1> 	jz	short M_12 ;; 20/02/2015
  6936 000022E9 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  6937 000022EB 7410                <1> 	JE	short M_12		; YES
  6938                              <1> M_720:
  6939 000022ED 80A7[09710000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  6940 000022F4 808F[09710000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  6941 000022FB EB07                <1> 	JMP	SHORT SETBAC		; BACK
  6942                              <1> M_12:	
  6943 000022FD 808F[09710000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  6944                              <1> 					; TURN ON DETERMINED & FMT CAPA
  6945                              <1> SETBAC:
  6946 00002304 C3                  <1> 	RETn
  6947                              <1> 
  6948                              <1> ;-------------------------------------------------------------------------------
  6949                              <1> ; RETRY	
  6950                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  6951                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  6952                              <1> ;
  6953                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  6954                              <1> ;-------------------------------------------------------------------------------
  6955                              <1> RETRY:
  6956 00002305 803D[FC700000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  6957 0000230C 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  6958 0000230E 803D[FC700000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  6959 00002315 743C                <1> 	JZ	short NO_RETRY
  6960 00002317 8AA7[09710000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  6961 0000231D F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  6962 00002320 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  6963 00002322 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  6964 00002325 8A2D[04710000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  6965 0000232B C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  6966 0000232E 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  6967 00002331 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  6968 00002333 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  6969                              <1> 
  6970                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  6971                              <1> ;	 00000000B (500) -> 10000000B	(250)
  6972                              <1> ;	 10000000B (250) -> 01000000B	(300)
  6973                              <1> ;	 01000000B (300) -> 00000000B	(500)
  6974                              <1> 
  6975 00002335 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  6976 00002338 D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  6977 0000233A 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  6978 0000233D 80A7[09710000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  6979                              <1> 					; RATE, DBL STEP OFF
  6980 00002344 08A7[09710000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  6981 0000234A C605[FC700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  6982 00002351 F9                  <1> 	STC				; SET CARRY FOR RETRY
  6983 00002352 C3                  <1> 	RETn				; RETRY RETURN
  6984                              <1> 
  6985                              <1> NO_RETRY:
  6986 00002353 F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  6987 00002354 C3                  <1> 	RETn				; NO RETRY RETURN
  6988                              <1> 
  6989                              <1> ;-------------------------------------------------------------------------------
  6990                              <1> ; NUM_TRANS
  6991                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  6992                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  6993                              <1> ;
  6994                              <1> ; ON ENTRY:	[BP+1] = TRACK
  6995                              <1> ;		SI-HI  = HEAD
  6996                              <1> ;		[BP]   = START SECTOR
  6997                              <1> ;
  6998                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  6999                              <1> ;-------------------------------------------------------------------------------
  7000                              <1> NUM_TRANS:
  7001 00002355 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  7002 00002357 803D[FC700000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  7003 0000235E 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  7004 00002360 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  7005 00002362 E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  7006 00002367 8A1D[02710000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  7007 0000236D 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  7008 00002370 3A2D[01710000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  7009 00002376 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  7010 00002378 8A2D[00710000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  7011 0000237E 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  7012 00002381 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  7013 00002383 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7014                              <1> DIF_HD:
  7015 00002385 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7016                              <1> SAME_TRK:
  7017 00002387 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  7018 0000238A 88D8                <1> 	MOV	AL,BL			; TO AL
  7019                              <1> NT_OUT:
  7020 0000238C C3                  <1> 	RETn
  7021                              <1> 
  7022                              <1> ;-------------------------------------------------------------------------------
  7023                              <1> ; SETUP_END
  7024                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  7025                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  7026                              <1> ;
  7027                              <1> ; ON EXIT:
  7028                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7029                              <1> ;-------------------------------------------------------------------------------
  7030                              <1> SETUP_END:
  7031 0000238D B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  7032 0000238F 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  7033 00002391 E8CB000000          <1> 	CALL	GET_PARM
  7034 00002396 8825[FB700000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  7035 0000239C 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  7036 0000239E 8A25[FC700000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  7037 000023A4 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  7038 000023A6 7402                <1> 	JZ	short NUN_ERR			; NO ERROR
  7039 000023A8 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  7040                              <1> NUN_ERR: 
  7041 000023AA 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  7042 000023AD F5                  <1> 	CMC				; SUCCESS OR FAILURE
  7043 000023AE C3                  <1> 	RETn
  7044                              <1> 
  7045                              <1> ;-------------------------------------------------------------------------------
  7046                              <1> ; SETUP_DBL
  7047                              <1> ;	CHECK DOUBLE STEP.
  7048                              <1> ;
  7049                              <1> ; ON ENTRY :	DI = DRIVE
  7050                              <1> ;
  7051                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  7052                              <1> ;-------------------------------------------------------------------------------
  7053                              <1> SETUP_DBL:
  7054 000023AF 8AA7[09710000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  7055 000023B5 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  7056 000023B8 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  7057                              <1> 
  7058                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  7059                              <1> 
  7060 000023BA C605[F9700000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  7061 000023C1 E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  7062 000023C6 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  7063 000023C8 E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  7064 000023CD E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  7065 000023D2 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  7066                              <1> 
  7067                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  7068                              <1> 
  7069 000023D4 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  7070 000023D8 F687[09710000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  7071 000023DF 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  7072 000023E1 B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  7073                              <1> 
  7074                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  7075                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  7076                              <1> ;	THEN SET DOUBLE STEP ON.
  7077                              <1> 
  7078                              <1> CNT_OK:
  7079 000023E3 C605[FB700000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  7080 000023EA 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  7081 000023EC C605[FC700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  7082 000023F3 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  7083 000023F6 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  7084 000023F8 C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  7085 000023FB 6650                <1> 	PUSH	AX			; SAVE HEAD
  7086 000023FD E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  7087 00002402 6658                <1> 	POP	AX			; RESTORE HEAD
  7088 00002404 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  7089 00002407 E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  7090 0000240C 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  7091 0000240D 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  7092 00002412 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  7093 00002413 6659                <1> 	POP	CX			; RESTORE COUNT
  7094 00002415 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  7095 00002417 FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  7096 00002419 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  7097 0000241B 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  7098                              <1> 
  7099                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  7100                              <1> 
  7101                              <1> SD_ERR:	
  7102 0000241D F9                  <1> 	STC				; SET CARRY FOR ERROR
  7103 0000241E C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  7104                              <1> 
  7105                              <1> DO_CHK:
  7106 0000241F 8A0D[00710000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  7107 00002425 888F[0D710000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  7108 0000242B D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  7109 0000242D 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  7110 0000242F 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  7111 00002431 808F[09710000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  7112                              <1> NO_DBL:
  7113 00002438 F8                  <1> 	CLC				; CLEAR ERROR FLAG
  7114 00002439 C3                  <1> 	RETn
  7115                              <1> 
  7116                              <1> ;-------------------------------------------------------------------------------
  7117                              <1> ; READ_ID
  7118                              <1> ;	READ ID FUNCTION.
  7119                              <1> ;
  7120                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  7121                              <1> ;
  7122                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  7123                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7124                              <1> ;-------------------------------------------------------------------------------
  7125                              <1> READ_ID:
  7126 0000243A B8[57240000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  7127 0000243F 50                  <1> 	PUSH	eAX
  7128 00002440 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  7129 00002442 E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7130 00002447 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  7131 0000244A 88C4                <1> 	MOV	AH,AL
  7132 0000244C E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7133 00002451 E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  7134 00002456 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  7135                              <1> ER_3:
  7136 00002457 C3                  <1> 	RETn
  7137                              <1> 
  7138                              <1> ;-------------------------------------------------------------------------------
  7139                              <1> ; CMOS_TYPE
  7140                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  7141                              <1> ;
  7142                              <1> ; ON ENTRY:	DI = DRIVE #
  7143                              <1> ;
  7144                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  7145                              <1> ;-------------------------------------------------------------------------------
  7146                              <1> 
  7147                              <1> CMOS_TYPE: ; 11/12/2014
  7148 00002458 8A87[2E6B0000]      <1> mov	al, [eDI+fd0_type]
  7149 0000245E 20C0                <1> and 	al, al ; 18/12/2014
  7150 00002460 C3                  <1> retn
  7151                              <1> 
  7152                              <1> ;CMOS_TYPE:
  7153                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  7154                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  7155                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  7156                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  7157                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  7158                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  7159                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  7160                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  7161                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  7162                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  7163                              <1> ;TB:
  7164                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  7165                              <1> ;BAD_CM:
  7166                              <1> ;	RETn				; CY, STATUS OF READ
  7167                              <1> 
  7168                              <1> ;-------------------------------------------------------------------------------
  7169                              <1> ; GET_PARM
  7170                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  7171                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  7172                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  7173                              <1> ;	THE PARAMETER IN DL.
  7174                              <1> ;
  7175                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  7176                              <1> ;
  7177                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  7178                              <1> ;		AL,DH DESTROYED
  7179                              <1> ;-------------------------------------------------------------------------------
  7180                              <1> GET_PARM:
  7181                              <1> 	;PUSH	DS
  7182 00002461 56                  <1> 	PUSH	eSI
  7183                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  7184                              <1>     	;MOV	DS,AX
  7185                              <1> 	;;mov	ax, cs
  7186                              <1> 	;;mov	ds, ax
  7187                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  7188 00002462 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  7189                              <1> 	;SUB	BH,BH			; BX = INDEX
  7190 00002464 81E3FF000000        <1> 	and	ebx, 0FFh
  7191                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  7192                              <1> 	;
  7193                              <1> 	; 17/12/2014
  7194 0000246A 66A1[216B0000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  7195 00002470 38E0                <1> 	cmp	al, ah
  7196 00002472 7425                <1> 	je	short gpndc
  7197 00002474 A2[226B0000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  7198 00002479 53                  <1> 	push	ebx ; 08/02/2015
  7199 0000247A 88C3                <1> 	mov	bl, al 
  7200                              <1> 	; 11/12/2014
  7201 0000247C 8A83[2E6B0000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  7202                              <1> 	; 18/12/2014
  7203 00002482 20C0                <1> 	and	al, al
  7204 00002484 7507                <1> 	jnz	short gpdtc
  7205 00002486 BB[0B6B0000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  7206 0000248B EB05                <1>         jmp     short gpdpu
  7207                              <1> gpdtc:	
  7208 0000248D E817F9FFFF          <1> 	call	DR_TYPE_CHECK
  7209                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  7210                              <1> gpdpu:
  7211 00002492 891D[A86A0000]      <1> 	mov	[DISK_POINTER], ebx
  7212 00002498 5B                  <1> 	pop	ebx
  7213                              <1> gpndc:
  7214 00002499 8B35[A86A0000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  7215 0000249F 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  7216 000024A2 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  7217 000024A4 5E                  <1> 	POP	eSI
  7218                              <1> 	;POP	DS
  7219 000024A5 C3                  <1> 	RETn
  7220                              <1> 
  7221                              <1> ;-------------------------------------------------------------------------------
  7222                              <1> ; MOTOR_ON
  7223                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  7224                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  7225                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  7226                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  7227                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  7228                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  7229                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  7230                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  7231                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  7232                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  7233                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  7234                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  7235                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  7236                              <1> ;
  7237                              <1> ; ON ENTRY:	DI = DRIVE #
  7238                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  7239                              <1> ;-------------------------------------------------------------------------------
  7240                              <1> MOTOR_ON:
  7241 000024A6 53                  <1> 	PUSH	eBX			; SAVE REG.
  7242 000024A7 E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  7243 000024AC 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  7244 000024AE E89BF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7245 000024B3 E865F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  7246                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  7247                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  7248                              <1> M_WAIT:
  7249 000024B8 B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  7250 000024BA E8A2FFFFFF          <1> 	CALL	GET_PARM
  7251                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  7252                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  7253                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  7254 000024BF 80FC08              <1> 	cmp	ah, 8
  7255                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  7256 000024C2 7702                <1> 	ja	short J13
  7257                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  7258 000024C4 B408                <1> 	mov	ah, 8
  7259                              <1> 
  7260                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  7261                              <1> GP2:	
  7262                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  7263                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  7264 000024C6 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  7265 000024CB E819F1FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  7266                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  7267 000024D0 FECC                <1> 	dec	ah
  7268 000024D2 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  7269                              <1> MOT_IS_ON:
  7270 000024D4 5B                  <1> 	POP	eBX			; RESTORE REG.
  7271 000024D5 C3                  <1> 	RETn
  7272                              <1> 
  7273                              <1> ;-------------------------------------------------------------------------------
  7274                              <1> ; TURN_ON
  7275                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  7276                              <1> ;
  7277                              <1> ; ON ENTRY:	DI = DRIVE #
  7278                              <1> ;
  7279                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  7280                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  7281                              <1> ;		AX,BX,CX,DX DESTROYED
  7282                              <1> ;-------------------------------------------------------------------------------
  7283                              <1> TURN_ON:
  7284 000024D6 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7285 000024D8 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  7286 000024DA C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  7287 000024DD FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  7288 000024DE C605[FB700000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  7289 000024E5 A0[FA700000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7290 000024EA 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  7291 000024EC B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  7292 000024EE D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  7293                              <1> 
  7294                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  7295                              <1> ;  BL = DRIVE SELECT DESIRED
  7296                              <1> ;  AH = MOTOR ON MASK DESIRED
  7297                              <1> 
  7298 000024F0 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  7299 000024F2 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  7300 000024F4 8425[FA700000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  7301 000024FA 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  7302                              <1> 
  7303                              <1> TURN_IT_ON:
  7304 000024FC 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  7305 000024FE 8A3D[FA700000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  7306 00002504 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  7307 00002507 8025[FA700000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  7308 0000250E 0825[FA700000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  7309 00002514 A0[FA700000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7310 00002519 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  7311 0000251B 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  7312 0000251E FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  7313 0000251F 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  7314 00002521 C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  7315 00002524 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  7316 00002526 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  7317 0000252A EE                  <1> 	OUT	DX,AL
  7318 0000252B 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  7319                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  7320 0000252D 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  7321 0000252F F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  7322 00002530 C3                  <1> 	RETn
  7323                              <1> 
  7324                              <1> NO_MOT_WAIT:
  7325 00002531 FB                  <1> 	sti
  7326                              <1> no_mot_w1: ; 27/02/2015
  7327 00002532 F9                  <1> 	STC				; SET NO WAIT REQUIRED
  7328                              <1> 	;STI				; INTERRUPTS BACK ON
  7329 00002533 C3                  <1> 	RETn
  7330                              <1> 
  7331                              <1> ;-------------------------------------------------------------------------------
  7332                              <1> ; HD_WAIT
  7333                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  7334                              <1> ;
  7335                              <1> ; ON ENTRY:	DI = DRIVE #
  7336                              <1> ;
  7337                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  7338                              <1> ;-------------------------------------------------------------------------------
  7339                              <1> HD_WAIT:
  7340 00002534 B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  7341 00002536 E826FFFFFF          <1> 	CALL	GET_PARM
  7342 0000253B 08E4                <1> 	or	ah, ah	; 17/12/2014
  7343 0000253D 7519                <1> 	jnz	short DO_WAT
  7344 0000253F F605[FA700000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  7345                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  7346                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  7347                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  7348 00002546 741E                <1> 	jz	short HW_DONE
  7349 00002548 B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  7350 0000254A 8A87[09710000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  7351 00002550 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  7352 00002552 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  7353 00002554 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  7354                              <1> ;GP3:
  7355 00002556 B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  7356                              <1> ;	JMP	SHORT DO_WAT
  7357                              <1> 
  7358                              <1> ;ISNT_WRITE:
  7359                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  7360                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  7361                              <1> 
  7362                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  7363                              <1> DO_WAT:
  7364                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  7365                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  7366                              <1> J29:					; 	1 MILLISECOND LOOP
  7367                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  7368 00002558 B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  7369 0000255D E887F0FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  7370                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  7371 00002562 FECC                <1> 	dec	ah
  7372 00002564 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  7373                              <1> HW_DONE:
  7374 00002566 C3                  <1> 	RETn
  7375                              <1> 
  7376                              <1> ;-------------------------------------------------------------------------------
  7377                              <1> ; NEC_OUTPUT
  7378                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  7379                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  7380                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  7381                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  7382                              <1> ; 
  7383                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  7384                              <1> ;
  7385                              <1> ; ON EXIT:	CY = 0  SUCCESS
  7386                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  7387                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  7388                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  7389                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  7390                              <1> ;		AX,CX,DX DESTROYED
  7391                              <1> ;-------------------------------------------------------------------------------
  7392                              <1> 
  7393                              <1> ; 09/12/2014 [Erdogan Tan] 
  7394                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  7395                              <1> ; Diskette Drive Controller Status Register (3F4h)
  7396                              <1> ;	This read only register facilitates the transfer of data between
  7397                              <1> ;	the system microprocessor and the controller.
  7398                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  7399                              <1> ;	  with the system micrprocessor.
  7400                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  7401                              <1> ;	  the transfer is to the controller.
  7402                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  7403                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  7404                              <1> ; Bit 3 - Reserved.
  7405                              <1> ; Bit 2 - Reserved.
  7406                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7407                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7408                              <1> 
  7409                              <1> ; Data Register (3F5h)
  7410                              <1> ; This read/write register passes data, commands and parameters, and provides
  7411                              <1> ; diskette status information.
  7412                              <1>   		
  7413                              <1> NEC_OUTPUT:
  7414                              <1> 	;PUSH	BX			; SAVE REG.
  7415 00002567 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  7416                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  7417                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  7418                              <1> 	; 16/12/2014
  7419                              <1> 	; waiting for (max.) 0.5 seconds
  7420                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  7421                              <1> 	;
  7422                              <1> 	; 17/12/2014
  7423                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  7424                              <1> 	;
  7425                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  7426                              <1> 	;		go on.
  7427                              <1> 	;INPUT:
  7428                              <1> 	;	AH=Mask for isolation bits.
  7429                              <1> 	;	AL=pattern to look for.
  7430                              <1> 	;	DX=Port to test for
  7431                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7432                              <1> 	;	     (normally 30 microseconds per period.)
  7433                              <1> 	;
  7434                              <1> 	;WFP_SHORT:  
  7435                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  7436                              <1> 	;
  7437                              <1> 
  7438                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  7439                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  7440 0000256B B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  7441                              <1> ;
  7442                              <1> ;WFPS_OUTER_LP:
  7443                              <1> ;	;
  7444                              <1> ;WFPS_CHECK_PORT:
  7445                              <1> J23:
  7446 00002570 EC                  <1> 	IN	AL,DX			; GET STATUS
  7447 00002571 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7448 00002573 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7449 00002575 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  7450                              <1> WFPS_HI:
  7451 00002577 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  7452 00002579 A810                <1> 	TEST	AL,010H			; transition on memory
  7453 0000257B 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  7454                              <1> WFPS_LO:
  7455 0000257D E461                <1> 	IN	AL, PORT_B		; SYS1
  7456 0000257F A810                <1> 	TEST	AL,010H
  7457 00002581 74FA                <1> 	JZ	SHORT WFPS_LO
  7458                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  7459 00002583 E2EB                <1> 	loop	J23	; 27/02/2015
  7460                              <1> ;	;
  7461                              <1> ;	dec	bl
  7462                              <1> ;	jnz	short WFPS_OUTER_LP
  7463                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  7464                              <1> ;J23:
  7465                              <1> ;	IN	AL,DX			; GET STATUS
  7466                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7467                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7468                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  7469                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  7470                              <1> 	;DEC	BL			; DECREMENT COUNTER
  7471                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  7472                              <1>    
  7473                              <1> 	;;27/02/2015
  7474                              <1> 	;16/12/2014
  7475                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  7476                              <1> 	;;jb	short J23
  7477                              <1> 
  7478                              <1> ;WFPS_TIMEOUT:
  7479                              <1> 
  7480                              <1> ;-----	FALL THRU TO ERROR RETURN
  7481                              <1> 
  7482 00002585 800D[FC700000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  7483                              <1> 	;POP	BX			; RESTORE REG.
  7484 0000258C 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  7485 0000258D F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  7486 0000258E C3                  <1> 	RETn
  7487                              <1> 
  7488                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  7489                              <1> 
  7490                              <1> J27:	
  7491 0000258F 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  7492 00002591 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  7493 00002593 EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  7494                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  7495                              <1> 	; 27/02/2015
  7496 00002594 9C                  <1> 	PUSHF				; SAVE FLAGS
  7497 00002595 B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  7498 0000259A E84AF0FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  7499 0000259F 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  7500                              <1> 	;POP	BX			; RESTORE REG
  7501 000025A0 C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  7502                              <1> 
  7503                              <1> ;-------------------------------------------------------------------------------
  7504                              <1> ; SEEK
  7505                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  7506                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  7507                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  7508                              <1> ;
  7509                              <1> ; ON ENTRY:	DI = DRIVE #
  7510                              <1> ;		CH = TRACK #
  7511                              <1> ;
  7512                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7513                              <1> ;		AX,BX,CX DX DESTROYED
  7514                              <1> ;-------------------------------------------------------------------------------
  7515                              <1> SEEK:
  7516 000025A1 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7517 000025A3 B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  7518 000025A5 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  7519 000025A7 D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  7520 000025A9 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  7521 000025AB 8405[F9700000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  7522 000025B1 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  7523                              <1> 
  7524 000025B3 0805[F9700000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  7525 000025B9 E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7526 000025BE 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  7527                              <1> 
  7528                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  7529                              <1> 
  7530 000025C0 C605[FC700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  7531 000025C7 E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7532 000025CC 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  7533                              <1> 
  7534                              <1> AFT_RECAL:
  7535 000025CE C687[0D710000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  7536 000025D5 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  7537 000025D7 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  7538                              <1> 
  7539                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  7540                              <1> 
  7541 000025D9 F687[09710000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  7542 000025E0 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  7543 000025E2 D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  7544                              <1> 
  7545 000025E4 3AAF[0D710000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  7546 000025EA 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  7547                              <1> 
  7548 000025EC BA[1F260000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  7549 000025F1 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  7550 000025F2 88AF[0D710000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  7551 000025F8 B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  7552 000025FA E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  7553 000025FF 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7554 00002601 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  7555 00002603 E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  7556 00002608 8AA7[0D710000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  7557 0000260E E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  7558 00002613 E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  7559                              <1> 
  7560                              <1> ;-----	WAIT FOR HEAD SETTLE
  7561                              <1> 
  7562                              <1> DO_WAIT:
  7563 00002618 9C                  <1> 	PUSHF				; SAVE STATUS
  7564 00002619 E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  7565 0000261E 9D                  <1> 	POPF				; RESTORE STATUS
  7566                              <1> RB:
  7567                              <1> NEC_ERR:
  7568                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  7569                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  7570 0000261F C3                  <1> 	RETn				; RETURN TO CALLER
  7571                              <1> 
  7572                              <1> ;-------------------------------------------------------------------------------
  7573                              <1> ; RECAL
  7574                              <1> ;	RECALIBRATE DRIVE
  7575                              <1> ;
  7576                              <1> ; ON ENTRY:	DI = DRIVE #
  7577                              <1> ;
  7578                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  7579                              <1> ;-------------------------------------------------------------------------------
  7580                              <1> RECAL:
  7581 00002620 6651                <1> 	PUSH	CX
  7582 00002622 B8[3E260000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  7583 00002627 50                  <1> 	PUSH	eAX
  7584 00002628 B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  7585 0000262A E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  7586 0000262F 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7587 00002631 88DC                <1> 	MOV	AH,BL
  7588 00002633 E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  7589 00002638 E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  7590 0000263D 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  7591                              <1> RC_BACK:
  7592 0000263E 6659                <1> 	POP	CX
  7593 00002640 C3                  <1> 	RETn
  7594                              <1> 
  7595                              <1> ;-------------------------------------------------------------------------------
  7596                              <1> ; CHK_STAT_2
  7597                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  7598                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  7599                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  7600                              <1> ;
  7601                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7602                              <1> ;-------------------------------------------------------------------------------
  7603                              <1> CHK_STAT_2:
  7604 00002641 B8[69260000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  7605 00002646 50                  <1> 	PUSH	eAX
  7606 00002647 E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  7607 0000264C 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  7608 0000264E B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  7609 00002650 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  7610 00002655 E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  7611 0000265A 720C                <1> 	JC	short J34
  7612 0000265C A0[FD700000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  7613 00002661 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  7614 00002663 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  7615 00002665 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  7616 00002667 F8                  <1> 	CLC				; GOOD RETURN
  7617                              <1> J34:
  7618 00002668 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  7619                              <1> CS_BACK:
  7620 00002669 C3                  <1> 	RETn
  7621                              <1> J35:
  7622 0000266A 800D[FC700000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  7623 00002671 F9                  <1> 	STC				; ERROR RETURN CODE
  7624 00002672 EBF4                <1> 	JMP	SHORT J34
  7625                              <1> 
  7626                              <1> ;-------------------------------------------------------------------------------
  7627                              <1> ; WAIT_INT
  7628                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  7629                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  7630                              <1> ;	IF THE DRIVE IS NOT READY.
  7631                              <1> ;
  7632                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7633                              <1> ;-------------------------------------------------------------------------------
  7634                              <1> 
  7635                              <1> ; 17/12/2014
  7636                              <1> ; 2.5 seconds waiting !
  7637                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  7638                              <1> ; amount of time to wait for completion interrupt from NEC.
  7639                              <1> 
  7640                              <1> 
  7641                              <1> WAIT_INT:
  7642 00002674 FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  7643 00002675 F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  7644                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  7645                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  7646                              <1> 
  7647                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  7648                              <1> 	;
  7649                              <1> 	;WAIT_FOR_MEM:	
  7650                              <1> 	;	Waits for a bit at a specified memory location pointed
  7651                              <1> 	;	to by ES:[DI] to become set.
  7652                              <1> 	;INPUT:
  7653                              <1> 	;	AH=Mask to test with.
  7654                              <1> 	;	ES:[DI] = memory location to watch.
  7655                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7656                              <1> 	;	     (normally 30 microseconds per period.)
  7657                              <1> 
  7658                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  7659                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  7660                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  7661                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  7662                              <1> 	; 27/02/2015
  7663 00002676 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  7664                              <1> WFMS_CHECK_MEM:
  7665 0000267B F605[F9700000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7666 00002682 7516                <1>         jnz     short J37
  7667                              <1> WFMS_HI:
  7668 00002684 E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  7669 00002686 A810                <1> 	TEST	AL,010H			; transition on memory
  7670 00002688 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  7671                              <1> WFMS_LO:
  7672 0000268A E461                <1> 	IN	AL,PORT_B		;SYS1
  7673 0000268C A810                <1> 	TEST	AL,010H
  7674 0000268E 74FA                <1> 	JZ	SHORT WFMS_LO
  7675 00002690 E2E9                <1>         LOOP    WFMS_CHECK_MEM
  7676                              <1> ;WFMS_OUTER_LP:
  7677                              <1> ;;	or	bl, bl			; check outer counter
  7678                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  7679                              <1> ;	dec	bl
  7680                              <1> ;	jz	short J36A	
  7681                              <1> ;	jmp	short WFMS_CHECK_MEM
  7682                              <1> 
  7683                              <1> 	;17/12/2014
  7684                              <1> 	;16/12/2014
  7685                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  7686                              <1> ;J36:
  7687                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7688                              <1> ;	JNZ	short J37
  7689                              <1> 	;16/12/2014
  7690                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  7691                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  7692                              <1> 	;JNZ	short J36
  7693                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  7694                              <1> ;	jb	short J36
  7695                              <1> 
  7696                              <1> ;WFMS_TIMEOUT:
  7697                              <1> ;J36A:
  7698 00002692 800D[FC700000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  7699 00002699 F9                  <1> 	STC				; ERROR RETURN
  7700                              <1> J37:
  7701 0000269A 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  7702 0000269B 8025[F9700000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  7703 000026A2 9D                  <1> 	POPF				; RECOVER CARRY
  7704 000026A3 C3                  <1> 	RETn				; GOOD RETURN CODE
  7705                              <1> 
  7706                              <1> ;-------------------------------------------------------------------------------
  7707                              <1> ; RESULTS
  7708                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  7709                              <1> ;	FOLLOWING AN INTERRUPT.
  7710                              <1> ;
  7711                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7712                              <1> ;		AX,BX,CX,DX DESTROYED
  7713                              <1> ;-------------------------------------------------------------------------------
  7714                              <1> RESULTS:
  7715 000026A4 57                  <1> 	PUSH	eDI
  7716 000026A5 BF[FD700000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  7717 000026AA B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  7718 000026AC 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  7719                              <1> 
  7720                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  7721                              <1> 
  7722                              <1> _R10: 
  7723                              <1> 	; 16/12/2014
  7724                              <1> 	; wait for (max) 0.5 seconds
  7725                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  7726                              <1> 	;XOR	CX,CX			; COUNTER
  7727                              <1> 
  7728                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  7729                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  7730                              <1> 	; 27/02/2015
  7731 000026B0 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  7732                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  7733                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  7734                              <1> 
  7735                              <1> WFPSR_OUTER_LP:
  7736                              <1> 	;
  7737                              <1> WFPSR_CHECK_PORT:
  7738                              <1> J39:					; WAIT FOR MASTER
  7739 000026B5 EC                  <1> 	IN	AL,DX			; GET STATUS
  7740 000026B6 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  7741 000026B8 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  7742 000026BA 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  7743                              <1> WFPSR_HI:
  7744 000026BC E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  7745 000026BE A810                <1> 	TEST	AL,010H			; transition on memory
  7746 000026C0 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  7747                              <1> WFPSR_LO:
  7748 000026C2 E461                <1> 	IN	AL, PORT_B		; SYS1
  7749 000026C4 A810                <1> 	TEST	AL,010H
  7750 000026C6 74FA                <1> 	JZ	SHORT WFPSR_LO
  7751 000026C8 E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  7752                              <1> 	;; 27/02/2015
  7753                              <1> 	;;dec	bh
  7754                              <1> 	;;jnz	short WFPSR_OUTER_LP
  7755                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  7756                              <1> 
  7757                              <1> 	;;mov	byte [wait_count], 0
  7758                              <1> ;J39:					; WAIT FOR MASTER
  7759                              <1> ;	IN	AL,DX			; GET STATUS
  7760                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  7761                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  7762                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  7763                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  7764                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  7765                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  7766                              <1> 	;
  7767                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  7768                              <1> 	;;jb	short J39	
  7769                              <1> 
  7770                              <1> ;WFPSR_TIMEOUT:
  7771 000026CA 800D[FC700000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  7772 000026D1 F9                  <1> 	STC				; SET ERROR RETURN
  7773 000026D2 EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  7774                              <1> 
  7775                              <1> ;-----	READ IN THE STATUS
  7776                              <1> 
  7777                              <1> J42:
  7778 000026D4 EB00                <1> 	JMP	$+2			; I/O DELAY
  7779 000026D6 6642                <1> 	INC	DX			; POINT AT DATA PORT
  7780 000026D8 EC                  <1> 	IN	AL,DX			; GET THE DATA
  7781                              <1> 	; 16/12/2014
  7782                              <1> 	NEWIODELAY
  7783 000026D9 E6EB                <2>  out 0ebh,al
  7784 000026DB 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  7785 000026DD 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  7786                              <1> 	; 16/12/2014
  7787                              <1> ;	push	cx
  7788                              <1> ;	mov	cx, 30
  7789                              <1> ;wdw2:
  7790                              <1> ;	NEWIODELAY
  7791                              <1> ;	loop	wdw2
  7792                              <1> ;	pop	cx
  7793                              <1> 
  7794 000026DE B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  7795 000026E3 E801EFFFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  7796 000026E8 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  7797 000026EA EC                  <1> 	IN	AL,DX			; GET STATUS
  7798                              <1> 	; 16/12/2014
  7799                              <1> 	NEWIODELAY
  7800 000026EB E6EB                <2>  out 0ebh,al
  7801                              <1> 	;
  7802 000026ED A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  7803 000026EF 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  7804                              <1> 
  7805 000026F1 FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  7806 000026F3 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  7807 000026F5 800D[FC700000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  7808 000026FC F9                  <1> 	STC				; SET ERROR FLAG
  7809                              <1> 
  7810                              <1> ;-----	RESULT OPERATION IS DONE
  7811                              <1> POPRES:
  7812 000026FD 5F                  <1> 	POP	eDI
  7813 000026FE C3                  <1> 	RETn				; RETURN WITH CARRY SET
  7814                              <1> 
  7815                              <1> ;-------------------------------------------------------------------------------
  7816                              <1> ; READ_DSKCHNG
  7817                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  7818                              <1> ;
  7819                              <1> ; ON ENTRY:	DI = DRIVE #
  7820                              <1> ;
  7821                              <1> ; ON EXIT:	DI = DRIVE #
  7822                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  7823                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  7824                              <1> ;		AX,CX,DX DESTROYED
  7825                              <1> ;-------------------------------------------------------------------------------
  7826                              <1> READ_DSKCHNG:
  7827 000026FF E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  7828 00002704 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  7829 00002708 EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  7830 00002709 A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  7831 0000270B C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  7832                              <1> 
  7833                              <1> ;-------------------------------------------------------------------------------
  7834                              <1> ; DRIVE_DET
  7835                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  7836                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  7837                              <1> ; ON ENTRY:	DI = DRIVE #
  7838                              <1> ;-------------------------------------------------------------------------------
  7839                              <1> DRIVE_DET:
  7840 0000270C E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  7841 00002711 E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7842 00002716 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  7843 00002718 B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  7844 0000271A E882FEFFFF          <1> 	CALL	SEEK
  7845 0000271F 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  7846 00002721 B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  7847                              <1> SK_GIN:
  7848 00002723 FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  7849 00002725 6651                <1> 	PUSH	CX			; SAVE TRACK
  7850 00002727 E875FEFFFF          <1> 	CALL	SEEK
  7851 0000272C 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  7852 0000272E B8[6A270000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  7853 00002733 50                  <1> 	PUSH	eAX
  7854 00002734 B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  7855 00002736 E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  7856 0000273B 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  7857 0000273E 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  7858 00002740 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  7859 00002745 E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  7860 0000274A 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  7861 0000274B 6659                <1> 	POP	CX			; RESTORE TRACK
  7862 0000274D F605[FD700000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  7863 00002754 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  7864 00002756 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  7865 00002758 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  7866                              <1> 
  7867                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  7868                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  7869                              <1> 
  7870 0000275A 808F[09710000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  7871 00002761 C3                  <1> 	RETn				; ALL INFORMATION SET
  7872                              <1> IS_80:
  7873 00002762 808F[09710000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  7874                              <1> DD_BAC:
  7875 00002769 C3                  <1> 	RETn
  7876                              <1> POP_BAC:
  7877 0000276A 6659                <1> 	POP	CX			; THROW AWAY
  7878 0000276C C3                  <1> 	RETn
  7879                              <1> 
  7880                              <1> fdc_int:  
  7881                              <1> 	  ; 30/07/2015	
  7882                              <1> 	  ; 16/02/2015
  7883                              <1> ;int_0Eh: ; 11/12/2014
  7884                              <1> 
  7885                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  7886                              <1> ; DISK_INT
  7887                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  7888                              <1> ;
  7889                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  7890                              <1> ;-------------------------------------------------------------------------------
  7891                              <1> DISK_INT_1:
  7892                              <1> 
  7893 0000276D 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  7894 0000276F 1E                  <1> 	push	ds
  7895 00002770 66B81000            <1> 	mov	ax, KDATA
  7896 00002774 8ED8                <1> 	mov 	ds, ax
  7897 00002776 800D[F9700000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  7898 0000277D B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  7899 0000277F E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  7900 00002781 1F                  <1> 	pop	ds
  7901 00002782 6658                <1> 	POP	AX			; RECOVER REGISTER
  7902 00002784 CF                  <1> 	IRET				; RETURN FROM INTERRUPT
  7903                              <1> 
  7904                              <1> ;-------------------------------------------------------------------------------
  7905                              <1> ; DSKETTE_SETUP
  7906                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  7907                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  7908                              <1> ;-------------------------------------------------------------------------------
  7909                              <1> DSKETTE_SETUP:
  7910                              <1> 	;PUSH	AX			; SAVE REGISTERS
  7911                              <1> 	;PUSH	BX
  7912                              <1> 	;PUSH	CX
  7913 00002785 52                  <1> 	PUSH	eDX
  7914                              <1> 	;PUSH	DI
  7915                              <1> 	;;PUSH	DS
  7916                              <1> 	; 14/12/2014
  7917                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  7918                              <1> 	;mov	[DISK_POINTER+2], cs
  7919                              <1> 	;
  7920                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  7921 00002786 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  7922 00002788 66C705[09710000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  7923 00002790 00                  <1>
  7924 00002791 8025[04710000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  7925 00002798 800D[04710000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  7926 0000279F C605[F9700000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  7927 000027A6 C605[FB700000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  7928 000027AD C605[FA700000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  7929 000027B4 C605[FC700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  7930                              <1> 	;
  7931                              <1> 	; 28/02/2015
  7932                              <1> 	;mov	word [cfd], 100h 
  7933 000027BB E85FF2FFFF          <1> 	call	DSK_RESET
  7934 000027C0 5A                  <1> 	pop	edx
  7935 000027C1 C3                  <1> 	retn
  7936                              <1> 
  7937                              <1> ;SUP0:
  7938                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  7939                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7940                              <1> ;	; 02/01/2015
  7941                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  7942                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  7943                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  7944                              <1> ;       cmp     byte [fd1_type], 0	
  7945                              <1> ;	jna	short sup1
  7946                              <1> ;	or	di, di
  7947                              <1> ;	jnz	short sup1
  7948                              <1> ;	inc	di
  7949                              <1> ;       jmp     short SUP0
  7950                              <1> ;sup1:
  7951                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  7952                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  7953                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  7954                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  7955                              <1> ;	;POP	DI
  7956                              <1> ;	POP	eDX
  7957                              <1> ;	;POP	CX
  7958                              <1> ;	;POP	BX
  7959                              <1> ;	;POP	AX
  7960                              <1> ;	RETn
  7961                              <1> 
  7962                              <1> ;//////////////////////////////////////////////////////
  7963                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7964                              <1> ;
  7965                              <1> 
  7966                              <1> int13h: ; 21/02/2015
  7967 000027C2 9C                  <1> 	pushfd
  7968 000027C3 0E                  <1> 	push 	cs
  7969 000027C4 E858000000          <1> 	call 	DISK_IO
  7970 000027C9 C3                  <1> 	retn
  7971                              <1> 
  7972                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  7973                              <1> ;/////////////////////////////////////////////////////////////////////
  7974                              <1> 
  7975                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  7976                              <1> ; 23/02/2015
  7977                              <1> ; 21/02/2015 (unix386.s)
  7978                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  7979                              <1> ;
  7980                              <1> ; Original Source Code:
  7981                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  7982                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  7983                              <1> ;
  7984                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  7985                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  7986                              <1> ;
  7987                              <1> 
  7988                              <1> 
  7989                              <1> ;The wait for controller to be not busy is 10 seconds.
  7990                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  7991                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  7992                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  7993                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  7994                              <1> 
  7995                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  7996                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  7997                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  7998                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  7999                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  8000                              <1> 
  8001                              <1> ;The wait for Data request on read and write longs is
  8002                              <1> ;2000 us. (?)
  8003                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  8004                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  8005                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  8006                              <1> 
  8007                              <1> ; Port 61h (PORT_B)
  8008                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  8009                              <1> 
  8010                              <1> ; 23/12/2014
  8011                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  8012                              <1> 
  8013                              <1> 
  8014                              <1> ;--- INT 13H -------------------------------------------------------------------
  8015                              <1> ;									       :
  8016                              <1> ; FIXED DISK I/O INTERFACE						       :
  8017                              <1> ;									       :
  8018                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  8019                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  8020                              <1> ;									       :
  8021                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  8022                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  8023                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  8024                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  8025                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  8026                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  8027                              <1> ;									       :
  8028                              <1> ;------------------------------------------------------------------------------:
  8029                              <1> ;									       :
  8030                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  8031                              <1> ;									       :
  8032                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  8033                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  8034                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  8035                              <1> ;			  DL > 80H - DISK				       :
  8036                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  8037                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  8038                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  8039                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  8040                              <1> ;	(AH)= 06H  UNUSED						       :
  8041                              <1> ;	(AH)= 07H  UNUSED						       :
  8042                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  8043                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  8044                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  8045                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  8046                              <1> ;	(AH)= 0AH  READ LONG						       :
  8047                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  8048                              <1> ;	(AH)= 0CH  SEEK 						       :
  8049                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  8050                              <1> ;	(AH)= 0EH  UNUSED						       :
  8051                              <1> ;	(AH)= 0FH  UNUSED						       :
  8052                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  8053                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  8054                              <1> ;	(AH)= 12H  UNUSED						       :
  8055                              <1> ;	(AH)= 13H  UNUSED						       :
  8056                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  8057                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  8058                              <1> ;									       :
  8059                              <1> ;-------------------------------------------------------------------------------
  8060                              <1> ;									       :
  8061                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  8062                              <1> ;									       :
  8063                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  8064                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  8065                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  8066                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  8067                              <1> ;									       :
  8068                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  8069                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  8070                              <1> ;				 (10 BITS TOTAL)			       :
  8071                              <1> ;									       :
  8072                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  8073                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  8074                              <1> ;									       :
  8075                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  8076                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  8077                              <1> ;									       :
  8078                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  8079                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  8080                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  8081                              <1> ;			       80H FOR A BAD SECTOR			       :
  8082                              <1> ;			   N = SECTOR NUMBER				       :
  8083                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  8084                              <1> ;			   THE TABLE SHOULD BE: 			       :
  8085                              <1> ;									       :
  8086                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  8087                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  8088                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  8089                              <1> ;									       :
  8090                              <1> ;-------------------------------------------------------------------------------
  8091                              <1> 
  8092                              <1> ;-------------------------------------------------------------------------------
  8093                              <1> ; OUTPUT								       :
  8094                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  8095                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  8096                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  8097                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  8098                              <1> ;									       :
  8099                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  8100                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  8101                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  8102                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  8103                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  8104                              <1> ;		REWRITTEN.						       :
  8105                              <1> ;									       :
  8106                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  8107                              <1> ;	   INPUT:							       :
  8108                              <1> ;	     (DL) = DRIVE NUMBER					       :
  8109                              <1> ;	   OUTPUT:							       :
  8110                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  8111                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  8112                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  8113                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  8114                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  8115                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  8116                              <1> ;									       :
  8117                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  8118                              <1> ;									       :
  8119                              <1> ;	AH = 0 - NOT PRESENT						       :
  8120                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  8121                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  8122                              <1> ;	     3 - FIXED DISK						       :
  8123                              <1> ;									       :
  8124                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  8125                              <1> ;									       :
  8126                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  8127                              <1> ;	INFORMATION.							       :
  8128                              <1> ;									       :
  8129                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  8130                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  8131                              <1> ;									       :
  8132                              <1> ;-------------------------------------------------------------------------------
  8133                              <1> 
  8134                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  8135                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  8136                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  8137                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  8138                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  8139                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  8140                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  8141                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  8142                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  8143                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  8144                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  8145                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  8146                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  8147                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  8148                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  8149                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  8150                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  8151                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  8152                              <1> 
  8153                              <1> ;--------------------------------------------------------
  8154                              <1> ;							:
  8155                              <1> ; FIXED DISK PARAMETER TABLE				:
  8156                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  8157                              <1> ;							:
  8158                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  8159                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  8160                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  8161                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  8162                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  8163                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  8164                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  8165                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  8166                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  8167                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  8168                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  8169                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  8170                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  8171                              <1> ;							:
  8172                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  8173                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  8174                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  8175                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  8176                              <1> ;							:
  8177                              <1> ;--------------------------------------------------------
  8178                              <1> 
  8179                              <1> ;--------------------------------------------------------
  8180                              <1> ;							:
  8181                              <1> ; HARDWARE SPECIFIC VALUES				:
  8182                              <1> ;							:
  8183                              <1> ;  -  CONTROLLER I/O PORT				:
  8184                              <1> ;							:
  8185                              <1> ;     > WHEN READ FROM: 				:
  8186                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  8187                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  8188                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  8189                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  8190                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  8191                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  8192                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  8193                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  8194                              <1> ;							:
  8195                              <1> ;     > WHEN WRITTEN TO:				:
  8196                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  8197                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  8198                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  8199                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  8200                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  8201                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  8202                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  8203                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  8204                              <1> ;							:
  8205                              <1> ;--------------------------------------------------------
  8206                              <1> 
  8207                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  8208                              <1> ;HF1_PORT	equ	0170h	
  8209                              <1> ;HF_REG_PORT	EQU	03F6H
  8210                              <1> ;HF1_REG_PORT	equ	0376h
  8211                              <1> 
  8212                              <1> HDC1_BASEPORT	equ	1F0h
  8213                              <1> HDC2_BASEPORT	equ	170h		
  8214                              <1> 
  8215                              <1> align 2
  8216                              <1> 
  8217                              <1> ;-----		STATUS REGISTER
  8218                              <1> 
  8219                              <1> ST_ERROR	EQU	00000001B	;
  8220                              <1> ST_INDEX	EQU	00000010B	;
  8221                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  8222                              <1> ST_DRQ		EQU	00001000B	;
  8223                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  8224                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  8225                              <1> ST_READY	EQU	01000000B	;
  8226                              <1> ST_BUSY 	EQU	10000000B	;
  8227                              <1> 
  8228                              <1> ;-----		ERROR REGISTER
  8229                              <1> 
  8230                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  8231                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  8232                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  8233                              <1> ;		EQU	00001000B	; NOT USED
  8234                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  8235                              <1> ;		EQU	00100000B	; NOT USED
  8236                              <1> ERR_DATA_ECC	EQU	01000000B
  8237                              <1> ERR_BAD_BLOCK	EQU	10000000B
  8238                              <1> 
  8239                              <1> 
  8240                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  8241                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  8242                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  8243                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  8244                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  8245                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  8246                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  8247                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  8248                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  8249                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  8250                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  8251                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  8252                              <1> 
  8253                              <1> ;MAX_FILE	EQU	2
  8254                              <1> ;S_MAX_FILE	EQU	2
  8255                              <1> MAX_FILE	equ	4		; 22/12/2014
  8256                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  8257                              <1> 
  8258                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  8259                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  8260                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  8261                              <1> 
  8262                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  8263                              <1> 
  8264                              <1> ;-----		COMMAND BLOCK REFERENCE
  8265                              <1> 
  8266                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  8267                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  8268                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  8269                              <1> ; 19/12/2014
  8270                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  8271                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  8272                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8273                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8274                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  8275                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  8276                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  8277                              <1> 
  8278                              <1> align 2
  8279                              <1> 
  8280                              <1> ;----------------------------------------------------------------
  8281                              <1> ; FIXED DISK I/O SETUP						:
  8282                              <1> ;								:
  8283                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  8284                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  8285                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  8286                              <1> ;								:
  8287                              <1> ;----------------------------------------------------------------
  8288                              <1> 
  8289                              <1> DISK_SETUP:
  8290                              <1> 	;CLI
  8291                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  8292                              <1> 	;xor	ax,ax
  8293                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  8294                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  8295                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  8296                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  8297                              <1> 	;MOV	[DISK_VECTOR+2],AX
  8298                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  8299                              <1> 	;MOV	[ORG_VECTOR+2],CS
  8300                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  8301                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  8302                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  8303                              <1> 	;;MOV	[HDISK_INT+2],CS
  8304                              <1> 	;mov	[HDISK_INT1+2],CS
  8305                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  8306                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  8307                              <1> 	;mov	[HDISK_INT2+2],CS
  8308                              <1> 	;
  8309                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  8310                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  8311                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  8312                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  8313                              <1> 	;push	cs
  8314                              <1> 	;pop	ds
  8315                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  8316                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  8317 000027CA C705[14710000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  8318 000027D2 0900                <1>
  8319                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  8320                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  8321 000027D4 C705[18710000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  8322 000027DC 0900                <1>
  8323                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  8324                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  8325 000027DE C705[1C710000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  8326 000027E6 0900                <1>
  8327                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  8328                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  8329 000027E8 C705[20710000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  8330 000027F0 0900                <1>
  8331                              <1> 	;
  8332                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  8333                              <1> 	;;;AND	AL,0BFH
  8334                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  8335                              <1> 	;;;JMP	$+2
  8336                              <1> 	;;IODELAY
  8337                              <1> 	;;OUT	INTB01,AL
  8338                              <1> 	;;IODELAY
  8339                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  8340                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  8341                              <1> 	;;;JMP	$+2
  8342                              <1> 	;;IODELAY
  8343                              <1> 	;;OUT	INTA01,AL
  8344                              <1> 	;
  8345                              <1> 	;STI
  8346                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  8347                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  8348                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  8349                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8350                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  8351                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  8352                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  8353                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  8354                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  8355                              <1> 	;mov	si, hd0_type
  8356 000027F2 BE[306B0000]        <1> 	mov	esi, hd0_type
  8357                              <1> 	;mov	cx, 4
  8358 000027F7 B904000000          <1> 	mov	ecx, 4
  8359                              <1> hde_l:
  8360 000027FC AC                  <1> 	lodsb
  8361 000027FD 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  8362 000027FF 7206                <1> 	jb	short _L4
  8363 00002801 FE05[10710000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  8364                              <1> _L4: ; 26/02/2015
  8365 00002807 E2F3                <1> 	loop	hde_l	
  8366                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  8367                              <1> ;L4:
  8368                              <1> 	; 
  8369                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  8370                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  8371                              <1> 	;;mov 	cl, 3
  8372                              <1> 	;;
  8373                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  8374                              <1> ;;hdc_dl:
  8375                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  8376                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  8377                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  8378                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  8379                              <1> 	;;jnc	short hdc_reset0
  8380                              <1> 	;;loop	hdc_dl
  8381                              <1> 	;;; 27/12/2014
  8382                              <1> 	;;stc
  8383                              <1> 	;;retn
  8384                              <1> 	;
  8385                              <1> ;;hdc_reset0:
  8386                              <1> 	; 18/01/2015
  8387 00002809 8A0D[10710000]      <1> 	mov	cl, [HF_NUM]
  8388 0000280F 20C9                <1> 	and	cl, cl
  8389 00002811 740D                <1> 	jz	short POD_DONE
  8390                              <1> 	;
  8391 00002813 B27F                <1> 	mov	dl, 7Fh
  8392                              <1> hdc_reset1:
  8393 00002815 FEC2                <1> 	inc	dl
  8394                              <1> 	;; 31/12/2015
  8395                              <1> 	;;push	dx
  8396                              <1> 	;;push	cx
  8397                              <1> 	;;push	ds
  8398                              <1> 	;;sub	ax, ax
  8399                              <1> 	;;mov	ds, ax
  8400                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  8401                              <1> 	;;pop	ds
  8402                              <1> 	;;MOV	BX,AX
  8403                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  8404                              <1> 	;;MOV	CX,AX
  8405                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  8406                              <1> 	;;
  8407                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  8408                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  8409                              <1> 	;;pop	cx
  8410                              <1> 	;;pop	dx
  8411                              <1> 	;;
  8412                              <1> 	; 18/01/2015
  8413 00002817 B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  8414                              <1> 	;int	13h
  8415 00002819 E8A4FFFFFF          <1> 	call	int13h
  8416 0000281E E2F5                <1> 	loop	hdc_reset1
  8417                              <1> POD_DONE:
  8418 00002820 C3                  <1> 	RETn
  8419                              <1> 
  8420                              <1> ;;-----	POD_ERROR
  8421                              <1> 
  8422                              <1> ;;CTL_ERRX:
  8423                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  8424                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  8425                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8426                              <1> ;	;JMP	short POD_DONE
  8427                              <1> 
  8428                              <1> ;;HD_RESET_1:
  8429                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  8430                              <1> ;;	;PUSH	CX
  8431                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  8432                              <1> ;;	INT	13H
  8433                              <1> ;;	JC	short RES_2
  8434                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  8435                              <1> ;;	INT	13H
  8436                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  8437                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  8438                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8439                              <1> ;;					; (30 seconds)		
  8440                              <1> ;;	;cmc
  8441                              <1> ;;	;JNC	short RES_1
  8442                              <1> ;;	jb	short RES_1
  8443                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  8444                              <1> ;;	;TEST	DL,1
  8445                              <1> ;;	;JNZ	RES_E1
  8446                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  8447                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  8448                              <1> ;;	;JMP	SHORT RES_E1
  8449                              <1> ;;RES_ER: ; 22/12/2014
  8450                              <1> ;;RES_OK:
  8451                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8452                              <1> ;;	;POP	BX
  8453                              <1> ;;	RETn
  8454                              <1> ;;
  8455                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  8456                              <1> ;;	INT	13H
  8457                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  8458                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  8459                              <1> ;;	INT	13H
  8460                              <1> ;;	JC	short RES_ER
  8461                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  8462                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  8463                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  8464                              <1> ;;	INT	13H
  8465                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  8466                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  8467                              <1> ;;	JE	short RES_OK
  8468                              <1> ;;	CMP	AH,DATA_CORRECTED
  8469                              <1> ;;	JE	short RES_OK
  8470                              <1> ;;	CMP	AH,BAD_ECC
  8471                              <1> ;;	JE	short RES_OK
  8472                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  8473                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8474                              <1> ;;					; (60 seconds)		
  8475                              <1> ;;	cmc
  8476                              <1> ;;	JC	short RES_ER		; FAILED
  8477                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  8478                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  8479                              <1> ;;	AND	AL,3FH
  8480                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  8481                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  8482                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  8483                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  8484                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  8485                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  8486                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  8487                              <1> ;;	;TEST	DL,1
  8488                              <1> ;;	;JNZ	short RES_E1
  8489                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  8490                              <1> ;;;RES_E1:
  8491                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8492                              <1> ;;;RES_OK:
  8493                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8494                              <1> ;;	;POP	BX
  8495                              <1> ;;	;RETn
  8496                              <1> ;
  8497                              <1> ;;SET_FAIL:
  8498                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  8499                              <1> ;	;CALL	CMOS_READ
  8500                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  8501                              <1> ;	;XCHG	AH,AL			; SAVE IT
  8502                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  8503                              <1> ;	;RETn
  8504                              <1> ;
  8505                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  8506                              <1> ;	;POP	AX			; SAVE RETURN
  8507                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  8508                              <1> ;	;POP	BX
  8509                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  8510                              <1> ;	;PUSH	CX
  8511                              <1> ;	;PUSH	AX
  8512                              <1> ;	;push	ds
  8513                              <1> ;	;xor	ax, ax
  8514                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  8515                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  8516                              <1> ;	;				; BX = START TIME
  8517                              <1> ;	;				; CX = END TIME
  8518                              <1> ;	;pop	ds
  8519                              <1> ;	;CMP	BX,CX
  8520                              <1> ;	;JB	short TCHK1		; START < END
  8521                              <1> ;	;CMP	BX,AX
  8522                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  8523                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  8524                              <1> ;;TCHK1: CMP	AX,BX
  8525                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  8526                              <1> ;;TCHK2: CMP	AX,CX
  8527                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  8528                              <1> ;;					; OR CURRENT < END < START
  8529                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  8530                              <1> ;;	RETn
  8531                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  8532                              <1> ;;	RETn
  8533                              <1> ;;
  8534                              <1> ;;int_13h:
  8535                              <1> 
  8536                              <1> ;----------------------------------------
  8537                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  8538                              <1> ;----------------------------------------
  8539                              <1> 
  8540                              <1> DISK_IO:
  8541 00002821 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  8542                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  8543                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  8544                              <1> 	;;call	int40h
  8545 00002824 0F8225F1FFFF        <1> 	jb	DISKETTE_IO_1
  8546                              <1> ;RET_2:
  8547                              <1> 	;RETf	2			; BACK TO CALLER
  8548                              <1> ;	retf	4
  8549                              <1> A1:
  8550 0000282A FB                  <1> 	STI				; ENABLE INTERRUPTS
  8551                              <1> 	;; 04/01/2015
  8552                              <1> 	;;OR	AH,AH
  8553                              <1> 	;;JNZ	short A2
  8554                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  8555                              <1> 	;;SUB	AH,AH
  8556 0000282B 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  8557 0000282E 772C                <1> 	JA	short RET_2
  8558                              <1> 	; 18/01/2015
  8559 00002830 08E4                <1> 	or	ah,ah
  8560 00002832 742B                <1> 	jz	short A4
  8561 00002834 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  8562 00002837 7504                <1> 	jne	short A2
  8563 00002839 28E4                <1> 	sub	ah,ah	; Reset
  8564 0000283B EB22                <1> 	jmp	short A4
  8565                              <1> A2:
  8566 0000283D 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  8567                              <1> 	;JNZ	short A3
  8568                              <1>         ;JMP    GET_PARM_N
  8569 00002840 0F841C030000        <1> 	je	GET_PARM_N
  8570 00002846 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  8571                              <1> 	;JNZ	short A4
  8572                              <1>         ;JMP    READ_DASD_TYPE
  8573 00002849 0F84C7020000        <1>         je      READ_DASD_TYPE
  8574                              <1> 	; 02/02/2015
  8575 0000284F 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  8576                              <1> 	; 12/01/2015
  8577 00002852 F5                  <1> 	cmc
  8578 00002853 730A                <1> 	jnc	short A4
  8579                              <1> 	; 30/01/2015
  8580                              <1> 	;mov     byte [CS:DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  8581 00002855 C605[0F710000]01    <1>         mov     byte [DISK_STATUS1], BAD_CMD
  8582                              <1> 	;jmp	short RET_2
  8583                              <1> RET_2:
  8584 0000285C CA0400              <1> 	retf	4
  8585                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  8586 0000285F C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  8587 00002863 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  8588 00002864 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  8589 00002865 52                  <1> 	PUSH	eDX
  8590 00002866 1E                  <1> 	PUSH	DS
  8591 00002867 06                  <1> 	PUSH	ES
  8592 00002868 56                  <1> 	PUSH	eSI
  8593 00002869 57                  <1> 	PUSH	eDI
  8594                              <1> 	;;04/01/2015
  8595                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  8596                              <1> 	;;JNZ	short A5
  8597                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  8598                              <1> ;;A5:	
  8599                              <1> 	;push	cs
  8600                              <1> 	;pop	ds
  8601                              <1> 	; 21/02/2015
  8602 0000286A 6650                <1> 	push	ax
  8603 0000286C 66B81000            <1> 	mov	ax, KDATA
  8604 00002870 8ED8                <1> 	mov	ds, ax
  8605 00002872 8EC0                <1> 	mov	es, ax	
  8606 00002874 6658                <1> 	pop	ax
  8607 00002876 E889000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  8608                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  8609 0000287B 8A25[0F710000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  8610 00002881 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  8611 00002884 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  8612 00002885 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  8613 00002886 5E                  <1> 	POP	eSI
  8614 00002887 07                  <1>         POP     ES
  8615 00002888 1F                  <1>         POP     DS
  8616 00002889 5A                  <1> 	POP	eDX
  8617 0000288A 59                  <1> 	POP	eCX
  8618 0000288B 5B                  <1> 	POP	eBX
  8619 0000288C C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  8620                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  8621 0000288D CA0400              <1> 	retf	4
  8622                              <1> ; 21/02/2015
  8623                              <1> ;       dw --> dd
  8624                              <1> M1:					; FUNCTION TRANSFER TABLE
  8625 00002890 [522A0000]          <1> 	dd	DISK_RESET		; 000H
  8626 00002894 [C92A0000]          <1> 	dd	RETURN_STATUS		; 001H
  8627 00002898 [D62A0000]          <1> 	dd	DISK_READ		; 002H
  8628 0000289C [DF2A0000]          <1> 	dd	DISK_WRITE		; 003H
  8629 000028A0 [E82A0000]          <1> 	dd	DISK_VERF		; 004H
  8630 000028A4 [002B0000]          <1> 	dd	FMT_TRK 		; 005H
  8631 000028A8 [482A0000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  8632 000028AC [482A0000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  8633 000028B0 [482A0000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  8634 000028B4 [C72B0000]          <1> 	dd	INIT_DRV		; 009H
  8635 000028B8 [262C0000]          <1> 	dd	RD_LONG 		; 00AH
  8636 000028BC [2F2C0000]          <1> 	dd	WR_LONG 		; 00BH
  8637 000028C0 [382C0000]          <1> 	dd	DISK_SEEK		; 00CH
  8638 000028C4 [522A0000]          <1> 	dd	DISK_RESET		; 00DH
  8639 000028C8 [482A0000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  8640 000028CC [482A0000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  8641 000028D0 [602C0000]          <1> 	dd	TST_RDY 		; 010H
  8642 000028D4 [842C0000]          <1> 	dd	HDISK_RECAL		; 011H
  8643 000028D8 [482A0000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  8644 000028DC [482A0000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  8645 000028E0 [BA2C0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  8646                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  8647 000028E4 [482A0000]          <1> 	dd	BAD_COMMAND		; 015h
  8648 000028E8 [482A0000]          <1> 	dd	BAD_COMMAND		; 016h
  8649 000028EC [482A0000]          <1> 	dd	BAD_COMMAND		; 017h
  8650 000028F0 [482A0000]          <1> 	dd	BAD_COMMAND		; 018h
  8651 000028F4 [482A0000]          <1> 	dd	BAD_COMMAND		; 019h
  8652 000028F8 [482A0000]          <1> 	dd	BAD_COMMAND		; 01Ah
  8653 000028FC [D62A0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  8654 00002900 [DF2A0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  8655                              <1> M1L     EQU    $-M1
  8656                              <1> 
  8657                              <1> DISK_IO_CONT:
  8658                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  8659 00002904 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  8660                              <1> 	;;JNZ	short SU0
  8661                              <1>         ;;JMP    RETURN_STATUS
  8662 00002907 0F84BC010000        <1> 	je	RETURN_STATUS
  8663                              <1> SU0:
  8664 0000290D C605[0F710000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8665                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  8666                              <1> 	;mov	si, bx ;; 14/02/2015
  8667 00002914 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  8668 00002916 8A1D[10710000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  8669                              <1> 	;; 04/01/2015
  8670                              <1> 	;;PUSH	AX
  8671 0000291C 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  8672                              <1> 					; (get drive number as 0 to 3)
  8673 0000291F 38D3                <1> 	CMP	BL,DL
  8674                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  8675 00002921 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  8676                              <1>         ;
  8677                              <1> 	;;03/01/2015
  8678 00002927 29DB                <1> 	sub	ebx, ebx
  8679 00002929 88D3                <1> 	mov	bl, dl
  8680                              <1> 	;sub	bh, bh
  8681 0000292B 883D[24710000]      <1> 	mov	[LBAMode], bh 	; 0
  8682                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  8683                              <1> 	;test	byte [ebx+hd0_type], 1
  8684                              <1> 	;jz	short su1		; no
  8685                              <1> 	;inc	byte [LBAMode]
  8686                              <1> ;su1:
  8687                              <1> 	; 21/02/2015 (32 bit modification)
  8688                              <1> 	;04/01/2015
  8689 00002931 6650                <1> 	push	ax ; ***
  8690                              <1> 	;PUSH	ES ; **
  8691 00002933 6652                <1> 	PUSH	DX ; *
  8692 00002935 6650                <1> 	push	ax
  8693 00002937 E85C060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  8694                              <1> 	; 02/02/2015
  8695                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  8696 0000293C 668B4310            <1> 	mov	ax, [ebx+16]
  8697 00002940 66A3[246B0000]      <1> 	mov	[HF_PORT], ax
  8698                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  8699 00002946 668B5312            <1> 	mov	dx, [ebx+18]
  8700 0000294A 668915[266B0000]    <1> 	mov	[HF_REG_PORT], dx
  8701                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  8702 00002951 8A4314              <1> 	mov	al, [ebx+20]
  8703                              <1> 	; 23/02/2015
  8704 00002954 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  8705 00002956 7406                <1> 	jz 	short su1
  8706 00002958 FE05[24710000]      <1> 	inc	byte [LBAMode] ; 1 
  8707                              <1> su1: 	 
  8708 0000295E C0E804              <1> 	shr 	al, 4
  8709 00002961 2401                <1> 	and	al, 1			
  8710 00002963 A2[286B0000]        <1> 	mov	[hf_m_s], al 
  8711                              <1> 	;
  8712                              <1> 	; 03/01/2015
  8713                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  8714 00002968 8A4308              <1> 	mov	al, [ebx+8]
  8715                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  8716 0000296B EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  8717                              <1> 					; Control Byte:  (= 08h, here)
  8718                              <1> 					; bit 0 - 0
  8719                              <1> 					; bit 1 - nIEN (1 = disable irq)
  8720                              <1> 					; bit 2 - SRST (software RESET)
  8721                              <1> 					; bit 3 - use extra heads (8 to 15)
  8722                              <1> 					;         -always set to 1-	
  8723                              <1> 					; (bits 3 to 7 are reserved
  8724                              <1> 					;          for ATA devices)
  8725 0000296C 8A25[11710000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  8726 00002972 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  8727 00002975 08C4                <1> 	OR	AH,AL
  8728 00002977 8825[11710000]      <1> 	MOV	[CONTROL_BYTE],AH	
  8729                              <1> 	; 04/01/2015
  8730 0000297D 6658                <1> 	pop	ax
  8731 0000297F 665A                <1> 	pop	dx ; * ;; 14/02/2015
  8732 00002981 20E4                <1> 	and	ah, ah	; Reset function ?
  8733 00002983 7507                <1> 	jnz	short su2
  8734                              <1> 	;;pop	dx ; * ;; 14/02/2015
  8735                              <1> 	;pop	es ; **
  8736 00002985 6658                <1> 	pop	ax ; ***
  8737                              <1> 	;;pop	bx
  8738 00002987 E9C6000000          <1>         jmp     DISK_RESET
  8739                              <1> su2:
  8740 0000298C 803D[24710000]00    <1> 	cmp	byte [LBAMode], 0
  8741 00002993 7661                <1> 	jna	short su3
  8742                              <1> 	;
  8743                              <1> 	; 02/02/2015 (LBA read/write function calls)
  8744 00002995 80FC1B              <1> 	cmp	ah, 1Bh
  8745 00002998 720B                <1> 	jb	short lbarw1
  8746 0000299A 80FC1C              <1> 	cmp	ah, 1Ch
  8747 0000299D 775C                <1> 	ja 	short invldfnc
  8748                              <1> 	;;pop	dx ; * ; 14/02/2015
  8749                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  8750 0000299F 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  8751                              <1> 	;; 14/02/2015
  8752 000029A1 88D1                <1> 	mov	cl, dl ; 14/02/2015
  8753                              <1> 	;;mov	dx, bx
  8754                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  8755                              <1> 	;;mov	bx, di
  8756                              <1> 	;mov	si, di ; Buffer offset
  8757 000029A3 EB31                <1> 	jmp	short lbarw2
  8758                              <1> lbarw1:
  8759                              <1> 	; convert CHS to LBA
  8760                              <1> 	;
  8761                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  8762                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  8763                              <1> 	;	+ Sector - 1
  8764 000029A5 6652                <1> 	push	dx ; * ;; 14/02/2015
  8765                              <1> 	;xor	dh, dh
  8766 000029A7 31D2                <1> 	xor	edx, edx
  8767                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  8768 000029A9 8A530E              <1> 	mov	dl, [ebx+14]
  8769                              <1> 	;xor	ah, ah
  8770 000029AC 31C0                <1> 	xor	eax, eax
  8771                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  8772 000029AE 8A4302              <1> 	mov	al, [ebx+2]
  8773 000029B1 FEC8                <1> 	dec	al
  8774 000029B3 6640                <1> 	inc	ax		; 0 =  256
  8775 000029B5 66F7E2              <1> 	mul 	dx
  8776                              <1> 		; AX = # of Heads" * Sectors/Track
  8777 000029B8 6689CA              <1> 	mov	dx, cx
  8778                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  8779 000029BB 83E13F              <1> 	and	ecx, 3fh
  8780 000029BE 86D6                <1> 	xchg	dl, dh
  8781 000029C0 C0EE06              <1> 	shr	dh, 6
  8782                              <1> 		; DX = cylinder (0 to 1023)
  8783                              <1> 	;mul 	dx
  8784                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  8785 000029C3 F7E2                <1> 	mul	edx
  8786 000029C5 FEC9                <1> 	dec	cl  ; sector - 1
  8787                              <1> 	;add	ax, cx
  8788                              <1> 	;adc	dx, 0
  8789                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  8790 000029C7 01C8                <1> 	add	eax, ecx
  8791 000029C9 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  8792                              <1> 	;push	dx
  8793                              <1> 	;push	ax
  8794 000029CB 50                  <1> 	push	eax
  8795                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  8796 000029CC 8A430E              <1> 	mov	al, [ebx+14]
  8797 000029CF F6E5                <1> 	mul	ch
  8798                              <1> 		;  AX = Head * Sectors/Track
  8799 000029D1 6699                <1>         cwd
  8800                              <1> 	;pop	dx
  8801 000029D3 5A                  <1> 	pop	edx
  8802                              <1> 	;add	ax, dx
  8803                              <1> 	;pop	dx
  8804                              <1> 	;adc	dx, 0 ; add carry bit
  8805 000029D4 01D0                <1> 	add	eax, edx
  8806                              <1> lbarw2:
  8807 000029D6 29D2                <1> 	sub	edx, edx ; 21/02/2015
  8808 000029D8 88CA                <1> 	mov	dl, cl ; 21/02/2015
  8809 000029DA C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  8810                              <1> 				; NOTE: Features register (1F1h, 171h)
  8811                              <1> 				; is not used for ATA device R/W functions. 
  8812                              <1> 				; It is old/obsolete 'write precompensation'
  8813                              <1> 				; register and error register
  8814                              <1> 				; for old ATA/IDE devices.
  8815                              <1> 	; 18/01/2014
  8816                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  8817 000029DE 8A0D[286B0000]      <1> 	mov	cl, [hf_m_s]
  8818                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  8819                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  8820                              <1> 				; bit 6 = 1 = LBA mode
  8821                              <1> 				; bit 7 = 1
  8822 000029E4 80C90E              <1> 	or	cl, 0Eh ; 1110b
  8823                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  8824 000029E7 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  8825 000029EC C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  8826                              <1> 	;or	dh, ch
  8827 000029EF 09C8                <1> 	or	eax, ecx	
  8828                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  8829                              <1> 				  ; (Sector Number Register)
  8830                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  8831                              <1> 				  ; (Cylinder Low Register)
  8832                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  8833                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  8834                              <1> 				  ; (Cylinder High Register)
  8835                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  8836                              <1> 				  ; (Drive/Head Register)
  8837                              <1> 	
  8838                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  8839 000029F1 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  8840                              <1> 	;14/02/2015
  8841                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  8842 000029F4 EB38                <1> 	jmp	short su4
  8843                              <1> su3:
  8844                              <1> 	; 02/02/2015 
  8845                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  8846 000029F6 80FC14              <1> 	cmp 	ah, 14h
  8847 000029F9 7604                <1> 	jna 	short chsfnc
  8848                              <1> invldfnc:
  8849                              <1>         ; 14/02/2015  
  8850                              <1> 	;pop	es ; **
  8851 000029FB 6658                <1>         pop     ax ; ***
  8852                              <1>         ;jmp     short BAD_COMMAND_POP
  8853 000029FD EB49                <1>         jmp     short BAD_COMMAND
  8854                              <1> chsfnc:	
  8855                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  8856 000029FF 668B4305            <1> 	mov	ax, [ebx+5]
  8857 00002A03 66C1E802            <1> 	SHR	AX,2
  8858 00002A07 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  8859                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  8860                              <1> 	;;PUSH	DX
  8861                              <1> 	;;MOV	DX,[HF_REG_PORT]
  8862                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  8863                              <1> 	;;POP	DX ; * 
  8864                              <1> 	;;POP	ES ; **
  8865                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  8866                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  8867                              <1> 	;;OR	AH,AL
  8868                              <1> 	;;MOV	[CONTROL_BYTE],AH
  8869                              <1> 	;
  8870 00002A0A 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  8871 00002A0C 243F                <1> 	AND	AL,3FH
  8872 00002A0E 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  8873 00002A11 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  8874 00002A14 88C8                <1> 	MOV	AL,CL
  8875 00002A16 C0E806              <1> 	SHR	AL,6
  8876 00002A19 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  8877                              <1> 	;;05/01/2015
  8878                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  8879 00002A1C A0[286B0000]        <1> 	mov	al, [hf_m_s]
  8880 00002A21 C0E004              <1> 	SHL	AL,4
  8881 00002A24 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  8882 00002A27 08F0                <1> 	OR	AL,DH
  8883                              <1> 	;OR	AL,80H or 20H
  8884 00002A29 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  8885 00002A2B 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  8886                              <1> su4:
  8887                              <1> 	;POP	ES ; **
  8888                              <1>         ;; 14/02/2015
  8889                              <1>         ;;POP   AX
  8890                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  8891                              <1>         ;;PUSH  AX
  8892                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  8893                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  8894                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  8895 00002A2E 6658                <1>         pop     ax ; ***
  8896 00002A30 8845F9              <1>         mov     [CMD_BLOCK+1], al
  8897 00002A33 29DB                <1>         sub	ebx, ebx
  8898 00002A35 88E3                <1> 	mov     bl, ah
  8899                              <1>         ;xor     bh, bh
  8900                              <1>         ;sal     bx, 1
  8901 00002A37 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  8902                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  8903                              <1>         ;;CMP   AX,M1L                  ; TEST WITHIN RANGE
  8904                              <1>         ;;JNB   short BAD_COMMAND_POP
  8905                              <1>         ;cmp     bx, M1L
  8906 00002A3B 83FB74              <1> 	cmp	ebx, M1L
  8907 00002A3E 7308                <1> 	jnb	short BAD_COMMAND
  8908                              <1>         ;xchg    bx, si
  8909 00002A40 87DE                <1>         xchg	ebx, esi
  8910                              <1> 	;;;POP	AX			; RESTORE AX
  8911                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  8912                              <1> 	
  8913                              <1> 	;;PUSH	CX
  8914                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  8915                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  8916                              <1> 	;SHR	CX,4
  8917                              <1> 	;MOV	AX,ES
  8918                              <1> 	;ADD	AX,CX
  8919                              <1> 	;MOV	ES,AX
  8920                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  8921                              <1> 	;;POP	AX
  8922                              <1> 	;;POP	CX
  8923                              <1> 	;;JMP	word [CS:SI+M1]
  8924                              <1> 	;jmp	word [SI+M1]
  8925 00002A42 FFA6[90280000]      <1> 	jmp	dword [esi+M1]
  8926                              <1> ;;BAD_COMMAND_POP:
  8927                              <1> ;;	POP	AX
  8928                              <1> ;;	POP	BX
  8929                              <1> BAD_COMMAND:
  8930 00002A48 C605[0F710000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  8931 00002A4F B000                <1> 	MOV	AL,0
  8932 00002A51 C3                  <1> 	RETn
  8933                              <1> 
  8934                              <1> ;----------------------------------------
  8935                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  8936                              <1> ;----------------------------------------
  8937                              <1> 
  8938                              <1> ; 18-1-2015 : one controller reset (not other one)
  8939                              <1> 
  8940                              <1> DISK_RESET:
  8941 00002A52 FA                  <1> 	CLI
  8942 00002A53 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  8943                              <1> 	;JMP	$+2
  8944                              <1> 	IODELAY
  8945 00002A55 EB00                <2>  jmp short $+2
  8946 00002A57 EB00                <2>  jmp short $+2
  8947                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  8948 00002A59 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  8949 00002A5B E6A1                <1> 	OUT	INTB01,AL
  8950 00002A5D FB                  <1> 	STI				; START INTERRUPTS
  8951                              <1> 	; 14/02/2015
  8952 00002A5E 6689D7              <1> 	mov	di, dx	
  8953                              <1> 	; 04/01/2015
  8954                              <1> 	;xor	di,di
  8955                              <1> drst0:
  8956 00002A61 B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  8957                              <1> 	;MOV	DX,HF_REG_PORT
  8958 00002A63 668B15[266B0000]    <1> 	MOV	DX,[HF_REG_PORT]
  8959 00002A6A EE                  <1> 	OUT	DX,AL			; RESET
  8960                              <1> ;	MOV	CX,10			; DELAY COUNT
  8961                              <1> ;DRD:	DEC	CX
  8962                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  8963                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  8964 00002A6B B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  8965 00002A70 E874EBFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  8966                              <1>                                         ; 40 micro seconds)
  8967 00002A75 A0[11710000]        <1> 	mov	al,[CONTROL_BYTE]
  8968 00002A7A 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  8969 00002A7C EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  8970 00002A7D E80E040000          <1> 	CALL	NOT_BUSY
  8971 00002A82 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  8972 00002A84 668B15[246B0000]    <1> 	MOV	DX,[HF_PORT]
  8973 00002A8B FEC2                <1> 	inc	dl  ; HF_PORT+1
  8974                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  8975                              <1>         ;mov     cl, 10
  8976 00002A8D B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  8977                              <1> drst1:
  8978 00002A92 EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  8979 00002A93 3C01                <1> 	CMP	AL,1
  8980                              <1> 	; 04/01/2015
  8981 00002A95 740A                <1> 	jz	short drst2
  8982                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  8983                              <1>         	; Drive/Head Register - bit 4
  8984 00002A97 E2F9                <1> 	loop	drst1
  8985                              <1> DRERR:	
  8986 00002A99 C605[0F710000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  8987 00002AA0 C3                  <1> 	RETn
  8988                              <1> drst2:
  8989                              <1> 	; 14/02/2015
  8990 00002AA1 6689FA              <1> 	mov	dx,di
  8991                              <1> ;drst3:
  8992                              <1> ;	; 05/01/2015
  8993                              <1> ;	shl 	di,1
  8994                              <1> ;	; 04/01/2015
  8995                              <1> ;	mov	ax,[di+hd_cports]
  8996                              <1> ;	cmp	ax,[HF_REG_PORT]
  8997                              <1> ;	je	short drst4
  8998                              <1> ;	mov	[HF_REG_PORT], ax
  8999                              <1> ;	; 03/01/2015
  9000                              <1> ;	mov	ax,[di+hd_ports]
  9001                              <1> ;       mov     [HF_PORT], ax
  9002                              <1> ;	; 05/01/2014
  9003                              <1> ;	shr	di,1
  9004                              <1> ;	; 04/01/2015
  9005                              <1> ;	jmp	short drst0	; reset other controller
  9006                              <1> ;drst4:
  9007                              <1> ;	; 05/01/2015
  9008                              <1> ;	shr	di,1
  9009                              <1> ;	mov	al,[di+hd_dregs]
  9010                              <1> ;	and	al,10h ; bit 4 only
  9011                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  9012                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  9013                              <1> 	;
  9014 00002AA4 A0[286B0000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  9015 00002AA9 A801                <1> 	test	al,1
  9016                              <1> ;	jnz	short drst6
  9017 00002AAB 7516                <1>         jnz     short drst4
  9018 00002AAD 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  9019                              <1> ;drst5:
  9020                              <1> drst3:
  9021 00002AB1 E811010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  9022                              <1> 	;mov	dx,di
  9023 00002AB6 E8C9010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  9024                              <1> 	; 04/01/2014
  9025                              <1> ;	inc	di
  9026                              <1> ;	mov	dx,di
  9027                              <1> ;	cmp	dl,[HF_NUM]
  9028                              <1> ;	jb	short drst3
  9029                              <1> ;DRE:
  9030 00002ABB C605[0F710000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  9031 00002AC2 C3                  <1> 	RETn
  9032                              <1> ;drst6:
  9033                              <1> drst4:		; Drive/Head Register - bit 4
  9034 00002AC3 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  9035                              <1>         ;jmp    short drst5
  9036 00002AC7 EBE8                <1>         jmp     short drst3
  9037                              <1> 
  9038                              <1> ;----------------------------------------
  9039                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  9040                              <1> ;----------------------------------------
  9041                              <1> 
  9042                              <1> RETURN_STATUS:
  9043 00002AC9 A0[0F710000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  9044 00002ACE C605[0F710000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  9045 00002AD5 C3                  <1> 	RETn
  9046                              <1> 
  9047                              <1> ;----------------------------------------
  9048                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  9049                              <1> ;----------------------------------------
  9050                              <1> 
  9051                              <1> DISK_READ:
  9052 00002AD6 C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  9053 00002ADA E930020000          <1>         JMP     COMMANDI
  9054                              <1> 
  9055                              <1> ;----------------------------------------
  9056                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  9057                              <1> ;----------------------------------------
  9058                              <1> 
  9059                              <1> DISK_WRITE:
  9060 00002ADF C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  9061 00002AE3 E97C020000          <1>         JMP     COMMANDO
  9062                              <1> 
  9063                              <1> ;----------------------------------------
  9064                              <1> ;	DISK VERIFY	     (AH = 04H) :
  9065                              <1> ;----------------------------------------
  9066                              <1> 
  9067                              <1> DISK_VERF:
  9068 00002AE8 C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  9069 00002AEC E8EA020000          <1> 	CALL	COMMAND
  9070 00002AF1 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  9071 00002AF3 E85C030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  9072 00002AF8 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  9073 00002AFA E8E9030000          <1> 	CALL	CHECK_STATUS
  9074                              <1> VERF_EXIT:
  9075 00002AFF C3                  <1> 	RETn
  9076                              <1> 
  9077                              <1> ;----------------------------------------
  9078                              <1> ;	FORMATTING	     (AH = 05H) :
  9079                              <1> ;----------------------------------------
  9080                              <1> 
  9081                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  9082 00002B00 C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  9083                              <1> 	;PUSH	ES
  9084                              <1> 	;PUSH	BX
  9085 00002B04 53                  <1> 	push	ebx
  9086 00002B05 E88E040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  9087                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  9088 00002B0A 8A430E              <1> 	mov	al, [ebx+14]
  9089 00002B0D 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  9090 00002B10 5B                  <1> 	pop	ebx
  9091                              <1> 	;POP	BX
  9092                              <1> 	;POP	ES
  9093 00002B11 E955020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  9094                              <1> 
  9095                              <1> ;----------------------------------------
  9096                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  9097                              <1> ;----------------------------------------
  9098                              <1> 
  9099                              <1> READ_DASD_TYPE:
  9100                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  9101 00002B16 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9102                              <1> 	;PUSH	ES
  9103 00002B17 53                  <1> 	PUSH	eBX
  9104                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  9105                              <1> 	;push	cs
  9106                              <1> 	;pop	ds
  9107 00002B18 66BB1000            <1>         mov	bx, KDATA
  9108 00002B1C 8EDB                <1> 	mov	ds, bx
  9109                              <1> 	;mov	es, bx
  9110 00002B1E C605[0F710000]00    <1> 	MOV     byte [DISK_STATUS1],0
  9111 00002B25 8A1D[10710000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  9112 00002B2B 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  9113 00002B2E 38D3                <1> 	CMP	BL,DL
  9114 00002B30 7625                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  9115 00002B32 E861040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  9116                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  9117 00002B37 8A4302              <1> 	mov	al, [ebx+2]
  9118                              <1> 	;MOV	CL,[ES:BX+14]
  9119 00002B3A 8A4B0E              <1> 	mov	cl, [ebx+14]
  9120 00002B3D F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  9121                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  9122 00002B3F 668B0B              <1> 	mov	cx ,[ebx]
  9123                              <1> 	;
  9124                              <1> 	; 02/01/2015 
  9125                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  9126                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  9127 00002B42 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  9128                              <1> 	;
  9129 00002B44 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  9130 00002B47 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  9131 00002B4A 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  9132                              <1> 	;SUB	AX,AX
  9133 00002B4D 28C0                <1> 	sub	al, al
  9134 00002B4F B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  9135 00002B51 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  9136                              <1> 	;POP	ES
  9137 00002B52 1F                  <1> 	POP	DS
  9138 00002B53 F8                  <1> 	CLC				; CLEAR CARRY
  9139                              <1> 	;RETf	2
  9140 00002B54 CA0400              <1> 	retf	4
  9141                              <1> RDT_NOT_PRESENT:
  9142 00002B57 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  9143 00002B5A 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  9144 00002B5D 6689C2              <1> 	MOV	DX,AX
  9145 00002B60 EBEF                <1> 	JMP	short RDT2
  9146                              <1> 
  9147                              <1> ;----------------------------------------
  9148                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  9149                              <1> ;----------------------------------------
  9150                              <1> 
  9151                              <1> GET_PARM_N:
  9152                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  9153 00002B62 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9154                              <1> 	;PUSH	ES
  9155 00002B63 53                  <1> 	PUSH	eBX
  9156                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  9157                              <1> 	;MOV	DS,AX
  9158                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  9159                              <1> 	;JZ	short G0
  9160                              <1> 	;LES	BX,@HF1_TBL_VEC
  9161                              <1> 	;JMP	SHORT G1
  9162                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  9163                              <1> ;G1:
  9164                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  9165                              <1> 	; 22/12/2014
  9166                              <1> 	;push	cs
  9167                              <1> 	;pop	ds
  9168 00002B64 66BB1000            <1> 	mov	bx, KDATA
  9169 00002B68 8EDB                <1> 	mov	ds, bx
  9170                              <1> 	;mov	es, bx
  9171                              <1> 	;
  9172 00002B6A 80EA80              <1> 	SUB	DL,80H
  9173 00002B6D 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  9174 00002B70 7341                <1> 	JAE	short G4
  9175                              <1> 	;
  9176 00002B72 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  9177                              <1> 	; 22/12/2014
  9178 00002B74 88D3                <1> 	mov	bl, dl
  9179                              <1> 	;xor	bh, bh  
  9180 00002B76 C0E302              <1> 	shl	bl, 2			; convert index to offset
  9181                              <1> 	;add	bx, HF_TBL_VEC
  9182 00002B79 81C3[14710000]      <1> 	add	ebx, HF_TBL_VEC
  9183                              <1> 	;mov	ax, [bx+2]
  9184                              <1> 	;mov	es, ax			; dpt segment
  9185                              <1> 	;mov	bx, [bx]		; dpt offset
  9186 00002B7F 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  9187                              <1> 
  9188 00002B81 C605[0F710000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9189                              <1>         ;MOV     AX,[ES:BX]              ; MAX NUMBER OF CYLINDERS
  9190 00002B88 668B03              <1> 	mov	ax, [ebx]
  9191                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  9192 00002B8B 6648                <1> 	dec	ax			; max. cylinder number
  9193 00002B8D 88C5                <1> 	MOV	CH,AL
  9194 00002B8F 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  9195 00002B93 66D1E8              <1> 	SHR	AX,1
  9196 00002B96 66D1E8              <1> 	SHR	AX,1
  9197                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  9198 00002B99 0A430E              <1> 	or	al, [ebx+14]
  9199 00002B9C 88C1                <1> 	MOV	CL,AL
  9200                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  9201 00002B9E 8A7302              <1> 	mov	dh, [ebx+2]
  9202 00002BA1 FECE                <1> 	DEC	DH			; 0-N RANGE
  9203 00002BA3 8A15[10710000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  9204 00002BA9 6629C0              <1> 	SUB	AX,AX
  9205                              <1>         ;27/12/2014 
  9206                              <1> 	; ES:DI = Address of disk parameter table from BIOS
  9207                              <1> 	;(Programmer's Guide to the AMIBIOS - 1993)
  9208                              <1> 	;mov	di, bx			; HDPT offset
  9209 00002BAC 89DF                <1> 	mov	edi, ebx
  9210                              <1> G5:
  9211 00002BAE 5B                  <1> 	POP	eBX			; RESTORE REGISTERS
  9212                              <1> 	;POP	ES
  9213 00002BAF 1F                  <1> 	POP	DS
  9214                              <1> 	;RETf	2
  9215 00002BB0 CA0400              <1> 	retf	4
  9216                              <1> G4:
  9217 00002BB3 C605[0F710000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  9218 00002BBA B407                <1> 	MOV	AH,INIT_FAIL
  9219 00002BBC 28C0                <1> 	SUB	AL,AL
  9220 00002BBE 6629D2              <1> 	SUB	DX,DX
  9221 00002BC1 6629C9              <1> 	SUB	CX,CX
  9222 00002BC4 F9                  <1> 	STC				; SET ERROR FLAG
  9223 00002BC5 EBE7                <1> 	JMP	short G5
  9224                              <1> 
  9225                              <1> ;----------------------------------------
  9226                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  9227                              <1> ;----------------------------------------
  9228                              <1> 	; 03/01/2015
  9229                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  9230                              <1> 	; logical sector per logical track
  9231                              <1> 	; and logical heads - 1 would be set but
  9232                              <1> 	; it is seen as it will be good
  9233                              <1> 	; if physical parameters will be set here
  9234                              <1> 	; because, number of heads <= 16.
  9235                              <1> 	; (logical heads usually more than 16)
  9236                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  9237                              <1> 	;	== INT 13h physical parameters
  9238                              <1> 
  9239                              <1> ;INIT_DRV:
  9240                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  9241                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  9242                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  9243                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  9244                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  9245                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  9246                              <1> ;	OR	AH,AL			; TO MAX HEAD
  9247                              <1> ;	MOV	[CMD_BLOCK+5],AH
  9248                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  9249                              <1> ;	MOV	[CMD_BLOCK+1],AL
  9250                              <1> ;	SUB	AX,AX
  9251                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  9252                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  9253                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  9254                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  9255                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  9256                              <1> ;	CALL	CHECK_STATUS
  9257                              <1> ;INIT_EXIT:
  9258                              <1> ;	RETn
  9259                              <1> 
  9260                              <1> ; 04/01/2015
  9261                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  9262                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  9263                              <1> INIT_DRV:
  9264                              <1> 	;xor	ah,ah
  9265 00002BC7 31C0                <1> 	xor	eax, eax ; 21/02/2015
  9266 00002BC9 B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  9267 00002BCB 3825[24710000]      <1>         cmp     [LBAMode], ah   ; 0
  9268 00002BD1 7702                <1> 	ja	short idrv0
  9269 00002BD3 B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  9270                              <1> idrv0:
  9271                              <1> 	; DL = drive number (0 based)
  9272 00002BD5 E8BE030000          <1> 	call	GET_VEC
  9273                              <1> 	;push	bx
  9274 00002BDA 53                  <1> 	push	ebx ; 21/02/2015
  9275                              <1> 	;add	bx,ax
  9276 00002BDB 01C3                <1> 	add	ebx, eax
  9277                              <1> 	;; 05/01/2015
  9278 00002BDD 8A25[286B0000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  9279                              <1> 	;;and 	ah,1 
  9280 00002BE3 C0E404              <1> 	shl	ah,4
  9281 00002BE6 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  9282                              <1> 	;mov	al,[es:bx]
  9283 00002BE9 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  9284 00002BEB FEC8                <1> 	dec	al	 ; last head number 
  9285                              <1> 	;and	al,0Fh
  9286 00002BED 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  9287                              <1> 	;
  9288 00002BEF C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  9289 00002BF3 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  9290                              <1> 	;pop	bx
  9291 00002BF6 5B                  <1> 	pop	ebx
  9292 00002BF7 29C0                <1> 	sub	eax, eax ; 21/02/2015
  9293 00002BF9 B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  9294 00002BFB 803D[24710000]00    <1> 	cmp	byte [LBAMode], 0
  9295 00002C02 7702                <1> 	ja	short idrv1
  9296 00002C04 B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  9297                              <1> idrv1:
  9298                              <1> 	;xor	ah,ah
  9299                              <1> 	;add	bx,ax
  9300 00002C06 01C3                <1> 	add	ebx, eax ; 21/02/2015
  9301                              <1> 	;mov	al,[es:bx]
  9302                              <1> 			; sector number
  9303 00002C08 8A03                <1> 	mov	al, [ebx]
  9304 00002C0A 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  9305 00002C0D 28C0                <1> 	sub	al,al
  9306 00002C0F 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  9307 00002C12 E8C4010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  9308 00002C17 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  9309 00002C19 E872020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  9310 00002C1E 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  9311 00002C20 E8C3020000          <1> 	call	CHECK_STATUS
  9312                              <1> INIT_EXIT:
  9313 00002C25 C3                  <1> 	RETn
  9314                              <1> 
  9315                              <1> ;----------------------------------------
  9316                              <1> ;	READ LONG	     (AH = 0AH) :
  9317                              <1> ;----------------------------------------
  9318                              <1> 
  9319                              <1> RD_LONG:
  9320                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  9321 00002C26 C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  9322 00002C2A E9E0000000          <1>         JMP     COMMANDI
  9323                              <1> 
  9324                              <1> ;----------------------------------------
  9325                              <1> ;	WRITE LONG	     (AH = 0BH) :
  9326                              <1> ;----------------------------------------
  9327                              <1> 
  9328                              <1> WR_LONG:
  9329                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  9330 00002C2F C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  9331 00002C33 E92C010000          <1>         JMP     COMMANDO
  9332                              <1> 
  9333                              <1> ;----------------------------------------
  9334                              <1> ;	SEEK		     (AH = 0CH) :
  9335                              <1> ;----------------------------------------
  9336                              <1> 
  9337                              <1> DISK_SEEK:
  9338 00002C38 C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  9339 00002C3C E89A010000          <1> 	CALL	COMMAND
  9340 00002C41 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  9341 00002C43 E80C020000          <1> 	CALL	_WAIT
  9342 00002C48 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  9343 00002C4A E899020000          <1> 	CALL	CHECK_STATUS
  9344 00002C4F 803D[0F710000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  9345 00002C56 7507                <1> 	JNE	short DS_EXIT
  9346 00002C58 C605[0F710000]00    <1>         MOV     byte [DISK_STATUS1],0
  9347                              <1> DS_EXIT:
  9348 00002C5F C3                  <1> 	RETn
  9349                              <1> 
  9350                              <1> ;----------------------------------------
  9351                              <1> ;	TEST DISK READY      (AH = 10H) :
  9352                              <1> ;----------------------------------------
  9353                              <1> 
  9354                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  9355 00002C60 E82B020000          <1> 	CALL	NOT_BUSY
  9356 00002C65 751C                <1> 	JNZ	short TR_EX
  9357 00002C67 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  9358 00002C6A 668B15[246B0000]    <1> 	MOV	DX,[HF_PORT]
  9359 00002C71 80C206              <1> 	add	dl,6
  9360 00002C74 EE                  <1> 	OUT	DX,AL
  9361 00002C75 E886020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  9362 00002C7A 7507                <1> 	JNZ	short TR_EX
  9363 00002C7C C605[0F710000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  9364                              <1> TR_EX:	
  9365 00002C83 C3                  <1> 	RETn
  9366                              <1> 
  9367                              <1> ;----------------------------------------
  9368                              <1> ;	RECALIBRATE	     (AH = 11H) :
  9369                              <1> ;----------------------------------------
  9370                              <1> 
  9371                              <1> HDISK_RECAL:
  9372 00002C84 C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  9373 00002C88 E84E010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  9374 00002C8D 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  9375 00002C8F E8C0010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  9376 00002C94 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  9377 00002C96 E8B9010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  9378 00002C9B 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  9379                              <1> RECAL_X:
  9380 00002C9D E846020000          <1> 	CALL	CHECK_STATUS
  9381 00002CA2 803D[0F710000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  9382 00002CA9 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  9383 00002CAB C605[0F710000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9384                              <1> RECAL_EXIT:
  9385 00002CB2 803D[0F710000]00    <1>         CMP     byte [DISK_STATUS1],0
  9386 00002CB9 C3                  <1> 	RETn
  9387                              <1> 
  9388                              <1> ;----------------------------------------
  9389                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  9390                              <1> ;----------------------------------------
  9391                              <1> 
  9392                              <1> CTLR_DIAGNOSTIC:
  9393 00002CBA FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  9394 00002CBB E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9395                              <1> 	;AND	AL,0BFH
  9396 00002CBD 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  9397                              <1> 	;JMP	$+2
  9398                              <1> 	IODELAY
  9399 00002CBF EB00                <2>  jmp short $+2
  9400 00002CC1 EB00                <2>  jmp short $+2
  9401 00002CC3 E6A1                <1> 	OUT	INTB01,AL
  9402                              <1> 	IODELAY
  9403 00002CC5 EB00                <2>  jmp short $+2
  9404 00002CC7 EB00                <2>  jmp short $+2
  9405 00002CC9 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9406 00002CCB 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9407                              <1> 	;JMP	$+2
  9408                              <1> 	IODELAY
  9409 00002CCD EB00                <2>  jmp short $+2
  9410 00002CCF EB00                <2>  jmp short $+2
  9411 00002CD1 E621                <1> 	OUT	INTA01,AL
  9412 00002CD3 FB                  <1> 	STI
  9413 00002CD4 E8B7010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  9414 00002CD9 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  9415                              <1> 	;MOV	DX, HF_PORT+7
  9416 00002CDB 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]
  9417 00002CE2 80C207              <1> 	add	dl, 7
  9418 00002CE5 B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  9419 00002CE7 EE                  <1> 	OUT	DX,AL
  9420 00002CE8 E8A3010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  9421 00002CED B480                <1> 	MOV	AH,TIME_OUT
  9422 00002CEF 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  9423                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  9424 00002CF1 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]
  9425 00002CF8 FEC2                <1> 	inc	dl
  9426 00002CFA EC                  <1> 	IN	AL,DX
  9427 00002CFB A2[06710000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  9428 00002D00 B400                <1> 	MOV	AH,0
  9429 00002D02 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  9430 00002D04 7402                <1> 	JE	SHORT CD_EXIT
  9431 00002D06 B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  9432                              <1> CD_EXIT:
  9433 00002D08 8825[0F710000]      <1> 	MOV	[DISK_STATUS1],AH
  9434 00002D0E C3                  <1> 	RETn
  9435                              <1> 
  9436                              <1> ;----------------------------------------
  9437                              <1> ; COMMANDI				:
  9438                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  9439                              <1> ;	NSECTOR RETURNS ZERO		:
  9440                              <1> ;----------------------------------------
  9441                              <1> COMMANDI:
  9442 00002D0F E85A020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9443 00002D14 724D                <1> 	JC	short CMD_ABORT
  9444                              <1> 	;MOV	DI,BX
  9445 00002D16 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  9446 00002D18 E8BE000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9447 00002D1D 7544                <1> 	JNZ	short CMD_ABORT
  9448                              <1> CMD_I1:
  9449 00002D1F E830010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  9450 00002D24 753D                <1> 	JNZ	short TM_OUT		; TIME OUT
  9451                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  9452 00002D26 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  9453                              <1> 	;MOV	DX,HF_PORT
  9454 00002D2B 668B15[246B0000]    <1> 	mov	dx,[HF_PORT]
  9455 00002D32 FA                  <1> 	CLI
  9456 00002D33 FC                  <1> 	CLD
  9457 00002D34 F3666D              <1> 	REP	INSW			; GET THE SECTOR
  9458 00002D37 FB                  <1> 	STI
  9459 00002D38 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  9460 00002D3C 7419                <1> 	JZ	CMD_I3
  9461 00002D3E E87A010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9462 00002D43 721E                <1> 	JC	short TM_OUT
  9463                              <1> 	;MOV	DX,HF_PORT
  9464 00002D45 668B15[246B0000]    <1> 	mov	dx,[HF_PORT]
  9465                              <1> 	;MOV	CX,4			; GET ECC BYTES
  9466 00002D4C B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  9467 00002D51 EC                  <1> CMD_I2: IN	AL,DX
  9468                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  9469 00002D52 8807                <1> 	mov 	[edi], al ; 21/02/2015
  9470 00002D54 47                  <1> 	INC	eDI
  9471 00002D55 E2FA                <1> 	LOOP	CMD_I2
  9472 00002D57 E88C010000          <1> CMD_I3: CALL	CHECK_STATUS
  9473 00002D5C 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  9474 00002D5E FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  9475 00002D61 75BC                <1> 	JNZ	SHORT CMD_I1
  9476                              <1> CMD_ABORT:
  9477 00002D63 C3                  <1> TM_OUT: RETn
  9478                              <1> 
  9479                              <1> ;----------------------------------------
  9480                              <1> ; COMMANDO				:
  9481                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  9482                              <1> ;	NSECTOR RETURNS ZERO		:
  9483                              <1> ;----------------------------------------
  9484                              <1> COMMANDO:
  9485 00002D64 E805020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9486 00002D69 72F8                <1> 	JC	short CMD_ABORT
  9487 00002D6B 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  9488 00002D6D E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9489 00002D72 75EF                <1> 	JNZ	short CMD_ABORT
  9490 00002D74 E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9491 00002D79 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  9492                              <1> CMD_O1: ;PUSH	DS
  9493                              <1> 	;PUSH	ES			; MOVE ES TO DS
  9494                              <1> 	;POP	DS
  9495                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  9496                              <1> 	;MOV	DX,HF_PORT
  9497                              <1> 	; 01/02/2015
  9498 00002D7B 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]
  9499                              <1> 	;push	es
  9500                              <1> 	;pop	ds
  9501                              <1> 	;mov	cx, 256
  9502 00002D82 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  9503 00002D87 FA                  <1> 	CLI
  9504 00002D88 FC                  <1> 	CLD
  9505 00002D89 F3666F              <1> 	REP	OUTSW
  9506 00002D8C FB                  <1> 	STI
  9507                              <1> 	;POP	DS			; RESTORE DS
  9508 00002D8D F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  9509 00002D91 7419                <1> 	JZ	short CMD_O3
  9510 00002D93 E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9511 00002D98 72C9                <1> 	JC	short TM_OUT
  9512                              <1> 	;MOV	DX,HF_PORT
  9513 00002D9A 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]
  9514                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  9515 00002DA1 B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  9516                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  9517 00002DA6 8A06                <1> 	mov	al, [esi]
  9518 00002DA8 EE                  <1> 	OUT	DX,AL
  9519 00002DA9 46                  <1> 	INC	eSI
  9520 00002DAA E2FA                <1> 	LOOP	CMD_O2
  9521                              <1> CMD_O3:
  9522 00002DAC E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  9523 00002DB1 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  9524 00002DB3 E830010000          <1> 	CALL	CHECK_STATUS
  9525 00002DB8 75A9                <1> 	JNZ	short CMD_ABORT
  9526 00002DBA F605[05710000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  9527 00002DC1 75B8                <1> 	JNZ	SHORT CMD_O1
  9528                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  9529 00002DC3 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]
  9530                              <1> 	;add	dl, 2
  9531 00002DCA FEC2                <1> 	inc	dl
  9532 00002DCC FEC2                <1> 	inc	dl
  9533 00002DCE EC                  <1> 	IN	AL,DX			;
  9534 00002DCF A8FF                <1> 	TEST	AL,0FFH 		;
  9535 00002DD1 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  9536 00002DD3 C605[0F710000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  9537                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  9538                              <1> CMD_O4:
  9539 00002DDA C3                  <1> 	RETn
  9540                              <1> 
  9541                              <1> ;--------------------------------------------------------
  9542                              <1> ; COMMAND						:
  9543                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  9544                              <1> ; OUTPUT						:
  9545                              <1> ;	BL = STATUS					:
  9546                              <1> ;	BH = ERROR REGISTER				:
  9547                              <1> ;--------------------------------------------------------
  9548                              <1> 
  9549                              <1> COMMAND:
  9550 00002DDB 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  9551                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  9552                              <1> COMMAND1:
  9553                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  9554 00002DDC E87FFEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  9555                              <1> 	;;POP	CX
  9556 00002DE1 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  9557 00002DE3 803D[0F710000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  9558                              <1> 	;JZ	short CMD_TIMEOUT
  9559                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  9560                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  9561 00002DEA 7507                <1> 	jne	short COMMAND4
  9562                              <1> CMD_TIMEOUT:
  9563 00002DEC C605[0F710000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9564                              <1> COMMAND4:
  9565 00002DF3 5B                  <1> 	POP	eBX
  9566 00002DF4 803D[0F710000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  9567 00002DFB C3                  <1> 	RETn
  9568                              <1> COMMAND2:
  9569 00002DFC 5B                  <1> 	POP	eBX
  9570 00002DFD 57                  <1> 	PUSH	eDI
  9571 00002DFE C605[07710000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  9572 00002E05 FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  9573 00002E06 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9574                              <1> 	;AND	AL,0BFH
  9575 00002E08 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  9576                              <1> 	;JMP	$+2
  9577                              <1> 	IODELAY
  9578 00002E0A EB00                <2>  jmp short $+2
  9579 00002E0C EB00                <2>  jmp short $+2
  9580 00002E0E E6A1                <1> 	OUT	INTB01,AL
  9581 00002E10 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9582 00002E12 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9583                              <1> 	;JMP	$+2
  9584                              <1> 	IODELAY
  9585 00002E14 EB00                <2>  jmp short $+2
  9586 00002E16 EB00                <2>  jmp short $+2
  9587 00002E18 E621                <1> 	OUT	INTA01,AL
  9588 00002E1A FB                  <1> 	STI
  9589 00002E1B 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  9590                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  9591 00002E1D 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]
  9592 00002E24 FEC2                <1> 	inc	dl
  9593 00002E26 F605[11710000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  9594 00002E2D 7411                <1> 	JZ	short COMMAND3
  9595 00002E2F 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  9596 00002E32 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  9597 00002E34 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  9598 00002E36 7208                <1> 	JB	short COMMAND3
  9599 00002E38 3C40                <1> 	CMP	AL,40H
  9600 00002E3A 7704                <1> 	JA	short COMMAND3
  9601 00002E3C 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  9602                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  9603                              <1> COMMAND3:
  9604 00002E40 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  9605 00002E44 EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  9606                              <1> 	IODELAY
  9607 00002E45 EB00                <2>  jmp short $+2
  9608 00002E47 EB00                <2>  jmp short $+2
  9609 00002E49 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  9610 00002E4A 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  9611 00002E4C 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  9612 00002E50 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  9613 00002E52 5F                  <1> 	POP	eDI
  9614 00002E53 C3                  <1> 	RETn				; ZERO FLAG IS SET
  9615                              <1> 
  9616                              <1> ;CMD_TIMEOUT:
  9617                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9618                              <1> ;COMMAND4:
  9619                              <1> ;	POP	BX
  9620                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9621                              <1> ;	RETn
  9622                              <1> 
  9623                              <1> ;----------------------------------------
  9624                              <1> ;	WAIT FOR INTERRUPT		:
  9625                              <1> ;----------------------------------------
  9626                              <1> ;WAIT:
  9627                              <1> _WAIT:
  9628 00002E54 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  9629                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  9630                              <1> 	;CLC
  9631                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  9632                              <1> 	;INT	15H
  9633                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  9634                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  9635                              <1> 
  9636                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  9637                              <1> 	;; 21/02/2015
  9638                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  9639                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  9640 00002E55 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  9641                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  9642                              <1> ;-----	WAIT LOOP
  9643                              <1> 
  9644                              <1> WT1:	
  9645                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
  9646 00002E5A F605[07710000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  9647                              <1> 	;LOOPZ	WT1
  9648 00002E61 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
  9649                              <1> 	;DEC	BL
  9650                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
  9651                              <1> 
  9652                              <1> WT1_hi:
  9653 00002E63 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  9654 00002E65 A810                <1> 	test	al, 10h			; transition on memory
  9655 00002E67 75FA                <1> 	jnz	short WT1_hi		; refresh.
  9656                              <1> WT1_lo:
  9657 00002E69 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  9658 00002E6B A810                <1> 	test	al, 10h			
  9659 00002E6D 74FA                <1> 	jz	short WT1_lo
  9660 00002E6F E2E9                <1> 	loop	WT1
  9661                              <1> 	;;or	bl, bl
  9662                              <1> 	;;jz	short WT2	
  9663                              <1> 	;;dec	bl
  9664                              <1> 	;;jmp	short WT1
  9665                              <1> 	;dec	bl
  9666                              <1> 	;jnz	short WT1	
  9667                              <1> 
  9668 00002E71 C605[0F710000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  9669 00002E78 EB0E                <1> 	JMP	SHORT WT4
  9670 00002E7A C605[0F710000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  9671 00002E81 C605[07710000]00    <1> 	MOV	byte [HF_INT_FLAG],0
  9672 00002E88 803D[0F710000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9673 00002E8F C3                  <1> 	RETn
  9674                              <1> 
  9675                              <1> ;----------------------------------------
  9676                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  9677                              <1> ;----------------------------------------
  9678                              <1> NOT_BUSY:
  9679 00002E90 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  9680                              <1> 	;PUSH	eBX
  9681                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  9682 00002E91 668B15[246B0000]    <1> 	mov	DX, [HF_PORT]
  9683 00002E98 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  9684                              <1> 	;MOV	BL,DELAY_1
  9685                              <1> 					; wait for 10 seconds
  9686                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  9687                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  9688                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  9689 00002E9B B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  9690                              <1> 	;
  9691                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
  9692                              <1> NB1:	
  9693 00002EA0 EC                  <1> 	IN	AL,DX			; CHECK STATUS
  9694                              <1> 	;TEST	AL,ST_BUSY
  9695 00002EA1 2480                <1> 	and	al, ST_BUSY
  9696                              <1> 	;LOOPNZ	NB1
  9697 00002EA3 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
  9698                              <1> 	;DEC	BL			
  9699                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
  9700                              <1> 
  9701 00002EA5 E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  9702 00002EA7 A810                <1> 	TEST	AL,010H			; transition on memory
  9703 00002EA9 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  9704 00002EAB E461                <1> NB1_lo: IN	AL,SYS1
  9705 00002EAD A810                <1> 	TEST	AL,010H
  9706 00002EAF 74FA                <1> 	JZ	short NB1_lo
  9707 00002EB1 E2ED                <1> 	LOOP	NB1
  9708                              <1> 	;dec	bl
  9709                              <1> 	;jnz	short NB1
  9710                              <1> 	;
  9711                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  9712                              <1> ;;	jb	short NB1
  9713                              <1> 	;
  9714                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
  9715                              <1> 	;JMP	SHORT NB3
  9716 00002EB3 B080                <1> 	mov	al, TIME_OUT
  9717                              <1> NB2:	
  9718                              <1> 	;MOV	byte [DISK_STATUS1],0
  9719                              <1> ;NB3:	
  9720                              <1> 	;POP	eBX
  9721 00002EB5 A2[0F710000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  9722                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9723 00002EBA 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  9724 00002EBC C3                  <1> 	RETn
  9725                              <1> 
  9726                              <1> ;----------------------------------------
  9727                              <1> ;	WAIT FOR DATA REQUEST		:
  9728                              <1> ;----------------------------------------
  9729                              <1> WAIT_DRQ:
  9730                              <1> 	;MOV	CX,DELAY_3
  9731                              <1> 	;MOV	DX,HF_PORT+7
  9732 00002EBD 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]
  9733 00002EC4 80C207              <1> 	add	dl, 7
  9734                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
  9735                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  9736                              <1> 					; (but it is written as 2000
  9737                              <1> 					; micro seconds in ATORGS.ASM file
  9738                              <1> 					; of Award Bios - 1999, D1A0622)
  9739 00002EC7 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  9740 00002ECC EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  9741 00002ECD A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  9742 00002ECF 7516                <1> 	JNZ	short WQ_OK
  9743                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  9744                              <1> WQ_hi:	
  9745 00002ED1 E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  9746 00002ED3 A810                <1> 	TEST	AL,010H			; transition on memory
  9747 00002ED5 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  9748 00002ED7 E461                <1> WQ_lo:  IN      AL,SYS1
  9749 00002ED9 A810                <1> 	TEST	AL,010H
  9750 00002EDB 74FA                <1> 	JZ	SHORT WQ_lo
  9751 00002EDD E2ED                <1> 	LOOP	WQ_1
  9752                              <1> 
  9753 00002EDF C605[0F710000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  9754 00002EE6 F9                  <1> 	STC
  9755                              <1> WQ_OK:
  9756 00002EE7 C3                  <1> 	RETn
  9757                              <1> ;WQ_OK:	;CLC
  9758                              <1> ;	RETn
  9759                              <1> 
  9760                              <1> ;----------------------------------------
  9761                              <1> ;	CHECK FIXED DISK STATUS 	:
  9762                              <1> ;----------------------------------------
  9763                              <1> CHECK_STATUS:
  9764 00002EE8 E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  9765 00002EED 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  9766 00002EEF A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  9767 00002EF1 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  9768 00002EF3 E847000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  9769                              <1> CHECK_S1:
  9770 00002EF8 803D[0F710000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  9771 00002EFF C3                  <1> 	RETn
  9772                              <1> 
  9773                              <1> ;----------------------------------------
  9774                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  9775                              <1> ;----------------------------------------
  9776                              <1> CHECK_ST:
  9777                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
  9778 00002F00 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]
  9779 00002F07 80C207              <1> 	add	dl, 7
  9780 00002F0A EC                  <1> 	IN	AL,DX
  9781 00002F0B A2[05710000]        <1> 	MOV	[HF_STATUS],AL
  9782 00002F10 B400                <1> 	MOV	AH,0
  9783 00002F12 A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  9784 00002F14 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  9785 00002F16 B4CC                <1> 	MOV	AH,WRITE_FAULT
  9786 00002F18 A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  9787 00002F1A 7514                <1> 	JNZ	short CKST_EXIT
  9788 00002F1C B4AA                <1> 	MOV	AH,NOT_RDY
  9789 00002F1E A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  9790 00002F20 740E                <1> 	JZ	short CKST_EXIT
  9791 00002F22 B440                <1> 	MOV	AH,BAD_SEEK
  9792 00002F24 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  9793 00002F26 7408                <1> 	JZ	short CKST_EXIT
  9794 00002F28 B411                <1> 	MOV	AH,DATA_CORRECTED
  9795 00002F2A A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  9796 00002F2C 7502                <1> 	JNZ	short CKST_EXIT
  9797 00002F2E B400                <1> 	MOV	AH,0
  9798                              <1> CKST_EXIT:
  9799 00002F30 8825[0F710000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  9800 00002F36 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  9801 00002F39 7403                <1> 	JZ	short CKST_EX1
  9802 00002F3B 80FC00              <1> 	CMP	AH,0
  9803                              <1> CKST_EX1:
  9804 00002F3E C3                  <1> 	RETn
  9805                              <1> 
  9806                              <1> ;----------------------------------------
  9807                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  9808                              <1> ;----------------------------------------
  9809                              <1> CHECK_ER:
  9810                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
  9811 00002F3F 668B15[246B0000]    <1> 	mov	dx, [HF_PORT]		;
  9812 00002F46 FEC2                <1> 	inc	dl
  9813 00002F48 EC                  <1> 	IN	AL,DX
  9814 00002F49 A2[06710000]        <1> 	MOV	[HF_ERROR],AL
  9815 00002F4E 53                  <1> 	PUSH	eBX ; 21/02/2015
  9816 00002F4F B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  9817 00002F54 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  9818 00002F56 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  9819 00002F58 E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  9820 00002F5A BB[186B0000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  9821 00002F5F 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  9822                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  9823                              <1> 	;mov	ah, [bx]
  9824 00002F61 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  9825 00002F63 8825[0F710000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  9826 00002F69 5B                  <1> 	POP	eBX
  9827 00002F6A 80FC00              <1> 	CMP	AH,0
  9828 00002F6D C3                  <1> 	RETn
  9829                              <1> 
  9830                              <1> ;--------------------------------------------------------
  9831                              <1> ; CHECK_DMA						:
  9832                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  9833                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  9834                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  9835                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  9836                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  9837                              <1> ;  -ERROR OTHERWISE					:
  9838                              <1> ;--------------------------------------------------------
  9839                              <1> CHECK_DMA:
  9840 00002F6E 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  9841 00002F70 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  9842 00002F74 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  9843 00002F78 7404                <1> 	JZ	short CKD1
  9844 00002F7A 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  9845 00002F7E 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  9846 00002F81 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  9847 00002F83 7208                <1> 	JB	short CKDERR		; TOO MANY
  9848 00002F85 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  9849 00002F87 7204                <1> 	JB	short CKDERR		; ERROR
  9850 00002F89 F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  9851 00002F8A 6658                <1> 	POP	AX
  9852 00002F8C C3                  <1> 	RETn				; NORMAL RETURN
  9853 00002F8D F9                  <1> CKDERR: STC				; INDICATE ERROR
  9854 00002F8E C605[0F710000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  9855 00002F95 6658                <1> 	POP	AX
  9856 00002F97 C3                  <1> 	RETn
  9857                              <1> 
  9858                              <1> ;----------------------------------------
  9859                              <1> ;	SET UP ES:BX-> DISK PARMS	:
  9860                              <1> ;----------------------------------------
  9861                              <1> 					
  9862                              <1> ; INPUT -> DL = 0 based drive number
  9863                              <1> ; OUTPUT -> ES:BX = disk parameter table address
  9864                              <1> 
  9865                              <1> GET_VEC:
  9866                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
  9867                              <1> 	;MOV	ES,AX
  9868                              <1> 	;TEST	DL,1
  9869                              <1> 	;JZ	short GV_0
  9870                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  9871                              <1> ;	JMP	SHORT GV_EXIT
  9872                              <1> ;GV_0:
  9873                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  9874                              <1> ;
  9875                              <1> 	;xor	bh, bh
  9876 00002F98 31DB                <1> 	xor	ebx, ebx
  9877 00002F9A 88D3                <1> 	mov	bl, dl
  9878                              <1> 	;;02/01/2015
  9879                              <1> 	;;shl	bl, 1			; port address offset
  9880                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  9881                              <1> 	;;shl	bl, 1			; dpt pointer offset
  9882 00002F9C C0E302              <1> 	shl	bl, 2	;;
  9883                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  9884 00002F9F 81C3[14710000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  9885                              <1> 	;push	word [bx+2]		; dpt segment
  9886                              <1> 	;pop	es
  9887                              <1> 	;mov	bx, [bx]		; dpt offset
  9888 00002FA5 8B1B                <1> 	mov	ebx, [ebx]		
  9889                              <1> ;GV_EXIT:
  9890 00002FA7 C3                  <1> 	RETn
  9891                              <1> 
  9892                              <1> hdc1_int: ; 21/02/2015
  9893                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  9894                              <1> ;								:
  9895                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  9896                              <1> ;								:
  9897                              <1> ;----------------------------------------------------------------
  9898                              <1> 
  9899                              <1> ; 22/12/2014
  9900                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  9901                              <1> ;	 '11/15/85'
  9902                              <1> ; AWARD BIOS 1999 (D1A0622) 
  9903                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  9904                              <1> 
  9905                              <1> ;int_76h:
  9906                              <1> HD_INT:
  9907 00002FA8 6650                <1> 	PUSH	AX
  9908 00002FAA 1E                  <1> 	PUSH	DS
  9909                              <1> 	;CALL	DDS
  9910                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  9911 00002FAB 66B81000            <1> 	mov	ax, KDATA
  9912 00002FAF 8ED8                <1> 	mov 	ds, ax
  9913                              <1> 	;
  9914                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  9915                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
  9916 00002FB1 C605[07710000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  9917                              <1> 	;
  9918 00002FB8 6652                <1> 	push	dx
  9919 00002FBA 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  9920                              <1> 					; Clear Controller
  9921                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  9922 00002FBE EC                  <1> 	in	al, dx			;
  9923 00002FBF 665A                <1> 	pop	dx
  9924                              <1> 	NEWIODELAY
  9925 00002FC1 E6EB                <2>  out 0ebh,al
  9926                              <1> 	;
  9927 00002FC3 B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  9928 00002FC5 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  9929                              <1> 	;JMP	$+2			; WAIT
  9930                              <1> 	NEWIODELAY
  9931 00002FC7 E6EB                <2>  out 0ebh,al
  9932 00002FC9 E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  9933 00002FCB 1F                  <1> 	POP	DS
  9934                              <1> 	;STI				; RE-ENABLE INTERRUPTS
  9935                              <1> 	;MOV	AX,9100H		; DEVICE POST
  9936                              <1> 	;INT	15H			;  INTERRUPT
  9937                              <1> irq15_iret: ; 25/02/2015
  9938 00002FCC 6658                <1> 	POP	AX
  9939 00002FCE CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  9940                              <1> 
  9941                              <1> hdc2_int: ; 21/02/2015
  9942                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
  9943                              <1> ;								:
  9944                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  9945                              <1> ;								:
  9946                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9947                              <1> 
  9948                              <1> ;int_77h:
  9949                              <1> HD1_INT:
  9950 00002FCF 6650                <1> 	PUSH	AX
  9951                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  9952                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  9953 00002FD1 B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  9954 00002FD3 E6A0                <1> 	out	0A0h, al
  9955 00002FD5 EB00                <1>         jmp short $+2
  9956 00002FD7 EB00                <1> 	jmp short $+2
  9957 00002FD9 E4A0                <1> 	in	al, 0A0h
  9958 00002FDB 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  9959 00002FDD 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  9960                              <1> 	;
  9961 00002FDF 1E                  <1> 	PUSH	DS
  9962                              <1> 	;CALL	DDS
  9963                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  9964 00002FE0 66B81000            <1> 	mov	ax, KDATA
  9965 00002FE4 8ED8                <1> 	mov 	ds, ax
  9966                              <1> 	;
  9967                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  9968                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
  9969 00002FE6 800D[07710000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  9970                              <1> 	;
  9971 00002FED 6652                <1> 	push	dx
  9972 00002FEF 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  9973                              <1> 					; Clear Controller (Award BIOS 1999)
  9974 00002FF3 EBC9                <1> 	jmp	short Clear_IRQ1415
  9975                              <1> 
  9976                              <1> 
  9977                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  9978                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  9979                              <1> 
  9980                              <1> 
  9981                              <1> ;////////////////////////////////////////////////////////////////////
  9982                              <1> ;; END OF DISK I/O SYTEM ///
  9983                                  %include 'memory.inc'  ; 09/03/2015
  9984                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
  9985                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
  9986                              <1> ; Last Modification: 18/10/2015 (!not completed!)
  9987                              <1> ;
  9988                              <1> ; Source code for NASM - Netwide Assembler (2.11)
  9989                              <1> 
  9990                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
  9991                              <1> 
  9992                              <1> ;;04/11/2014 (unix386.s)	
  9993                              <1> ;PDE_A_PRESENT	equ	1		; Present flag for PDE
  9994                              <1> ;PDE_A_WRITE	equ 	2		; Writable (write permission) flag
  9995                              <1> ;PDE_A_USER	equ	4		; User (non-system/kernel) page flag
  9996                              <1> ;;
  9997                              <1> ;PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
  9998                              <1> ;PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
  9999                              <1> ;PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
 10000                              <1> ;PTE_A_ACCESS   equ	32		; Accessed flag (bit 5) ; 09/03/2015
 10001                              <1> 
 10002                              <1> ; 27/04/2015
 10003                              <1> ; 09/03/2015
 10004                              <1> PAGE_SIZE 	equ 4096		; page size in bytes
 10005                              <1> PAGE_SHIFT 	equ 12			; page table shift count
 10006                              <1> PAGE_D_SHIFT 	equ 22	; 12 + 10	; page directory shift count
 10007                              <1> PAGE_OFF	equ 0FFFh		; 12 bit byte offset in page frame
 10008                              <1> PTE_MASK 	equ 03FFh		; page table entry mask
 10009                              <1> PTE_DUPLICATED  equ 200h		; duplicated page sign (AVL bit 0)
 10010                              <1> PDE_A_CLEAR	equ 0F000h		; to clear PDE attribute bits
 10011                              <1> PTE_A_CLEAR	equ 0F000h		; to clear PTE attribute bits
 10012                              <1> LOGIC_SECT_SIZE equ 512			; logical sector size
 10013                              <1> ERR_MAJOR_PF	equ 0E0h		; major error: page fault
 10014                              <1> ERR_MINOR_IM	equ 1			; insufficient (out of) memory
 10015                              <1> ERR_MINOR_DSK	equ 2			; disk read/write error
 10016                              <1> ERR_MINOR_PV	equ 3			; protection violation
 10017                              <1> SWP_DISK_READ_ERR equ 4
 10018                              <1> SWP_DISK_NOT_PRESENT_ERR equ 5
 10019                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 6
 10020                              <1> SWP_NO_FREE_SPACE_ERR equ 7
 10021                              <1> SWP_DISK_WRITE_ERR equ 8
 10022                              <1> SWP_NO_PAGE_TO_SWAP_ERR equ 9
 10023                              <1> PTE_A_ACCESS_BIT equ 5  ; Bit 5 (accessed flag)        
 10024                              <1> SECTOR_SHIFT    equ 3   ; sector shift (to convert page block number)
 10025                              <1> 
 10026                              <1> ;
 10027                              <1> ;; Retro Unix 386 v1 - paging method/principles
 10028                              <1> ;;
 10029                              <1> ;; 10/10/2014
 10030                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
 10031                              <1> ;;
 10032                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
 10033                              <1> ;;	(virtual address = physical address)
 10034                              <1> ;; KERNEL PAGE TABLES:
 10035                              <1> ;;	Kernel page directory and all page tables are
 10036                              <1> ;;	on memory as initialized, as equal to physical memory
 10037                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
 10038                              <1> ;;
 10039                              <1> ;;	what for: User pages may be swapped out, when accessing
 10040                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
 10041                              <1> ;;	kernel would have to swap it in! But it is also may be
 10042                              <1> ;;	in use by a user process. (In system/kernel mode
 10043                              <1> ;;	kernel can access all memory pages even if they are
 10044                              <1> ;;	reserved/allocated for user processes. Swap out/in would
 10045                              <1> ;;	cause conflicts.) 
 10046                              <1> ;;	
 10047                              <1> ;;	As result of these conditions,
 10048                              <1> ;;	all kernel pages must be initialized as equal to 
 10049                              <1> ;;	physical layout for preventing page faults. 
 10050                              <1> ;;	Also, calling "allocate page" procedure after
 10051                              <1> ;;	a page fault can cause another page fault (double fault)
 10052                              <1> ;;	if all kernel page tables would not be initialized.
 10053                              <1> ;;
 10054                              <1> ;;	[first_page] = Beginning of users space, as offset to 
 10055                              <1> ;;	memory allocation table. (double word aligned)
 10056                              <1> ;;
 10057                              <1> ;;	[next_page] = first/next free space to be searched
 10058                              <1> ;;	as offset to memory allocation table. (dw aligned)
 10059                              <1> ;;
 10060                              <1> ;;	[last_page] = End of memory (users space), as offset
 10061                              <1> ;;	to memory allocation table. (double word aligned)
 10062                              <1> ;;
 10063                              <1> ;; USER PAGE TABLES:
 10064                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
 10065                              <1> ;;		'ready only' marked copies of the 
 10066                              <1> ;;		parent process's page table entries (for
 10067                              <1> ;;		same physical memory).
 10068                              <1> ;;		(A page will be copied to a new page after
 10069                              <1> ;;		 if it causes R/W page fault.)
 10070                              <1> ;;
 10071                              <1> ;;	Every user process has own (different)
 10072                              <1> ;;	page directory and page tables.	
 10073                              <1> ;;
 10074                              <1> ;;	Code starts at virtual address 0, always.
 10075                              <1> ;;	(Initial value of EIP is 0 in user mode.)
 10076                              <1> ;;	(Programs can be written/developed as simple
 10077                              <1> ;;	 flat memory programs.)
 10078                              <1> ;;
 10079                              <1> ;; MEMORY ALLOCATION STRATEGY:
 10080                              <1> ;;	Memory page will be allocated by kernel only 
 10081                              <1> ;;		(in kernel/system mode only).
 10082                              <1> ;;	* After a
 10083                              <1> ;;	  - 'not present' page fault
 10084                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
 10085                              <1> ;;	* For loading (opening, reading) a file or disk/drive
 10086                              <1> ;;	* As responce to 'allocate additional memory blocks' 
 10087                              <1> ;;	  request by running process.
 10088                              <1> ;;	* While creating a process, allocating a new buffer,
 10089                              <1> ;;	  new page tables etc.
 10090                              <1> ;;
 10091                              <1> ;;	At first,
 10092                              <1> ;;	- 'allocate page' procedure will be called;
 10093                              <1> ;,	   if it will return with a valid (>0) physical address
 10094                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
 10095                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
 10096                              <1> ;;	- 'allocate page' will be called for allocating page
 10097                              <1> ;;	   directory, page table and running space (data/code).
 10098                              <1> ;;	- every successful 'allocate page' call will decrease
 10099                              <1> ;;	  'free_pages' count (pointer).
 10100                              <1> ;;	- 'out of (insufficient) memory error' will be returned
 10101                              <1> ;;	  if 'free_pages' points to a ZERO.
 10102                              <1> ;;	- swapping out and swapping in (if it is not a new page)
 10103                              <1> ;;	  procedures will be called as responce to 'out of memory'
 10104                              <1> ;;	  error except errors caused by attribute conflicts.
 10105                              <1> ;;	 (swapper functions)	 
 10106                              <1> ;;					
 10107                              <1> ;;	At second,
 10108                              <1> ;;	- page directory entry will be updated then page table
 10109                              <1> ;;	  entry will be updated.		
 10110                              <1> ;;
 10111                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
 10112                              <1> ;;	- M.A.T. has a size according to available memory as
 10113                              <1> ;;	  follows:
 10114                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
 10115                              <1> ;;		  - a bit with value of 0 means allocated page
 10116                              <1> ;;		  - a bit with value of 1 means a free page
 10117                              <1> ;,	- 'free_pages' pointer holds count of free pages
 10118                              <1> ;;	  depending on M.A.T.
 10119                              <1> ;;		(NOTE: Free page count will not be checked
 10120                              <1> ;;		again -on M.A.T.- after initialization. 
 10121                              <1> ;;		Kernel will trust on initial count.)
 10122                              <1> ;,	- 'free_pages' count will be decreased by allocation
 10123                              <1> ;;	  and it will be increased by deallocation procedures.
 10124                              <1> ;;	
 10125                              <1> ;;	- Available memory will be calculated during
 10126                              <1> ;;	  the kernel's initialization stage (in real mode).
 10127                              <1> ;;	  Memory allocation table and kernel page tables 
 10128                              <1> ;;	  will be formatted/sized as result of available
 10129                              <1> ;;	  memory calculation before paging is enabled.
 10130                              <1> ;;
 10131                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
 10132                              <1> ;;	- Memory Allocation Table size will be 128 KB.
 10133                              <1> ;;	- Memory allocation for kernel page directory size 
 10134                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10135                              <1> ;;	  for page tables)
 10136                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
 10137                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
 10138                              <1> ;;	- User (available) space will be started 
 10139                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
 10140                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10141                              <1> ;;	  memory allocation table and kernel's page directory
 10142                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10143                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10144                              <1> ;; 	  for buffers.
 10145                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10146                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10147                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
 10148                              <1> ;;
 10149                              <1> ;; For 1GB Available Memory:
 10150                              <1> ;;	- Memory Allocation Table size will be 32 KB.
 10151                              <1> ;;	- Memory allocation for kernel page directory size 
 10152                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10153                              <1> ;;	  for page tables)
 10154                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
 10155                              <1> ;;	  is 1 MB (256*4*1024 bytes).
 10156                              <1> ;;	- User (available) space will be started 
 10157                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
 10158                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10159                              <1> ;;	  memory allocation table and kernel's page directory
 10160                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10161                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10162                              <1> ;; 	  for buffers.
 10163                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10164                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10165                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
 10166                              <1> ;;
 10167                              <1> ;;
 10168                              <1> 
 10169                              <1> 
 10170                              <1> ;;************************************************************************************
 10171                              <1> ;; 
 10172                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
 10173                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
 10174                              <1> 
 10175                              <1> ;; Main factor: "sys fork" system call 
 10176                              <1> ;;	
 10177                              <1> ;; 		FORK
 10178                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
 10179                              <1> ;;  writable pages ---->|
 10180                              <1> ;;                      |----> child - duplicated PTEs, read only pages
 10181                              <1> ;; 
 10182                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
 10183                              <1> ;; 
 10184                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
 10185                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
 10186                              <1> ;;       -while R/W bit is 0-. 
 10187                              <1> ;; 
 10188                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
 10189                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
 10190                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
 10191                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
 10192                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
 10193                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
 10194                              <1> ;; 
 10195                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
 10196                              <1> ;; # Parent's read only pages are copied to new child pages. 
 10197                              <1> ;;   Parent's PTE attributes are not changed.
 10198                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
 10199                              <1> ;;    destroy/mix previous fork result).
 10200                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
 10201                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
 10202                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
 10203                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
 10204                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
 10205                              <1> ;;   as Child's Page Table Entries without copying actual page.
 10206                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
 10207                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
 10208                              <1> ;; 
 10209                              <1> ;; !? WHAT FOR (duplication after duplication):
 10210                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
 10211                              <1> ;; program/executable code continues from specified location as child process, 
 10212                              <1> ;; returns back previous code location as parent process, every child after 
 10213                              <1> ;; every sys fork uses last image of code and data just prior the fork.
 10214                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
 10215                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
 10216                              <1> ;; was copied to child's process segment (all of code and data) according to
 10217                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
 10218                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
 10219                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
 10220                              <1> ;; (complete running image of parent process) to the child process; 
 10221                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
 10222                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
 10223                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
 10224                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
 10225                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
 10226                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
 10227                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
 10228                              <1> ;; new/fresh pages will be used to load and run new executable/program.
 10229                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
 10230                              <1> ;; for sharing same read only pages between parent and child processes.
 10231                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
 10232                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
 10233                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
 10234                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
 10235                              <1> ;; -deallocation problem-.
 10236                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
 10237                              <1> ;; 
 10238                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10239                              <1> ;; # Page fault handler will do those:
 10240                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10241                              <1> ;;   - If it is reset/clear, there is a child uses same page.
 10242                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
 10243                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
 10244                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
 10245                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
 10246                              <1> ;;     read only page will be converted to writable and unique page which belongs
 10247                              <1> ;;     to child process.)	
 10248                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10249                              <1> ;; # Page fault handler will do those:
 10250                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10251                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
 10252                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
 10253                              <1> ;;     address or not. 
 10254                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
 10255                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
 10256                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
 10257                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
 10258                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
 10259                              <1> ;; 
 10260                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
 10261                              <1> ;;       will be set as writable (and unique) in case of child process was using 
 10262                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
 10263                              <1> ;;       duplication method details, it is not possible multiple child processes
 10264                              <1> ;;       were using same page with duplicated PTEs.
 10265                              <1> ;; 
 10266                              <1> ;;************************************************************************************   
 10267                              <1> 
 10268                              <1> ;; 08/10/2014
 10269                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
 10270                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
 10271                              <1> 
 10272                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
 10273                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
 10274                              <1> ;; (25/08/2014, Revision: 5057) file 
 10275                              <1> ;; by KolibriOS Team (2004-2012)
 10276                              <1> 
 10277                              <1> allocate_page:
 10278                              <1> 	; 01/07/2015
 10279                              <1> 	; 05/05/2015
 10280                              <1> 	; 30/04/2015
 10281                              <1> 	; 16/10/2014
 10282                              <1> 	; 08/10/2014
 10283                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
 10284                              <1> 	;
 10285                              <1> 	; INPUT -> none
 10286                              <1> 	;
 10287                              <1> 	; OUTPUT ->
 10288                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10289                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
 10290                              <1> 	;
 10291                              <1> 	;	CF = 1 and EAX = 0 
 10292                              <1> 	; 		   if there is not a free page to be allocated	
 10293                              <1> 	;
 10294                              <1> 	; Modified Registers -> none (except EAX)
 10295                              <1> 	;
 10296 00002FF5 A1[80700000]        <1> 	mov	eax, [free_pages]
 10297 00002FFA 21C0                <1> 	and	eax, eax
 10298 00002FFC 7438                <1> 	jz	short out_of_memory
 10299                              <1> 	;
 10300 00002FFE 53                  <1> 	push	ebx
 10301 00002FFF 51                  <1> 	push	ecx
 10302                              <1> 	;
 10303 00003000 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
 10304 00003005 89D9                <1> 	mov	ecx, ebx
 10305                              <1>  				     ; NOTE: 32 (first_page) is initial
 10306                              <1> 				     ; value of [next_page].
 10307                              <1> 				     ; It points to the first available
 10308                              <1> 				     ; page block for users (ring 3) ...	
 10309                              <1> 				     ; (MAT offset 32 = 1024/32)	
 10310                              <1> 				     ; (at the of the first 4 MB)		
 10311 00003007 031D[84700000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
 10312                              <1> 				 ; next_free_page >> 5
 10313 0000300D 030D[88700000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
 10314                              <1> 				 ; (total_pages - 1) >> 5
 10315                              <1> al_p_scan:
 10316 00003013 39CB                <1> 	cmp	ebx, ecx
 10317 00003015 770A                <1> 	ja	short al_p_notfound
 10318                              <1> 	;
 10319                              <1> 	; 01/07/2015
 10320                              <1> 	; AMD64 Architecture Programmers Manual
 10321                              <1> 	; Volume 3:
 10322                              <1> 	; General-Purpose and System Instructions
 10323                              <1> 	;
 10324                              <1> 	; BSF - Bit Scan Forward
 10325                              <1> 	;
 10326                              <1> 	;   Searches the value in a register or a memory location
 10327                              <1> 	;   (second operand) for the least-significant set bit. 
 10328                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
 10329                              <1> 	;   and stores the index of the least-significant set bit in a destination
 10330                              <1> 	;   register (first operand). If the second operand contains 0, 
 10331                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
 10332                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
 10333                              <1> 	;   of the searched value
 10334                              <1> 	;
 10335 00003017 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 10336                              <1> 			   ; Clear ZF if a bit is found set (1) and 
 10337                              <1> 			   ; loads the destination with an index to
 10338                              <1> 			   ; first set bit. (0 -> 31) 
 10339                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 10340 0000301A 7525                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
 10341                              <1> 			 ;
 10342                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
 10343                              <1> 			 ;	  with value of 1 means 
 10344                              <1> 			 ;	  the corresponding page is free 
 10345                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
 10346 0000301C 83C304              <1> 	add	ebx, 4
 10347                              <1> 			 ; We return back for searching next page block
 10348                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
 10349                              <1> 			 ;	 we always will find at least 1 free page here.
 10350 0000301F EBF2                <1>         jmp     short al_p_scan
 10351                              <1> 	;
 10352                              <1> al_p_notfound:
 10353 00003021 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10354 00003027 890D[84700000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
 10355                              <1> 				 ; (deallocate_page procedure will change it)
 10356 0000302D 31C0                <1> 	xor	eax, eax
 10357 0000302F A3[80700000]        <1> 	mov	[free_pages], eax ; 0
 10358 00003034 59                  <1> 	pop	ecx
 10359 00003035 5B                  <1> 	pop	ebx
 10360                              <1> 	;
 10361                              <1> out_of_memory:
 10362 00003036 E857040000          <1> 	call	swap_out
 10363 0000303B 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
 10364                              <1> 	;
 10365 0000303D 29C0                <1> 	sub 	eax, eax ; 0
 10366 0000303F F9                  <1> 	stc
 10367 00003040 C3                  <1> 	retn
 10368                              <1> 
 10369                              <1> al_p_found:
 10370 00003041 89D9                <1> 	mov	ecx, ebx
 10371 00003043 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10372 00003049 890D[84700000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
 10373                              <1> 				 ; address/offset (to the next)
 10374 0000304F FF0D[80700000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
 10375                              <1> 	;
 10376 00003055 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 10377                              <1> 				 ; is copied into the Carry Flag and then cleared
 10378                              <1> 				 ; in the destination.
 10379                              <1> 				 ;
 10380                              <1> 				 ; Reset the bit which is corresponding to the 
 10381                              <1> 				 ; (just) allocated page.
 10382                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
 10383 00003058 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
 10384 0000305B 01C8                <1> 	add	eax, ecx	 ; = page number
 10385 0000305D C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
 10386                              <1> 	; EAX = physical address of memory page
 10387                              <1> 	;
 10388                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
 10389                              <1> 	;       according to this EAX value...
 10390 00003060 59                  <1> 	pop	ecx
 10391 00003061 5B                  <1> 	pop	ebx
 10392                              <1> al_p_ok:
 10393 00003062 C3                  <1> 	retn
 10394                              <1> 
 10395                              <1> 
 10396                              <1> make_page_dir:
 10397                              <1> 	; 18/04/2015
 10398                              <1> 	; 12/04/2015
 10399                              <1> 	; 23/10/2014
 10400                              <1> 	; 16/10/2014
 10401                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10402                              <1> 	;
 10403                              <1> 	; INPUT ->
 10404                              <1> 	;	none
 10405                              <1> 	; OUTPUT ->
 10406                              <1> 	;	(EAX = 0)
 10407                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10408                              <1> 	;	cf = 0 ->
 10409                              <1> 	;	u.pgdir = page directory (physical) address of the current
 10410                              <1> 	;		  process/user.
 10411                              <1> 	;
 10412                              <1> 	; Modified Registers -> EAX
 10413                              <1> 	;
 10414 00003063 E88DFFFFFF          <1> 	call	allocate_page
 10415 00003068 7216                <1> 	jc	short mkpd_error
 10416                              <1> 	;
 10417 0000306A A3[AB740000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
 10418                              <1> 				  ; (Physical address)
 10419                              <1> clear_page:
 10420                              <1> 	; 18/04/2015
 10421                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10422                              <1> 	;
 10423                              <1> 	; INPUT ->
 10424                              <1> 	;	EAX = physical address of the page
 10425                              <1> 	; OUTPUT ->
 10426                              <1> 	;	all bytes of the page will be cleared
 10427                              <1> 	;
 10428                              <1> 	; Modified Registers -> none
 10429                              <1> 	;
 10430 0000306F 57                  <1> 	push	edi
 10431 00003070 51                  <1> 	push	ecx
 10432 00003071 50                  <1> 	push	eax
 10433 00003072 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 10434 00003077 89C7                <1> 	mov	edi, eax
 10435 00003079 31C0                <1> 	xor	eax, eax
 10436 0000307B F3AB                <1> 	rep	stosd
 10437 0000307D 58                  <1> 	pop	eax
 10438 0000307E 59                  <1> 	pop	ecx
 10439 0000307F 5F                  <1> 	pop	edi
 10440                              <1> mkpd_error:
 10441                              <1> mkpt_error:
 10442 00003080 C3                  <1> 	retn
 10443                              <1> 
 10444                              <1> make_page_table:
 10445                              <1> 	; 23/06/2015
 10446                              <1> 	; 18/04/2015
 10447                              <1> 	; 12/04/2015
 10448                              <1> 	; 16/10/2014
 10449                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10450                              <1> 	;
 10451                              <1> 	; INPUT ->
 10452                              <1> 	;	EBX = virtual (linear) address
 10453                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10454                              <1> 	;	      (higher 20 bits must be ZERO)
 10455                              <1> 	;	      (bit 0 must be 1)	 
 10456                              <1> 	;	u.pgdir = page directory (physical) address
 10457                              <1> 	; OUTPUT ->
 10458                              <1> 	;	EDX = Page directory entry address
 10459                              <1> 	;	EAX = Page table address
 10460                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10461                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
 10462                              <1> 	;
 10463                              <1> 	; Modified Registers -> EAX, EDX
 10464                              <1> 	;
 10465 00003081 E86FFFFFFF          <1> 	call	allocate_page
 10466 00003086 72F8                <1> 	jc	short mkpt_error
 10467 00003088 E811000000          <1> 	call	set_pde	
 10468 0000308D EBE0                <1> 	jmp	short clear_page
 10469                              <1> 
 10470                              <1> make_page:
 10471                              <1> 	; 24/07/2015
 10472                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
 10473                              <1> 	;
 10474                              <1> 	; INPUT ->
 10475                              <1> 	;	EBX = virtual (linear) address
 10476                              <1> 	;	ECX = page attributes (lower 12 bits)
 10477                              <1> 	;	      (higher 20 bits must be ZERO)
 10478                              <1> 	;	      (bit 0 must be 1)	 
 10479                              <1> 	;	u.pgdir = page directory (physical) address
 10480                              <1> 	; OUTPUT ->
 10481                              <1> 	;	EBX = Virtual address
 10482                              <1> 	;	(EDX = PTE value)
 10483                              <1> 	;	EAX = Physical address
 10484                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10485                              <1> 	;
 10486                              <1> 	; Modified Registers -> EAX, EDX
 10487                              <1> 	;
 10488 0000308F E861FFFFFF          <1> 	call	allocate_page
 10489 00003094 7207                <1> 	jc	short mkp_err
 10490 00003096 E821000000          <1> 	call	set_pte	
 10491 0000309B 73D2                <1> 	jnc	short clear_page ; 18/04/2015
 10492                              <1> mkp_err:
 10493 0000309D C3                  <1> 	retn
 10494                              <1> 
 10495                              <1> 
 10496                              <1> set_pde:	; Set page directory entry (PDE)
 10497                              <1> 	; 20/07/2015
 10498                              <1> 	; 18/04/2015
 10499                              <1> 	; 12/04/2015
 10500                              <1> 	; 23/10/2014
 10501                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10502                              <1> 	;
 10503                              <1> 	; INPUT ->
 10504                              <1> 	;	EAX = physical address
 10505                              <1> 	;	      (use present value if EAX = 0)
 10506                              <1> 	;	EBX = virtual (linear) address
 10507                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10508                              <1> 	;	      (higher 20 bits must be ZERO)
 10509                              <1> 	;	      (bit 0 must be 1)	 
 10510                              <1> 	;	u.pgdir = page directory (physical) address
 10511                              <1> 	; OUTPUT ->
 10512                              <1> 	;	EDX = PDE address
 10513                              <1> 	;	EAX = page table address (physical)
 10514                              <1> 	;	;(CF=1 -> Invalid page address)
 10515                              <1> 	;
 10516                              <1> 	; Modified Registers -> EDX
 10517                              <1> 	;
 10518 0000309E 89DA                <1> 	mov	edx, ebx
 10519 000030A0 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
 10520 000030A3 C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
 10521 000030A6 0315[AB740000]      <1> 	add	edx, [u.pgdir]
 10522                              <1> 	;
 10523 000030AC 21C0                <1> 	and	eax, eax
 10524 000030AE 7506                <1> 	jnz	short spde_1
 10525                              <1> 	;
 10526 000030B0 8B02                <1> 	mov	eax, [edx]  ; old PDE value
 10527                              <1> 	;test	al, 1
 10528                              <1> 	;jz	short spde_2
 10529 000030B2 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
 10530                              <1> spde_1:
 10531                              <1> 	;and	cx, 0FFFh
 10532 000030B6 8902                <1> 	mov	[edx], eax
 10533 000030B8 66090A              <1> 	or	[edx], cx
 10534 000030BB C3                  <1> 	retn
 10535                              <1> ;spde_2: ; error
 10536                              <1> ;	stc
 10537                              <1> ;	retn
 10538                              <1> 
 10539                              <1> set_pte:	; Set page table entry (PTE)
 10540                              <1> 	; 24/07/2015
 10541                              <1> 	; 20/07/2015
 10542                              <1> 	; 23/06/2015
 10543                              <1> 	; 18/04/2015
 10544                              <1> 	; 12/04/2015
 10545                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10546                              <1> 	;
 10547                              <1> 	; INPUT ->
 10548                              <1> 	;	EAX = physical page address
 10549                              <1> 	;	      (use present value if EAX = 0)
 10550                              <1> 	;	EBX = virtual (linear) address
 10551                              <1> 	;	ECX = page attributes (lower 12 bits)
 10552                              <1> 	;	      (higher 20 bits must be ZERO)
 10553                              <1> 	;	      (bit 0 must be 1)	 
 10554                              <1> 	;	u.pgdir = page directory (physical) address
 10555                              <1> 	; OUTPUT ->
 10556                              <1> 	;	EAX = physical page address
 10557                              <1> 	;	(EDX = PTE value)
 10558                              <1> 	;	EBX = virtual address
 10559                              <1> 	;
 10560                              <1> 	;	CF = 1 -> error
 10561                              <1> 	;
 10562                              <1> 	; Modified Registers -> EAX, EDX
 10563                              <1> 	;
 10564 000030BC 50                  <1> 	push	eax
 10565 000030BD A1[AB740000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
 10566 000030C2 E837000000          <1> 	call 	get_pde
 10567                              <1> 		; EDX = PDE address
 10568                              <1> 		; EAX = PDE value
 10569 000030C7 5A                  <1> 	pop	edx ; physical page address
 10570 000030C8 722A                <1> 	jc	short spte_err ; PDE not present
 10571                              <1> 	;
 10572 000030CA 53                  <1> 	push	ebx ; 24/07/2015
 10573 000030CB 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10574                              <1> 			    ; EDX = PT address (physical)	
 10575 000030CF C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
 10576 000030D2 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
 10577                              <1> 			 ; clear higher 10 bits (PD bits)
 10578 000030D8 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
 10579 000030DB 01C3                <1> 	add	ebx, eax
 10580                              <1> 	;
 10581 000030DD 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
 10582 000030DF A801                <1> 	test	al, 1
 10583 000030E1 740C                <1> 	jz	short spte_0
 10584 000030E3 09D2                <1> 	or	edx, edx
 10585 000030E5 750F                <1> 	jnz	short spte_1
 10586 000030E7 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10587 000030EB 89C2                <1> 	mov	edx, eax
 10588 000030ED EB09                <1> 	jmp	short spte_2	
 10589                              <1> spte_0:
 10590                              <1> 	; If this PTE contains a swap (disk) address,
 10591                              <1> 	; it can be updated by using 'swap_in' procedure
 10592                              <1> 	; only!
 10593 000030EF 21C0                <1> 	and	eax, eax
 10594 000030F1 7403                <1> 	jz	short spte_1
 10595                              <1> 	; 24/07/2015
 10596                              <1> 	; swapped page ! (on disk)
 10597 000030F3 5B                  <1> 	pop	ebx
 10598                              <1> spte_err:
 10599 000030F4 F9                  <1> 	stc
 10600 000030F5 C3                  <1> 	retn
 10601                              <1> spte_1: 
 10602 000030F6 89D0                <1> 	mov	eax, edx
 10603                              <1> spte_2:
 10604 000030F8 09CA                <1> 	or	edx, ecx
 10605                              <1> 	; 23/06/2015
 10606 000030FA 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
 10607                              <1> 	; 24/07/2015
 10608 000030FC 5B                  <1> 	pop	ebx
 10609 000030FD C3                  <1> 	retn
 10610                              <1> 
 10611                              <1> get_pde:	; Get present value of the relevant PDE
 10612                              <1> 	; 20/07/2015
 10613                              <1> 	; 18/04/2015
 10614                              <1> 	; 12/04/2015
 10615                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10616                              <1> 	;
 10617                              <1> 	; INPUT ->
 10618                              <1> 	;	EBX = virtual (linear) address
 10619                              <1> 	;	EAX = page directory (physical) address
 10620                              <1> 	; OUTPUT ->
 10621                              <1> 	;	EDX = Page directory entry address
 10622                              <1> 	;	EAX = Page directory entry value
 10623                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 10624                              <1> 	; Modified Registers -> EDX, EAX
 10625                              <1> 	;
 10626 000030FE 89DA                <1> 	mov	edx, ebx
 10627 00003100 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
 10628 00003103 C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
 10629 00003106 01C2                <1> 	add	edx, eax ; page directory address (physical)
 10630 00003108 8B02                <1> 	mov	eax, [edx]
 10631 0000310A A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
 10632 0000310C 751F                <1> 	jnz	short gpte_retn
 10633 0000310E F9                  <1> 	stc
 10634                              <1> gpde_retn:	
 10635 0000310F C3                  <1> 	retn
 10636                              <1> 
 10637                              <1> get_pte:
 10638                              <1> 		; Get present value of the relevant PTE
 10639                              <1> 	; 29/07/2015
 10640                              <1> 	; 20/07/2015
 10641                              <1> 	; 18/04/2015
 10642                              <1> 	; 12/04/2015
 10643                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10644                              <1> 	;
 10645                              <1> 	; INPUT ->
 10646                              <1> 	;	EBX = virtual (linear) address
 10647                              <1> 	;	EAX = page directory (physical) address
 10648                              <1> 	; OUTPUT ->
 10649                              <1> 	;	EDX = Page table entry address (if CF=0)
 10650                              <1> 	;	      Page directory entry address (if CF=1)
 10651                              <1> 	;            (Bit 0 value is 0 if PT is not present)
 10652                              <1> 	;	EAX = Page table entry value (page address)
 10653                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 10654                              <1> 	; Modified Registers -> EAX, EDX
 10655                              <1> 	;
 10656 00003110 E8E9FFFFFF          <1> 	call 	get_pde
 10657 00003115 72F8                <1> 	jc	short gpde_retn	; page table is not present
 10658                              <1> 	;jnc	short gpte_1
 10659                              <1> 	;retn
 10660                              <1> ;gpte_1:
 10661 00003117 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10662 0000311B 89DA                <1> 	mov	edx, ebx
 10663 0000311D C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
 10664 00003120 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
 10665                              <1> 			 ; clear higher 10 bits (PD bits)
 10666 00003126 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
 10667 00003129 01C2                <1> 	add	edx, eax
 10668 0000312B 8B02                <1> 	mov	eax, [edx]
 10669                              <1> gpte_retn:
 10670 0000312D C3                  <1> 	retn
 10671                              <1> 
 10672                              <1> deallocate_page_dir:
 10673                              <1> 	; 15/09/2015
 10674                              <1> 	; 05/08/2015
 10675                              <1> 	; 30/04/2015
 10676                              <1> 	; 28/04/2015
 10677                              <1> 	; 17/10/2014
 10678                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10679                              <1> 	;
 10680                              <1> 	; INPUT ->
 10681                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
 10682                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 10683                              <1> 	; OUTPUT ->
 10684                              <1> 	;	All of page tables in the page directory
 10685                              <1> 	;	and page dir's itself will be deallocated
 10686                              <1> 	;	except 'read only' duplicated pages (will be converted
 10687                              <1> 	;	to writable pages).
 10688                              <1> 	;
 10689                              <1> 	; Modified Registers -> EAX
 10690                              <1> 	;
 10691                              <1> 	;
 10692 0000312E 56                  <1> 	push	esi
 10693 0000312F 51                  <1> 	push	ecx
 10694 00003130 50                  <1> 	push	eax
 10695 00003131 89C6                <1> 	mov	esi, eax 
 10696 00003133 31C9                <1> 	xor	ecx, ecx
 10697                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
 10698                              <1> 	; it must not be deallocated
 10699 00003135 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
 10700                              <1> dapd_0:
 10701 00003137 AD                  <1> 	lodsd
 10702 00003138 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
 10703 0000313A 7409                <1> 	jz	short dapd_1	
 10704 0000313C 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 10705 00003140 E812000000          <1> 	call	deallocate_page_table			
 10706                              <1> dapd_1:
 10707 00003145 41                  <1> 	inc	ecx ; page directory entry index
 10708 00003146 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
 10709 0000314C 72E9                <1> 	jb	short dapd_0
 10710                              <1> dapd_2:
 10711 0000314E 58                  <1> 	pop	eax
 10712 0000314F E879000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
 10713 00003154 59                  <1> 	pop	ecx
 10714 00003155 5E                  <1> 	pop	esi
 10715 00003156 C3                  <1> 	retn
 10716                              <1> 
 10717                              <1> deallocate_page_table:
 10718                              <1> 	; 19/09/2015
 10719                              <1> 	; 15/09/2015
 10720                              <1> 	; 05/08/2015
 10721                              <1> 	; 30/04/2015
 10722                              <1> 	; 28/04/2015
 10723                              <1> 	; 24/10/2014
 10724                              <1> 	; 23/10/2014
 10725                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10726                              <1> 	;
 10727                              <1> 	; INPUT ->
 10728                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
 10729                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 10730                              <1> 	;	(ECX = page directory entry index)
 10731                              <1> 	; OUTPUT ->
 10732                              <1> 	;	All of pages in the page table and page table's itself
 10733                              <1> 	;	will be deallocated except 'read only' duplicated pages
 10734                              <1> 	;	(will be converted to writable pages).
 10735                              <1> 	;
 10736                              <1> 	; Modified Registers -> EAX
 10737                              <1> 	;
 10738 00003157 56                  <1> 	push	esi
 10739 00003158 57                  <1> 	push	edi
 10740 00003159 52                  <1> 	push	edx
 10741 0000315A 50                  <1> 	push	eax ; *
 10742 0000315B 89C6                <1> 	mov	esi, eax 
 10743 0000315D 31FF                <1> 	xor	edi, edi ; 0
 10744                              <1> dapt_0:
 10745 0000315F AD                  <1> 	lodsd
 10746 00003160 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
 10747 00003162 7441                <1> 	jz	short dapt_1
 10748                              <1> 	;
 10749 00003164 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
 10750                              <1> 				  ; (must be 1)
 10751 00003166 754C                <1> 	jnz	short dapt_3
 10752                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
 10753 00003168 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
 10754                              <1> 				   ; as child's page ?
 10755 0000316C 744B                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
 10756                              <1> 	; check the parent's PTE value is read only & same page or not.. 
 10757                              <1> 	; ECX = page directory entry index (0-1023)
 10758 0000316E 53                  <1> 	push	ebx
 10759 0000316F 51                  <1> 	push	ecx
 10760 00003170 66C1E102            <1> 	shl	cx, 2 ; *4 
 10761 00003174 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
 10762 00003176 8B0B                <1> 	mov	ecx, [ebx]
 10763 00003178 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
 10764 0000317B 7435                <1> 	jz	short dapt_2	; parent process does not use this page
 10765 0000317D 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 10766                              <1> 	; EDI = page table entry index (0-1023)
 10767 00003182 89FA                <1> 	mov	edx, edi 
 10768 00003184 66C1E202            <1> 	shl	dx, 2 ; *4 
 10769 00003188 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
 10770 0000318A 8B1A                <1> 	mov	ebx, [edx]
 10771 0000318C F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
 10772 0000318F 7421                <1> 	jz	short dapt_2	; parent process does not use this page
 10773 00003191 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
 10774 00003195 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
 10775 0000319A 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
 10776 0000319C 7514                <1> 	jne	short dapt_2	; not same page
 10777                              <1> 				; deallocate the child's page
 10778 0000319E 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
 10779 000031A1 59                  <1> 	pop	ecx
 10780 000031A2 5B                  <1> 	pop	ebx
 10781 000031A3 EB14                <1> 	jmp	short dapt_4
 10782                              <1> dapt_1:
 10783 000031A5 09C0                <1> 	or	eax, eax	; swapped page ?
 10784 000031A7 7417                <1> 	jz	short dapt_5	; no
 10785                              <1> 				; yes
 10786 000031A9 D1E8                <1> 	shr	eax, 1
 10787 000031AB E848040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
 10788                              <1> 				  ; on the swap disk (or in file)
 10789 000031B0 EB0E                <1> 	jmp	short dapt_5
 10790                              <1> dapt_2:
 10791 000031B2 59                  <1> 	pop	ecx
 10792 000031B3 5B                  <1> 	pop	ebx
 10793                              <1> dapt_3:	
 10794                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 10795 000031B4 E814000000          <1> 	call	deallocate_page
 10796                              <1> dapt_4:
 10797 000031B9 C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
 10798                              <1> dapt_5:
 10799 000031C0 47                  <1> 	inc	edi ; page table entry index
 10800 000031C1 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
 10801 000031C7 7296                <1> 	jb	short dapt_0
 10802                              <1> 	;
 10803 000031C9 58                  <1> 	pop	eax ; *
 10804 000031CA 5A                  <1> 	pop	edx
 10805 000031CB 5F                  <1> 	pop	edi	
 10806 000031CC 5E                  <1> 	pop	esi
 10807                              <1> 	;
 10808                              <1> 	;call	deallocate_page	; deallocate the page table's itself
 10809                              <1> 	;retn
 10810                              <1> 
 10811                              <1> deallocate_page:
 10812                              <1> 	; 15/09/2015
 10813                              <1> 	; 28/04/2015
 10814                              <1> 	; 10/03/2015
 10815                              <1> 	; 17/10/2014
 10816                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10817                              <1> 	;
 10818                              <1> 	; INPUT -> 
 10819                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10820                              <1> 	; OUTPUT ->
 10821                              <1> 	;	[free_pages] is increased
 10822                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
 10823                              <1> 	;	CF = 1 if the page is already deallocated
 10824                              <1> 	; 	       (or not allocated) before.  
 10825                              <1> 	;
 10826                              <1> 	; Modified Registers -> EAX
 10827                              <1> 	;
 10828 000031CD 53                  <1> 	push	ebx
 10829 000031CE 52                  <1> 	push	edx
 10830                              <1> 	;
 10831 000031CF C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
 10832                              <1> 				     ; 12 bits right
 10833                              <1> 				     ; to get page number
 10834 000031D2 89C2                <1> 	mov	edx, eax
 10835                              <1> 	; 15/09/2015
 10836 000031D4 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
 10837                              <1> 				     ; (1 allocation bit = 1 page)
 10838                              <1> 				     ; (1 allocation bytes = 8 pages)
 10839 000031D7 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 10840                              <1> 				     ; (to get 32 bit position)			
 10841                              <1> 	;
 10842 000031DA BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
 10843 000031DF 01D3                <1> 	add	ebx, edx
 10844 000031E1 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 10845                              <1> 				     ; (allocation bit position)	 
 10846 000031E4 3B15[84700000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
 10847                              <1> 				     ; than the address in 'next_page' ?
 10848                              <1> 				     ; (next/first free page value)		
 10849 000031EA 7306                <1> 	jnb	short dap_1	     ; no	
 10850 000031EC 8915[84700000]      <1> 	mov	[next_page], edx     ; yes
 10851                              <1> dap_1:
 10852 000031F2 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
 10853                              <1> 				     ; set relevant bit to 1.
 10854                              <1> 				     ; set CF to the previous bit value	
 10855                              <1> 	;cmc			     ; complement carry flag	
 10856                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
 10857                              <1> 				     ; if the page is already deallocated
 10858                              <1> 				     ; before.	
 10859 000031F5 FF05[80700000]      <1>         inc     dword [free_pages]
 10860                              <1> dap_2:
 10861 000031FB 5A                  <1> 	pop	edx
 10862 000031FC 5B                  <1> 	pop	ebx
 10863 000031FD C3                  <1> 	retn
 10864                              <1> 
 10865                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 10866                              <1> ;;                                                              ;;
 10867                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
 10868                              <1> ;; Distributed under terms of the GNU General Public License    ;;
 10869                              <1> ;;                                                              ;;
 10870                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 10871                              <1> 
 10872                              <1> ;;$Revision: 5057 $
 10873                              <1> 
 10874                              <1> 
 10875                              <1> ;;align 4
 10876                              <1> ;;proc alloc_page
 10877                              <1> 
 10878                              <1> ;;        pushfd
 10879                              <1> ;;        cli
 10880                              <1> ;;        push    ebx
 10881                              <1> ;;;//-
 10882                              <1> ;;        cmp     [pg_data.pages_free], 1
 10883                              <1> ;;        jle     .out_of_memory
 10884                              <1> ;;;//-
 10885                              <1> ;;
 10886                              <1> ;;        mov     ebx, [page_start]
 10887                              <1> ;;        mov     ecx, [page_end]
 10888                              <1> ;;.l1:
 10889                              <1> ;;        bsf     eax, [ebx];
 10890                              <1> ;;        jnz     .found
 10891                              <1> ;;        add     ebx, 4
 10892                              <1> ;;        cmp     ebx, ecx
 10893                              <1> ;;        jb      .l1
 10894                              <1> ;;        pop     ebx
 10895                              <1> ;;        popfd
 10896                              <1> ;;        xor     eax, eax
 10897                              <1> ;;        ret
 10898                              <1> ;;.found:
 10899                              <1> ;;;//-
 10900                              <1> ;;        dec     [pg_data.pages_free]
 10901                              <1> ;;        jz      .out_of_memory
 10902                              <1> ;;;//-
 10903                              <1> ;;        btr     [ebx], eax
 10904                              <1> ;;        mov     [page_start], ebx
 10905                              <1> ;;        sub     ebx, sys_pgmap
 10906                              <1> ;;        lea     eax, [eax+ebx*8]
 10907                              <1> ;;        shl     eax, 12
 10908                              <1> ;;;//-       dec [pg_data.pages_free]
 10909                              <1> ;;        pop     ebx
 10910                              <1> ;;        popfd
 10911                              <1> ;;        ret
 10912                              <1> ;;;//-
 10913                              <1> ;;.out_of_memory:
 10914                              <1> ;;        mov     [pg_data.pages_free], 1
 10915                              <1> ;;        xor     eax, eax
 10916                              <1> ;;        pop     ebx
 10917                              <1> ;;        popfd
 10918                              <1> ;;        ret
 10919                              <1> ;;;//-
 10920                              <1> ;;endp
 10921                              <1> 
 10922                              <1> duplicate_page_dir:
 10923                              <1> 	; 21/09/2015
 10924                              <1> 	; 31/08/2015
 10925                              <1> 	; 20/07/2015
 10926                              <1> 	; 28/04/2015
 10927                              <1> 	; 27/04/2015
 10928                              <1> 	; 18/04/2015
 10929                              <1> 	; 12/04/2015
 10930                              <1> 	; 18/10/2014
 10931                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 10932                              <1> 	;
 10933                              <1> 	; INPUT -> 
 10934                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 10935                              <1> 	;		    page directory.
 10936                              <1> 	; OUTPUT ->
 10937                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 10938                              <1> 	;	       page directory.
 10939                              <1> 	;	(New page directory with new page table entries.)
 10940                              <1> 	;	(New page tables with read only copies of the parent's
 10941                              <1> 	;	pages.)
 10942                              <1> 	;	EAX = 0 -> Error (CF = 1)
 10943                              <1> 	;
 10944                              <1> 	; Modified Registers -> none (except EAX)
 10945                              <1> 	;
 10946 000031FE E8F2FDFFFF          <1> 	call	allocate_page
 10947 00003203 723E                <1> 	jc	short dpd_err
 10948                              <1> 	;
 10949 00003205 55                  <1> 	push	ebp ; 20/07/2015
 10950 00003206 56                  <1> 	push	esi
 10951 00003207 57                  <1> 	push	edi
 10952 00003208 53                  <1> 	push	ebx
 10953 00003209 51                  <1> 	push	ecx
 10954 0000320A 8B35[AB740000]      <1> 	mov	esi, [u.pgdir]
 10955 00003210 89C7                <1> 	mov	edi, eax
 10956 00003212 50                  <1> 	push	eax ; save child's page directory address
 10957                              <1> 	; 31/08/2015
 10958                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 10959                              <1> 	; (use same system space for all user page tables) 
 10960 00003213 A5                  <1> 	movsd
 10961 00003214 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 10962 00003219 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 10963                              <1> dpd_0:	
 10964 0000321E AD                  <1> 	lodsd
 10965                              <1> 	;or	eax, eax
 10966                              <1>         ;jnz     short dpd_1
 10967 0000321F A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 10968 00003221 7508                <1> 	jnz	short dpd_1
 10969                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
 10970 00003223 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 10971 00003229 EB0F                <1> 	jmp	short dpd_2
 10972                              <1> dpd_1:	
 10973 0000322B 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 10974 0000322F 89C3                <1> 	mov	ebx, eax
 10975                              <1> 	; EBX = Parent's page table address
 10976 00003231 E81F000000          <1> 	call	duplicate_page_table
 10977 00003236 720C                <1> 	jc	short dpd_p_err
 10978                              <1> 	; EAX = Child's page table address
 10979 00003238 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 10980                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 10981                              <1> 			 ; (present, writable, user)
 10982                              <1> dpd_2:
 10983 0000323A AB                  <1> 	stosd
 10984 0000323B E2E1                <1> 	loop	dpd_0
 10985                              <1> 	;
 10986 0000323D 58                  <1> 	pop	eax  ; restore child's page directory address
 10987                              <1> dpd_3:
 10988 0000323E 59                  <1> 	pop	ecx
 10989 0000323F 5B                  <1> 	pop	ebx
 10990 00003240 5F                  <1> 	pop	edi
 10991 00003241 5E                  <1> 	pop	esi
 10992 00003242 5D                  <1> 	pop	ebp ; 20/07/2015
 10993                              <1> dpd_err:
 10994 00003243 C3                  <1> 	retn
 10995                              <1> dpd_p_err:
 10996                              <1> 	; release the allocated pages missing (recover free space)
 10997 00003244 58                  <1> 	pop	eax  ; the new page directory address (physical)
 10998 00003245 8B1D[AB740000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 10999 0000324B E8DEFEFFFF          <1> 	call 	deallocate_page_dir
 11000 00003250 29C0                <1> 	sub	eax, eax ; 0
 11001 00003252 F9                  <1> 	stc
 11002 00003253 EBE9                <1> 	jmp	short dpd_3	
 11003                              <1> 
 11004                              <1> duplicate_page_table:
 11005                              <1> 	; 21/09/2015
 11006                              <1> 	; 20/07/2015
 11007                              <1> 	; 05/05/2015
 11008                              <1> 	; 28/04/2015
 11009                              <1> 	; 27/04/2015
 11010                              <1> 	; 18/04/2015
 11011                              <1> 	; 18/10/2014
 11012                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 11013                              <1> 	;
 11014                              <1> 	; INPUT -> 
 11015                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 11016                              <1> 	;	EBP = page table entry index (from 'duplicate_page_dir')
 11017                              <1> 	; OUTPUT ->
 11018                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 11019                              <1> 	;	      (with 'read only' attribute of page table entries)
 11020                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 11021                              <1> 	;	CF = 1 -> error 
 11022                              <1> 	;
 11023                              <1> 	; Modified Registers -> EBP (except EAX)
 11024                              <1> 	;
 11025 00003255 E89BFDFFFF          <1> 	call	allocate_page
 11026 0000325A 726A                <1> 	jc	short dpt_err
 11027                              <1> 	;
 11028 0000325C 50                  <1> 	push	eax ; *
 11029 0000325D 56                  <1> 	push	esi
 11030 0000325E 57                  <1> 	push	edi
 11031 0000325F 52                  <1> 	push	edx
 11032 00003260 51                  <1> 	push	ecx
 11033                              <1> 	;
 11034 00003261 89DE                <1> 	mov	esi, ebx
 11035 00003263 89C7                <1> 	mov	edi, eax
 11036 00003265 89C2                <1> 	mov	edx, eax
 11037 00003267 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 11038                              <1> dpt_0:
 11039 0000326D AD                  <1> 	lodsd
 11040 0000326E 21C0                <1> 	and	eax, eax
 11041 00003270 7444                <1> 	jz	short dpt_3
 11042 00003272 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 11043 00003274 7507                <1> 	jnz	short dpt_1
 11044                              <1> 	; 20/07/2015
 11045                              <1> 	; ebp = virtual (linear) address of the memory page
 11046 00003276 E887040000          <1> 	call	reload_page ; 28/04/2015
 11047 0000327B 7244                <1> 	jc	short dpt_p_err
 11048                              <1> dpt_1:
 11049                              <1> 	; 21/09/2015
 11050 0000327D 89C1                <1> 	mov	ecx, eax
 11051 0000327F 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11052 00003283 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
 11053 00003286 7525                <1> 	jnz	short dpt_2
 11054                              <1> 	; Read only (parent) page
 11055                              <1> 	; 	- there is a third process which uses this page -
 11056                              <1> 	; Allocate a new page for the child process
 11057 00003288 E868FDFFFF          <1> 	call	allocate_page
 11058 0000328D 7232                <1> 	jc	short dpt_p_err
 11059 0000328F 57                  <1> 	push	edi
 11060 00003290 56                  <1> 	push	esi
 11061 00003291 89CE                <1> 	mov	esi, ecx
 11062 00003293 89C7                <1> 	mov	edi, eax
 11063 00003295 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 11064 0000329A F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 11065 0000329C 5E                  <1> 	pop	esi
 11066 0000329D 5F                  <1> 	pop	edi
 11067                              <1> 	; 
 11068 0000329E 53                  <1> 	push	ebx
 11069 0000329F 50                  <1> 	push	eax
 11070                              <1> 	; 20/07/2015
 11071 000032A0 89EB                <1> 	mov	ebx, ebp
 11072                              <1> 	; ebx = virtual address of the memory page
 11073 000032A2 E80B030000          <1> 	call	add_to_swap_queue
 11074 000032A7 58                  <1> 	pop	eax
 11075 000032A8 5B                  <1> 	pop	ebx
 11076                              <1> 	; 21/09/2015
 11077 000032A9 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 11078                              <1> 		; user + writable + present page
 11079 000032AB EB09                <1> 	jmp	short dpt_3
 11080                              <1> dpt_2:
 11081                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 11082 000032AD 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
 11083                              <1> 		    ; (read only page!)
 11084 000032AF 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
 11085 000032B2 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
 11086                              <1> dpt_3:
 11087 000032B6 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 11088                              <1> 	;
 11089 000032B7 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 11090                              <1> 	;
 11091 000032BD 39D7                <1> 	cmp	edi, edx
 11092 000032BF 72AC                <1> 	jb	short dpt_0
 11093                              <1> dpt_p_err:
 11094 000032C1 59                  <1> 	pop	ecx
 11095 000032C2 5A                  <1> 	pop	edx
 11096 000032C3 5F                  <1> 	pop	edi
 11097 000032C4 5E                  <1> 	pop	esi
 11098 000032C5 58                  <1> 	pop	eax ; *
 11099                              <1> dpt_err:
 11100 000032C6 C3                  <1> 	retn
 11101                              <1> 
 11102                              <1> page_fault_handler:	; CPU EXCEPTION 0Eh (14) : Page Fault !
 11103                              <1> 	; 21/09/2015
 11104                              <1> 	; 19/09/2015
 11105                              <1> 	; 17/09/2015
 11106                              <1> 	; 28/08/2015
 11107                              <1> 	; 20/07/2015
 11108                              <1> 	; 28/06/2015
 11109                              <1> 	; 03/05/2015
 11110                              <1> 	; 30/04/2015
 11111                              <1> 	; 18/04/2015
 11112                              <1> 	; 12/04/2015
 11113                              <1> 	; 30/10/2014
 11114                              <1> 	; 11/09/2014
 11115                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
 11116                              <1> 	;
 11117                              <1> 	; Note: This is not an interrupt/exception handler.
 11118                              <1> 	;	This is a 'page fault remedy' subroutine 
 11119                              <1> 	;	which will be called by standard/uniform
 11120                              <1> 	;	exception handler.
 11121                              <1> 	;
 11122                              <1> 	; INPUT -> 
 11123                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
 11124                              <1> 	;
 11125                              <1> 	;	cr2 = the virtual (linear) address 
 11126                              <1> 	;	      which has caused to page fault (19/09/2015)
 11127                              <1> 	;
 11128                              <1> 	; OUTPUT ->
 11129                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11130                              <1> 	;	EAX = 0 -> no error
 11131                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
 11132                              <1> 	;
 11133                              <1> 	; Modified Registers -> none (except EAX)
 11134                              <1> 	;	
 11135                              <1>         ;
 11136                              <1>         ; ERROR CODE:
 11137                              <1> 	;	 31  .....	4   3	2   1	0
 11138                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11139                              <1> 	;	|   Reserved  | I | R | U | W | P |
 11140                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11141                              <1> 	;
 11142                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
 11143                              <1>     	;		a page-protection violation. When not set,
 11144                              <1> 	;		it was caused by a non-present page.
 11145                              <1> 	; W : WRITE   -	When set, the page fault was caused by
 11146                              <1> 	;		a page write. When not set, it was caused
 11147                              <1> 	;		by a page read.
 11148                              <1> 	; U : USER    -	When set, the page fault was caused 
 11149                              <1> 	;		while CPL = 3. 
 11150                              <1> 	;		This does not necessarily mean that
 11151                              <1> 	;		the page fault was a privilege violation.
 11152                              <1> 	; R : RESERVD -	When set, the page fault was caused by
 11153                              <1> 	;     WRITE	reading a 1 in a reserved field.
 11154                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
 11155                              <1> 	;     FETCH	an instruction fetch
 11156                              <1> 	;
 11157                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
 11158                              <1> 	;  31               22                  12 11                    0
 11159                              <1> 	; +-------------------+-------------------+-----------------------+
 11160                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
 11161                              <1>        	; +-------------------+-------------------+-----------------------+
 11162                              <1> 	;
 11163                              <1> 
 11164                              <1> 	;; CR3 REGISTER (Control Register 3)
 11165                              <1> 	;  31                                   12             5 4 3 2   0
 11166                              <1> 	; +---------------------------------------+-------------+---+-----+
 11167                              <1>       	; |                                       |  		|P|P|     |
 11168                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
 11169                              <1>       	; |                                       | 		|D|T|     |
 11170                              <1>    	; +---------------------------------------+-------------+---+-----+
 11171                              <1> 	;
 11172                              <1> 	;	PWT    - WRITE THROUGH
 11173                              <1> 	;	PCD    - CACHE DISABLE		
 11174                              <1> 	;
 11175                              <1> 	;
 11176                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
 11177                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11178                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11179                              <1>       	; |                                       |     | | | | |P|P|U|R| |
 11180                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
 11181                              <1>       	; |                                       |     | | | | |D|T|S|W| |
 11182                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11183                              <1> 	;
 11184                              <1>         ;       P      - PRESENT
 11185                              <1>         ;       R/W    - READ/WRITE
 11186                              <1>         ;       U/S    - USER/SUPERVISOR
 11187                              <1> 	;	PWT    - WRITE THROUGH
 11188                              <1> 	;	PCD    - CACHE DISABLE	
 11189                              <1> 	;	A      - ACCESSED	
 11190                              <1>         ;       D      - DIRTY (IGNORED)
 11191                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11192                              <1> 	;	G      - GLOBAL	(IGNORED) 
 11193                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11194                              <1> 	;
 11195                              <1> 	;
 11196                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
 11197                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11198                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11199                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
 11200                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
 11201                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
 11202                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11203                              <1> 	;
 11204                              <1>         ;       P      - PRESENT
 11205                              <1>         ;       R/W    - READ/WRITE
 11206                              <1>         ;       U/S    - USER/SUPERVISOR
 11207                              <1> 	;	PWT    - WRITE THROUGH
 11208                              <1> 	;	PCD    - CACHE DISABLE	
 11209                              <1> 	;	A      - ACCESSED	
 11210                              <1>         ;       D      - DIRTY
 11211                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11212                              <1> 	;	G      - GLOBAL	 
 11213                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11214                              <1> 	;
 11215                              <1> 	;
 11216                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
 11217                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11218                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11219                              <1>       	; |                                       |     | | | | | | |U|R| |
 11220                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
 11221                              <1>       	; |                                       |     | | | | | | |S|W| |
 11222                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11223                              <1> 	;
 11224                              <1>         ;       P      - PRESENT
 11225                              <1>         ;       R/W    - READ/WRITE
 11226                              <1>         ;       U/S    - USER/SUPERVISOR
 11227                              <1>         ;       D      - DIRTY
 11228                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11229                              <1> 	;
 11230                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
 11231                              <1> 	;
 11232                              <1> 	;
 11233                              <1> 	;; Invalid Page Table Entry
 11234                              <1> 	; 31                                                           1 0
 11235                              <1>       	; +-------------------------------------------------------------+-+
 11236                              <1>       	; |                                                             | |
 11237                              <1>       	; |                          AVAILABLE                          |0|
 11238                              <1>       	; |                                                             | |
 11239                              <1>       	; +-------------------------------------------------------------+-+
 11240                              <1> 	;
 11241                              <1> 
 11242 000032C7 53                  <1> 	push	ebx
 11243 000032C8 52                  <1> 	push	edx
 11244 000032C9 51                  <1> 	push	ecx
 11245                              <1> 	;
 11246                              <1> 	; 21/09/2015 (debugging)
 11247 000032CA FF05[BB740000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
 11248 000032D0 FF05[38850000]      <1> 	inc	dword [PF_Count] ; total page fault count	
 11249                              <1> 	; 28/06/2015
 11250                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
 11251 000032D6 8A15[30850000]      <1> 	mov	dl, [error_code]
 11252                              <1> 	;
 11253 000032DC F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
 11254                              <1> 			; sign
 11255 000032DF 7422                <1> 	jz	short pfh_alloc_np
 11256                              <1> 	; 
 11257                              <1> 	; If it is not a 'write on read only page' type page fault
 11258                              <1> 	; major page fault error with minor reason must be returned without 
 11259                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
 11260                              <1> 	; after return here!
 11261                              <1> 	; Page fault will be remedied, by copying page contents
 11262                              <1> 	; to newly allocated page with write permission;
 11263                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
 11264                              <1> 	; used for working with minimum possible memory usage. 
 11265                              <1> 	; sys_fork will duplicate page directory and tables of parent  
 11266                              <1> 	; process with 'read only' flag. If the child process attempts to
 11267                              <1> 	; write on these read only pages, page fault will be directed here
 11268                              <1> 	; for allocating a new page with same data/content. 
 11269                              <1> 	;
 11270                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
 11271                              <1> 	; will not force to separate CODE and DATA space 
 11272                              <1> 	; in a process/program... 
 11273                              <1> 	; CODE segment/section may contain DATA!
 11274                              <1> 	; It is flat, smoth and simplest programming method already as in 
 11275                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
 11276                              <1> 	;	
 11277 000032E1 F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
 11278                              <1> 			; sign
 11279 000032E4 0F84AB000000        <1>         jz      pfh_p_err
 11280                              <1> 	; 31/08/2015
 11281 000032EA F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
 11282                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
 11283 000032ED 0F84A2000000        <1>         jz	pfh_pv_err
 11284                              <1> 	;
 11285                              <1> 	; make a new page and copy the parent's page content
 11286                              <1> 	; as the child's new page content
 11287                              <1> 	;
 11288 000032F3 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
 11289                              <1> 			 ; which has caused to page fault
 11290 000032F6 E8A2000000          <1> 	call 	copy_page
 11291 000032FB 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
 11292                              <1> 	;
 11293 00003301 EB7D                <1>         jmp     pfh_cpp_ok
 11294                              <1> 	;
 11295                              <1> pfh_alloc_np:
 11296 00003303 E8EDFCFFFF          <1> 	call	allocate_page	; (allocate a new page)
 11297 00003308 0F8280000000        <1>         jc      pfh_im_err	; 'insufficient memory' error
 11298                              <1> pfh_chk_cpl:
 11299                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11300                              <1> 		; (Lower 12 bits are ZERO, because 
 11301                              <1> 		;	the address is on a page boundary)
 11302 0000330E 80E204              <1> 	and	dl, 4	; CPL = 3 ?
 11303 00003311 7505                <1> 	jnz	short pfh_um
 11304                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
 11305 00003313 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
 11306                              <1> 			 ; of the current/active page directory
 11307                              <1> 			 ; (Always kernel/system mode page directory, here!)
 11308                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
 11309 00003316 EB06                <1> 	jmp	short pfh_get_pde
 11310                              <1> 	;
 11311                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
 11312 00003318 8B1D[AB740000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
 11313                              <1> 			; Physical address of the USER's page directory
 11314                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
 11315                              <1> pfh_get_pde:
 11316 0000331E 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
 11317 00003321 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
 11318                              <1> 			 ; which has been caused to page fault
 11319                              <1> 			 ;
 11320 00003324 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
 11321 00003327 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
 11322                              <1> 	;
 11323 0000332A 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
 11324 0000332C 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
 11325 0000332E F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
 11326 00003331 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
 11327                              <1> 			  	  ; set/validate page directory entry
 11328 00003333 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 11329 00003338 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
 11330 0000333A 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
 11331 0000333C EB16                <1> 	jmp	short pfh_get_pte
 11332                              <1> pfh_set_pde:
 11333                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
 11334                              <1> 	;;	 (So, we know this PDE is empty or invalid)
 11335                              <1> 	;
 11336 0000333E 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
 11337 00003340 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
 11338 00003342 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
 11339 00003344 89C3                <1> 	mov	ebx, eax
 11340 00003346 E8AAFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
 11341 0000334B 7241                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
 11342                              <1> pfh_spde_1:
 11343                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11344 0000334D 89C1                <1> 	mov	ecx, eax
 11345 0000334F E81BFDFFFF          <1> 	call	clear_page ; Clear page content
 11346                              <1> pfh_get_pte:
 11347 00003354 0F20D0              <1> 	mov	eax, cr2 ; virtual address
 11348                              <1> 			 ; which has been caused to page fault
 11349 00003357 89C7                <1> 	mov	edi, eax ; 20/07/2015
 11350 00003359 C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
 11351                              <1> 			 ; higher 20 bits of the page fault address 
 11352 0000335C 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
 11353 00003361 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
 11354 00003364 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
 11355 00003366 8B03                <1> 	mov	eax, [ebx] ; get previous value of pte
 11356                              <1> 		; bit 0 of EAX is always 0 (otherwise we would not be here)
 11357 00003368 21C0                <1> 	and	eax, eax
 11358 0000336A 7410                <1> 	jz	short pfh_gpte_1
 11359                              <1> 	; 20/07/2015
 11360 0000336C 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
 11361 0000336E 55                  <1> 	push	ebp ; 20/07/2015
 11362 0000336F 0F20D5              <1> 	mov	ebp, cr2
 11363                              <1> 		; ECX = physical address of the page table entry
 11364                              <1> 		; EBX = Memory page address (physical!)
 11365                              <1> 		; EAX = Swap disk (offset) address
 11366                              <1> 		; EBP = virtual address (page fault address)
 11367 00003372 E8B7000000          <1> 	call	swap_in
 11368 00003377 5D                  <1> 	pop	ebp
 11369 00003378 7210                <1> 	jc      short pfh_err_retn
 11370 0000337A 87CB                <1> 	xchg	ecx, ebx
 11371                              <1> 		; EBX = physical address of the page table entry
 11372                              <1> 		; ECX = new page
 11373                              <1> pfh_gpte_1:
 11374 0000337C 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
 11375 0000337E 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
 11376                              <1> pfh_cpp_ok:
 11377                              <1> 	; 20/07/2015
 11378 00003380 0F20D3              <1> 	mov	ebx, cr2
 11379 00003383 E82A020000          <1> 	call 	add_to_swap_queue
 11380                              <1> 	;
 11381                              <1> 	; The new PTE (which contains the new page) will be added to 
 11382                              <1> 	; the swap queue, here. 
 11383                              <1> 	; (Later, if memory will become insufficient, 
 11384                              <1> 	; one page will be swapped out which is at the head of 
 11385                              <1> 	; the swap queue by using FIFO and access check methods.)
 11386                              <1> 	;
 11387 00003388 31C0                <1> 	xor	eax, eax  ; 0
 11388                              <1> 	;
 11389                              <1> pfh_err_retn:
 11390 0000338A 59                  <1> 	pop	ecx
 11391 0000338B 5A                  <1> 	pop	edx
 11392 0000338C 5B                  <1> 	pop	ebx
 11393 0000338D C3                  <1> 	retn 
 11394                              <1> 	
 11395                              <1> pfh_im_err:
 11396 0000338E B8E1000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
 11397                              <1> 			; Major (Primary) Error: Page Fault
 11398                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
 11399 00003393 EBF5                <1> 	jmp	short pfh_err_retn
 11400                              <1> 
 11401                              <1> 
 11402                              <1> pfh_p_err: ; 09/03/2015
 11403                              <1> pfh_pv_err:
 11404                              <1> 	; Page fault was caused by a protection-violation
 11405 00003395 B8E3000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
 11406                              <1> 			; Major (Primary) Error: Page Fault
 11407                              <1> 			; Minor (Secondary) Error: Protection violation !
 11408 0000339A F9                  <1> 	stc
 11409 0000339B EBED                <1> 	jmp	short pfh_err_retn
 11410                              <1> 
 11411                              <1> copy_page:
 11412                              <1> 	; 22/09/2015
 11413                              <1> 	; 21/09/2015
 11414                              <1> 	; 19/09/2015
 11415                              <1> 	; 07/09/2015
 11416                              <1> 	; 31/08/2015
 11417                              <1> 	; 20/07/2015
 11418                              <1> 	; 05/05/2015
 11419                              <1> 	; 03/05/2015
 11420                              <1> 	; 18/04/2015
 11421                              <1> 	; 12/04/2015
 11422                              <1> 	; 30/10/2014
 11423                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
 11424                              <1> 	;
 11425                              <1> 	; INPUT -> 
 11426                              <1> 	;	EBX = Virtual (linear) address of source page
 11427                              <1> 	;	     (Page fault address)
 11428                              <1> 	; OUTPUT ->
 11429                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11430                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11431                              <1> 	;	EAX = 0 (CF = 1) 
 11432                              <1> 	;		if there is not a free page to be allocated
 11433                              <1> 	;	(page content of the source page will be copied
 11434                              <1> 	;	onto the target/new page) 	
 11435                              <1> 	;
 11436                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
 11437                              <1> 	;	
 11438 0000339D 56                  <1> 	push	esi
 11439 0000339E 57                  <1> 	push	edi
 11440                              <1> 	;push	ebx
 11441                              <1> 	;push	ecx
 11442 0000339F 31F6                <1> 	xor 	esi, esi
 11443 000033A1 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
 11444 000033A4 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
 11445 000033A6 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
 11446 000033A9 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
 11447 000033AC 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
 11448 000033AE 031D[AB740000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
 11449 000033B4 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
 11450 000033B6 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
 11451 000033BA 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
 11452 000033BC 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11453 000033C2 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
 11454 000033C6 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
 11455                              <1> 	; 07/09/2015
 11456 000033C8 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
 11457                              <1> 				     ; read only page as a child process?)	
 11458 000033CD 7509                <1> 	jnz	short cpp_0 ; yes
 11459 000033CF 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
 11460 000033D1 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
 11461 000033D6 EB32                <1> 	jmp	short cpp_1
 11462                              <1> cpp_0:
 11463 000033D8 89FE                <1> 	mov	esi, edi
 11464 000033DA 0335[AF740000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
 11465 000033E0 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
 11466 000033E2 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11467 000033E6 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
 11468 000033E8 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11469 000033EE 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
 11470 000033F2 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
 11471 000033F4 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
 11472                              <1> 	; 21/09/2015
 11473 000033F6 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
 11474 000033F8 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
 11475                              <1> 	;
 11476 000033FC F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
 11477 000033FF 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
 11478                              <1> 	;
 11479 00003401 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
 11480 00003406 39C8                <1> 	cmp	eax, ecx   ; Same page?	
 11481 00003408 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
 11482                              <1> 			    ; Convert child's page to writable page
 11483                              <1> cpp_1:
 11484 0000340A E8E6FBFFFF          <1> 	call	allocate_page
 11485 0000340F 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
 11486 00003411 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
 11487 00003413 7405                <1> 	jz	short cpp_2
 11488                              <1> 		; Convert read only page to writable page 
 11489                              <1> 		;(for the parent of the current process)
 11490                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
 11491                              <1> 	; 22/09/2015
 11492 00003415 890E                <1> 	mov	[esi], ecx
 11493 00003417 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
 11494                              <1> 				 ; 1+2+4 = 7
 11495                              <1> cpp_2:
 11496 0000341A 89C7                <1> 	mov	edi, eax ; new page address of the child process
 11497                              <1> 	; 07/09/2015
 11498 0000341C 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
 11499 0000341E B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 11500 00003423 F3A5                <1> 	rep	movsd ; 31/08/2015
 11501                              <1> cpp_3:		
 11502 00003425 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
 11503 00003427 8903                <1> 	mov	[ebx], eax ; Update PTE
 11504 00003429 28C0                <1> 	sub	al, al ; clear attributes
 11505                              <1> cpp_4:
 11506                              <1> 	;pop	ecx
 11507                              <1> 	;pop	ebx
 11508 0000342B 5F                  <1> 	pop	edi
 11509 0000342C 5E                  <1> 	pop	esi
 11510 0000342D C3                  <1> 	retn
 11511                              <1> 
 11512                              <1> ;; 28/04/2015
 11513                              <1> ;; 24/10/2014
 11514                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
 11515                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
 11516                              <1> ;;
 11517                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
 11518                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
 11519                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
 11520                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
 11521                              <1> ;;
 11522                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
 11523                              <1> ;;
 11524                              <1> ;; Method:
 11525                              <1> ;;	Swap page queue is a list of allocated pages with physical
 11526                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
 11527                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
 11528                              <1> ;;	When a new page is being allocated, swap queue is updated
 11529                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
 11530                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
 11531                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
 11532                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
 11533                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
 11534                              <1> ;;	offset value becomes it's previous offset value - 4.
 11535                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
 11536                              <1> ;;	the queue/list is not shifted.
 11537                              <1> ;;	After the queue/list shift, newly allocated page is added
 11538                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
 11539                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
 11540                              <1> ;;	will not be added to the tail of swap page queue.  		 
 11541                              <1> ;;	
 11542                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
 11543                              <1> ;;	the first non-accessed, writable page in the list, 
 11544                              <1> ;;	from the head to the tail. The list is shifted to left 
 11545                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
 11546                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
 11547                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
 11548                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
 11549                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
 11550                              <1> ;;	procedure will be failed)...
 11551                              <1> ;;
 11552                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
 11553                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
 11554                              <1> ;;	(PTE) will be added to the tail of the queue after
 11555                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
 11556                              <1> ;;	the queue will be rotated and the PTE in the head will be
 11557                              <1> ;;	added to the tail after resetting 'accessed' bit. 
 11558                              <1> ;;
 11559                              <1> ;;
 11560                              <1> ;;	
 11561                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
 11562                              <1> ;;
 11563                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
 11564                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
 11565                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
 11566                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
 11567                              <1> ;;
 11568                              <1> ;; [swpd_next] = the first free block address in swapped page records
 11569                              <1> ;;    		 for next free block search by 'swap_out' procedure.
 11570                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
 11571                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
 11572                              <1> ;; 		 (entire swap space must be accessed by using
 11573                              <1> ;;		 31 bit offset address) 
 11574                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
 11575                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
 11576                              <1> ;;		  0 for file, or beginning sector of the swap partition
 11577                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
 11578                              <1> ;;
 11579                              <1> ;; 					
 11580                              <1> ;; Method:
 11581                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
 11582                              <1> ;;	procedure swaps out a page from memory to the swap disk 
 11583                              <1> ;;	(partition) or swap file to get a new free page at the memory.
 11584                              <1> ;;	Swapping out is performed by using swap page queue.
 11585                              <1> ;;
 11586                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
 11587                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
 11588                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
 11589                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
 11590                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
 11591                              <1> ;;	Absolute physical (logical) address of the swapped page is 
 11592                              <1> ;;	calculated by adding offset value to the swap partition's 
 11593                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
 11594                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
 11595                              <1> ;;	and offset value is equal to absolute (physical or logical)
 11596                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
 11597                              <1> ;;	is in a partitioned virtual hard disk.) 
 11598                              <1> ;;
 11599                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
 11600                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
 11601                              <1> ;;
 11602                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
 11603                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
 11604                              <1> ;;
 11605                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
 11606                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
 11607                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
 11608                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
 11609                              <1> ;;	it means relevant (respective) block is in use, and, 
 11610                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
 11611                              <1> ;;      swap disk/file block is free.
 11612                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
 11613                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
 11614                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
 11615                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
 11616                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
 11617                              <1> ;;	------------------------------------------------------------
 11618                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
 11619                              <1> ;;	------------------------------------------------------------
 11620                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
 11621                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
 11622                              <1> ;;
 11623                              <1> ;;	..............................................................
 11624                              <1> ;;
 11625                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
 11626                              <1> ;;	then it searches Swap Allocation Table if free count is not
 11627                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
 11628                              <1> ;;	position with value of 1 on the table is converted to swap
 11629                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
 11630                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
 11631                              <1> ;;	number of physical swap disk or virtual swap disk)
 11632                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
 11633                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
 11634                              <1> ;;	(memory page). That will be a direct disk write procedure.
 11635                              <1> ;;	(for preventing late memory allocation, significant waiting). 
 11636                              <1> ;;	If disk write procedure returns with error or free count of 
 11637                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
 11638                              <1> ;;	'insufficient memory error' (cf=1). 
 11639                              <1> ;;
 11640                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
 11641                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
 11642                              <1> ;;	in other words, 'swap_out' will not check the table for other
 11643                              <1> ;;	free blocks after a disk write error. It will return to 
 11644                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
 11645                              <1> ;;
 11646                              <1> ;;	After writing the page on to swap disk/file address/sector,
 11647                              <1> ;;	'swap_out' procesure returns with that swap (offset) sector
 11648                              <1> ;;	address (cf=0). 
 11649                              <1> ;;
 11650                              <1> ;;	..............................................................
 11651                              <1> ;;
 11652                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
 11653                              <1> ;;	file sectors at specified memory page. Then page allocation
 11654                              <1> ;;	procedure updates relevant page table entry with 'present' 
 11655                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
 11656                              <1> ;;	to do, except to terminate the process which is the owner of
 11657                              <1> ;;	the swapped page.
 11658                              <1> ;;
 11659                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
 11660                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
 11661                              <1> ;;	updates [swpd_first] pointer if it is required.
 11662                              <1> ;;
 11663                              <1> ;;	..............................................................	 
 11664                              <1> ;;
 11665                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
 11666                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
 11667                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
 11668                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
 11669                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
 11670                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
 11671                              <1> ;;
 11672                              <1> 
 11673                              <1> swap_in:
 11674                              <1> 	; 31/08/2015
 11675                              <1> 	; 20/07/2015
 11676                              <1> 	; 28/04/2015
 11677                              <1> 	; 18/04/2015
 11678                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 11679                              <1> 	;
 11680                              <1> 	; INPUT -> 
 11681                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
 11682                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
 11683                              <1> 	;	EAX = Offset Address for the swapped page on the
 11684                              <1> 	;	      swap disk or in the swap file.
 11685                              <1> 	;
 11686                              <1> 	; OUTPUT ->
 11687                              <1> 	;	EAX = 0 if loading at memory has been successful
 11688                              <1> 	;
 11689                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
 11690                              <1> 	;		  or sector not present or drive not ready
 11691                              <1> 	;	     EAX = Error code
 11692                              <1> 	;	     [u.error] = EAX 
 11693                              <1> 	;		       = The last error code for the process
 11694                              <1> 	;		         (will be reset after returning to user)	  
 11695                              <1> 	;
 11696                              <1> 	; Modified Registers -> EAX
 11697                              <1> 	;
 11698                              <1> 
 11699 0000342E 833D[1A850000]00    <1>         cmp     dword [swp_drv], 0
 11700 00003435 7648                <1> 	jna	short swpin_dnp_err
 11701                              <1> 
 11702 00003437 3B05[1E850000]      <1> 	cmp	eax, [swpd_size]
 11703 0000343D 734C                <1> 	jnb	short swpin_snp_err
 11704                              <1> 
 11705 0000343F 56                  <1> 	push	esi
 11706 00003440 53                  <1> 	push	ebx
 11707 00003441 51                  <1> 	push	ecx
 11708 00003442 8B35[1A850000]      <1> 	mov	esi, [swp_drv]	
 11709 00003448 B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 11710                              <1> 		; Note: Even if corresponding physical disk's sector 
 11711                              <1> 		; size different than 512 bytes, logical disk sector
 11712                              <1> 		; size is 512 bytes and disk reading procedure
 11713                              <1> 		; will be performed for reading 4096 bytes
 11714                              <1> 		; (2*2048, 8*512). 
 11715                              <1> 	; ESI = Logical disk description table address
 11716                              <1> 	; EBX = Memory page (buffer) address (physical!)
 11717                              <1> 	; EAX = Sector adress (offset address, logical sector number)
 11718                              <1> 	; ECX = Sector count ; 8 sectors
 11719 0000344D 50                  <1> 	push	eax
 11720 0000344E E833020000          <1> 	call	logical_disk_read
 11721 00003453 58                  <1> 	pop	eax
 11722 00003454 730C                <1> 	jnc	short swpin_read_ok
 11723                              <1> 	;
 11724 00003456 B804000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
 11725 0000345B A3[A7740000]        <1> 	mov	[u.error], eax
 11726 00003460 EB19                <1> 	jmp	short swpin_retn
 11727                              <1> 	;
 11728                              <1> swpin_read_ok:
 11729                              <1> 	; EAX = Offset address (logical sector number)
 11730 00003462 E891010000          <1> 	call	unlink_swap_block  ; Deallocate swap block	
 11731                              <1> 	;
 11732                              <1> 	; EBX = Memory page (buffer) address (physical!)
 11733                              <1> 	; 20/07/2015
 11734 00003467 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
 11735 00003469 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 11736 0000346E 8A1D[A1740000]      <1> 	mov	bl, [u.uno] ; current process number
 11737                              <1> 	; EBX = Virtual address & process number combination
 11738 00003474 E89E000000          <1> 	call	swap_queue_shift
 11739 00003479 29C0                <1> 	sub	eax, eax  ; 0 ; Error Code = 0  (no error)
 11740                              <1> 	;
 11741                              <1> swpin_retn:
 11742 0000347B 59                  <1> 	pop	ecx
 11743 0000347C 5B                  <1> 	pop	ebx
 11744 0000347D 5E                  <1> 	pop	esi
 11745 0000347E C3                  <1> 	retn
 11746                              <1> 
 11747                              <1> swpin_dnp_err:
 11748 0000347F B805000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
 11749                              <1> swpin_err_retn:
 11750 00003484 A3[A7740000]        <1> 	mov	[u.error], eax
 11751 00003489 F9                  <1> 	stc
 11752 0000348A C3                  <1> 	retn
 11753                              <1> 
 11754                              <1> swpin_snp_err:
 11755 0000348B B806000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
 11756 00003490 EBF2                <1> 	jmp	short swpin_err_retn
 11757                              <1> 
 11758                              <1> swap_out:
 11759                              <1> 	; 31/08/2015
 11760                              <1> 	; 05/05/2015
 11761                              <1> 	; 30/04/2015
 11762                              <1> 	; 28/04/2015
 11763                              <1> 	; 18/04/2015
 11764                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 11765                              <1> 	;
 11766                              <1> 	; INPUT -> 
 11767                              <1> 	;	none
 11768                              <1> 	;
 11769                              <1> 	; OUTPUT ->
 11770                              <1> 	;	EAX = Physical page address (which is swapped out
 11771                              <1> 	;	      for allocating a new page)
 11772                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
 11773                              <1> 	;		  or sector not present or drive not ready
 11774                              <1> 	;	     EAX = Error code
 11775                              <1> 	;	     [u.error] = EAX 
 11776                              <1> 	;		       = The last error code for the process
 11777                              <1> 	;		         (will be reset after returning to user)	  
 11778                              <1> 	;
 11779                              <1> 	; Modified Registers -> non (except EAX)
 11780                              <1> 	;
 11781 00003492 66833D[18850000]01  <1> 	cmp 	word [swpq_count], 1
 11782 0000349A 7274                <1>         jc      short swpout_im_err ; 'insufficient memory'
 11783                              <1> 
 11784                              <1>         ;cmp     dword [swp_drv], 1
 11785                              <1> 	;jc	short swpout_dnp_err ; 'swap disk/file not present'
 11786                              <1> 
 11787 0000349C 833D[22850000]01    <1>         cmp     dword [swpd_free], 1
 11788 000034A3 7258                <1> 	jc	short swpout_nfspc_err ; 'no free space on swap disk'
 11789                              <1> 
 11790 000034A5 53                  <1> 	push	ebx
 11791                              <1> swpout_1:
 11792 000034A6 31DB                <1> 	xor	ebx, ebx
 11793 000034A8 E86A000000          <1> 	call	swap_queue_shift
 11794 000034AD 21C0                <1> 	and	eax, eax	; entry count (before shifting)
 11795 000034AF 7457                <1> 	jz	short swpout_npts_err  ; There is no any PTE in
 11796                              <1> 				       ; the swap queue
 11797 000034B1 BB00E00800          <1> 	mov	ebx, swap_queue	       ; Addres of the head of 
 11798                              <1> 				       ; the swap queue		
 11799 000034B6 8B03                <1> 	mov	eax, [ebx]	       ; The PTE in the queue head	
 11800                              <1> 
 11801                              <1> 	;test	al, PTE_A_PRESENT      ; bit 0 = 1
 11802                              <1> 	;jz	short swpout_1	       ; non-present page already
 11803                              <1> 				       ; must not be in the queue
 11804                              <1> 
 11805                              <1> 	;test	al, PTE_A_WRITE	       ; bit 1 = 0
 11806                              <1> 	;jz	short swpout_1 	       ; read only page (must not be
 11807                              <1> 				       ; swapped out)
 11808                              <1> 	
 11809 000034B8 A820                <1> 	test	al, PTE_A_ACCESS       ; bit 5 = 1 (Accessed)
 11810 000034BA 75EA                <1> 	jnz	short swpout_1 	       ; accessed page (must not be
 11811                              <1> 				       ; swapped out, at this stage)
 11812                              <1> 	;
 11813 000034BC 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11814                              <1> 	;
 11815 000034C0 52                  <1> 	push	edx
 11816 000034C1 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
 11817 000034C3 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
 11818                              <1> 	;
 11819 000034C5 E861010000          <1> 	call	link_swap_block
 11820 000034CA 7304                <1> 	jnc	short swpout_2	       ; It may not be needed here	
 11821 000034CC 5A                  <1> 	pop	edx		       ; because [swpd_free] value	
 11822 000034CD 5B                  <1> 	pop	ebx
 11823 000034CE EB2D                <1> 	jmp	short swpout_nfspc_err ; was checked at the beginging. 	
 11824                              <1> swpout_2:	
 11825 000034D0 56                  <1> 	push	esi
 11826 000034D1 51                  <1> 	push	ecx
 11827 000034D2 50                  <1> 	push	eax ; sector address
 11828 000034D3 8B35[1A850000]      <1> 	mov	esi, [swp_drv]	
 11829 000034D9 B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 11830                              <1> 		; Note: Even if corresponding physical disk's sector 
 11831                              <1> 		; size different than 512 bytes, logical disk sector
 11832                              <1> 		; size is 512 bytes and disk writing procedure
 11833                              <1> 		; will be performed for writing 4096 bytes
 11834                              <1> 		; (2*2048, 8*512). 
 11835                              <1> 	; ESI = Logical disk description table address
 11836                              <1> 	; EBX = Buffer address
 11837                              <1> 	; EAX = Sector adress (offset address, logical sector number)
 11838                              <1> 	; ECX = Sector count ; 8 sectors
 11839 000034DE E8A4010000          <1> 	call	logical_disk_write
 11840 000034E3 59                  <1> 	pop	ecx ; sector address	
 11841 000034E4 730C                <1> 	jnc	short swpout_write_ok
 11842                              <1> 	;
 11843                              <1> 	;; call	unlink_swap_block ; this block must be left as 'in use'
 11844                              <1> swpout_dw_err:
 11845 000034E6 B808000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
 11846 000034EB A3[A7740000]        <1> 	mov	[u.error], eax
 11847 000034F0 EB06                <1> 	jmp	short swpout_retn
 11848                              <1> 	;
 11849                              <1> swpout_write_ok:
 11850                              <1> 	; EBX = Buffer (page) address
 11851                              <1> 	; EDX = Page Table entry address
 11852                              <1> 	; ECX = Swap disk sector (file block) address (31 bit)
 11853 000034F2 D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
 11854 000034F4 890A                <1> 	mov 	[edx], ecx 
 11855                              <1> 		; bit 0 = 0 (swapped page)
 11856 000034F6 89D8                <1> 	mov	eax, ebx
 11857                              <1> swpout_retn:
 11858 000034F8 59                  <1> 	pop	ecx
 11859 000034F9 5E                  <1> 	pop	esi
 11860 000034FA 5A                  <1> 	pop	edx
 11861 000034FB 5B                  <1> 	pop	ebx
 11862 000034FC C3                  <1> 	retn
 11863                              <1> 
 11864                              <1> ; Note: Swap_queue will not be updated in 'swap_out' procedure
 11865                              <1> ;	after the page is swapped out. (the PTE at the queue head
 11866                              <1> ;	-with 'non-present' attribute- will be dropped from the
 11867                              <1> ;	the queue in next 'swap_out' or in next 'swap_queue_shift'.
 11868                              <1> 	
 11869                              <1> ;swpout_dnp_err:
 11870                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
 11871                              <1> ;	jmp	short swpout_err_retn
 11872                              <1> swpout_nfspc_err:
 11873 000034FD B807000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
 11874                              <1> swpout_err_retn:
 11875 00003502 A3[A7740000]        <1> 	mov	[u.error], eax
 11876                              <1> 	;stc
 11877 00003507 C3                  <1> 	retn
 11878                              <1> swpout_npts_err:
 11879 00003508 B809000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
 11880 0000350D 5B                  <1> 	pop	ebx
 11881 0000350E EBF2                <1> 	jmp	short swpout_err_retn
 11882                              <1> swpout_im_err:
 11883 00003510 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
 11884 00003515 EBEB                <1> 	jmp	short swpout_err_retn
 11885                              <1> 
 11886                              <1> swap_queue_shift:
 11887                              <1> 	; 20/07/2015
 11888                              <1> 	; 28/04/2015
 11889                              <1> 	; 18/04/2015
 11890                              <1> 	; 23/10/2014 (Retro UNIX 386 v1 - beginning)
 11891                              <1> 	;
 11892                              <1> 	; INPUT ->
 11893                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
 11894                              <1> 	;	      and process number combination (bit 0 to 11)
 11895                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
 11896                              <1> 	; OUTPUT ->
 11897                              <1> 	;	If EBX input > 0 
 11898                              <1> 	;	    the queue will be shifted 4 bytes (dword),
 11899                              <1> 	; 	    from the tail to the head, up to entry offset
 11900                              <1> 	; 	    which points to EBX input value or nothing
 11901                              <1> 	;	    to do if EBX value is not found in the queue.
 11902                              <1> 	;	    (The entry -with EBX value- will be removed
 11903                              <1> 	;	     from the queue if it is found.)	
 11904                              <1> 	;	If EBX input = 0
 11905                              <1> 	;	    the queue will be shifted 4 bytes (dword),
 11906                              <1> 	; 	    from the tail to the head, if the PTE address
 11907                              <1> 	;	    in head of the queue is marked as "accessed"
 11908                              <1> 	;	    or it is marked as "non present".
 11909                              <1> 	;	    (If "accessed" flag of the PTE -in the head-
 11910                              <1> 	; 	    is set -to 1-, it will be reset -to 0- and then, 
 11911                              <1> 	;	    the queue will be rotated -without dropping
 11912                              <1> 	; 	    the PTE from the queue-, for 4 bytes on head
 11913                              <1> 	; 	    to tail direction. The PTE in the head will be
 11914                              <1> 	;	    moved in the tail, other PTEs will be shifted on
 11915                              <1> 	;	    head direction.)	
 11916                              <1> 	;
 11917                              <1> 	;	EAX = [swpq_count] (before the shifting)
 11918                              <1> 	;	    (EAX = 0 -> next 'swap_out' stage 
 11919                              <1> 	; 	     is not applicable)	
 11920                              <1> 	;
 11921                              <1> 	; Modified Registers -> EAX
 11922                              <1> 	;
 11923 00003517 0FB705[18850000]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
 11924 0000351E 6621C0              <1> 	and	ax, ax
 11925 00003521 7433                <1> 	jz	short swpqs_retn
 11926 00003523 57                  <1> 	push	edi
 11927 00003524 56                  <1> 	push	esi
 11928 00003525 53                  <1> 	push	ebx
 11929 00003526 51                  <1> 	push	ecx
 11930 00003527 50                  <1> 	push	eax
 11931 00003528 BE00E00800          <1> 	mov	esi, swap_queue
 11932 0000352D 89C1                <1> 	mov	ecx, eax
 11933 0000352F 09DB                <1> 	or	ebx, ebx
 11934 00003531 7424                <1> 	jz	short swpqs_7
 11935                              <1> swpqs_1:
 11936 00003533 AD                  <1> 	lodsd
 11937 00003534 39D8                <1> 	cmp	eax, ebx
 11938 00003536 7404                <1> 	je	short swpqs_2
 11939 00003538 E2F9                <1> 	loop	swpqs_1
 11940 0000353A EB15                <1> 	jmp	short swpqs_6
 11941                              <1> swpqs_2:
 11942 0000353C 89F7                <1> 	mov	edi, esi
 11943 0000353E 83EF04              <1> 	sub 	edi, 4
 11944                              <1> swpqs_3:
 11945 00003541 66FF0D[18850000]    <1> 	dec	word [swpq_count]
 11946 00003548 7403                <1> 	jz	short swpqs_5
 11947                              <1> swpqs_4:
 11948 0000354A 49                  <1> 	dec 	ecx
 11949 0000354B F3A5                <1> 	rep	movsd	; shift up (to the head)
 11950                              <1> swpqs_5:
 11951 0000354D 31C0                <1> 	xor	eax, eax
 11952 0000354F 8907                <1> 	mov	[edi], eax
 11953                              <1> swpqs_6:
 11954 00003551 58                  <1> 	pop	eax
 11955 00003552 59                  <1> 	pop	ecx
 11956 00003553 5B                  <1> 	pop	ebx
 11957 00003554 5E                  <1> 	pop	esi
 11958 00003555 5F                  <1> 	pop	edi
 11959                              <1> swpqs_retn:
 11960 00003556 C3                  <1> 	retn		
 11961                              <1> swpqs_7:
 11962 00003557 89F7                <1> 	mov	edi, esi ; head
 11963 00003559 AD                  <1> 	lodsd
 11964                              <1> 	; 20/07/2015
 11965 0000355A 89C3                <1> 	mov	ebx, eax
 11966 0000355C 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
 11967                              <1> 		      ; ebx = virtual address (at page boundary)	
 11968 00003562 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
 11969                              <1> 		      ; ax = process number (1 to 4095)
 11970 00003567 3A05[A1740000]      <1> 	cmp	al, [u.uno]
 11971                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
 11972 0000356D 7507                <1> 	jne	short swpqs_8
 11973 0000356F A1[AB740000]        <1> 	mov	eax, [u.pgdir]
 11974 00003574 EB16                <1> 	jmp	short swpqs_9
 11975                              <1> swpqs_8:
 11976                              <1> 	;shl	ax, 2
 11977 00003576 C0E002              <1> 	shl	al, 2
 11978 00003579 8B80[E2710000]      <1> 	mov 	eax, [eax+p.upage-4]
 11979 0000357F 09C0                <1> 	or	eax, eax
 11980 00003581 74BE                <1> 	jz	short swpqs_3 ; invalid upage
 11981 00003583 83C05B              <1> 	add	eax, u.pgdir - user
 11982                              <1> 			 ; u.pgdir value for the process
 11983                              <1> 			 ; is in [eax]
 11984 00003586 8B00                <1> 	mov	eax, [eax]
 11985 00003588 21C0                <1> 	and	eax, eax
 11986 0000358A 74B5                <1> 	jz	short swpqs_3 ; invalid page directory
 11987                              <1> swpqs_9:
 11988 0000358C 52                  <1> 	push	edx
 11989                              <1> 	; eax = page directory
 11990                              <1> 	; ebx = virtual address
 11991 0000358D E87EFBFFFF          <1> 	call	get_pte
 11992 00003592 89D3                <1> 	mov	ebx, edx ; PTE address
 11993 00003594 5A                  <1> 	pop	edx
 11994 00003595 72AA                <1> 	jc	short swpqs_3 ; empty PDE
 11995                              <1> 	; EAX = PTE value
 11996 00003597 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
 11997 00003599 74A6                <1> 	jz	short swpqs_3 ; Drop non-present page
 11998                              <1> 			      ; from the queue (head)
 11999 0000359B A802                <1> 	test	al, PTE_A_WRITE	  ; bit 1 = 0
 12000 0000359D 74A2                <1> 	jz	short swpqs_3 ; Drop read only page
 12001                              <1> 			      ; from the queue (head) 	
 12002                              <1> 	;test	al, PTE_A_ACCESS  ; bit 5 = 1 (Accessed)
 12003                              <1> 	;jz	short swpqs_6 ; present
 12004                              <1> 			      ; non-accessed page
 12005 0000359F 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
 12006 000035A3 73AC                <1> 	jnc	short swpqs_6  ; non-accessed page
 12007 000035A5 8903                <1> 	mov	[ebx], eax     ; save changed attribute
 12008                              <1> 	;
 12009                              <1> 	; Rotation (head -> tail)
 12010 000035A7 49                  <1> 	dec	ecx     ; entry count -> last entry number		
 12011 000035A8 74A7                <1> 	jz	short swpqs_6
 12012                              <1> 		; esi = head + 4
 12013                              <1> 		; edi = head
 12014 000035AA 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
 12015 000035AC F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 12016 000035AE 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1] 		
 12017 000035B0 EB9F                <1> 	jmp	short swpqs_6
 12018                              <1> 
 12019                              <1> add_to_swap_queue:
 12020                              <1> ; temporary - 16/09/2015
 12021 000035B2 C3                  <1> retn
 12022                              <1> 	; 20/07/2015
 12023                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12024                              <1> 	;
 12025                              <1> 	; Adds new page to swap queue
 12026                              <1> 	; (page directories and page tables must not be added
 12027                              <1> 	; to swap queue)	
 12028                              <1> 	;
 12029                              <1> 	; INPUT ->
 12030                              <1> 	;	EBX = Virtual address (for current process, [u.uno])
 12031                              <1> 	;
 12032                              <1> 	; OUTPUT ->
 12033                              <1> 	;	EAX = [swpq_count]
 12034                              <1> 	;	      (after the PTE has been added)
 12035                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
 12036                              <1> 	;	      the pte could not be added.
 12037                              <1> 	;
 12038                              <1> 	; Modified Registers -> EAX
 12039                              <1> 	;
 12040 000035B3 53                  <1> 	push	ebx
 12041 000035B4 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 12042 000035B9 8A1D[A1740000]      <1> 	mov	bl, [u.uno] ; current process number
 12043 000035BF E853FFFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
 12044                              <1> 				 ; it is already in the queue
 12045                              <1> 		; Then add it to the tail of the queue
 12046 000035C4 0FB705[18850000]    <1> 	movzx	eax, word [swpq_count]
 12047 000035CB 663D0004            <1> 	cmp	ax, 1024
 12048 000035CF 7205                <1> 	jb	short atsq_1
 12049 000035D1 6629C0              <1> 	sub	ax, ax
 12050 000035D4 5B                  <1> 	pop	ebx
 12051 000035D5 C3                  <1> 	retn
 12052                              <1> atsq_1:
 12053 000035D6 56                  <1> 	push	esi
 12054 000035D7 BE00E00800          <1> 	mov	esi, swap_queue
 12055 000035DC 6621C0              <1> 	and	ax, ax
 12056 000035DF 740A                <1> 	jz	short atsq_2
 12057 000035E1 66C1E002            <1> 	shl	ax, 2	; convert to offset
 12058 000035E5 01C6                <1> 	add	esi, eax
 12059 000035E7 66C1E802            <1> 	shr	ax, 2
 12060                              <1> atsq_2:
 12061 000035EB 6640                <1> 	inc	ax
 12062 000035ED 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
 12063 000035EF 66A3[18850000]      <1> 	mov	[swpq_count], ax
 12064 000035F5 5E                  <1> 	pop	esi
 12065 000035F6 5B                  <1> 	pop	ebx
 12066 000035F7 C3                  <1> 	retn
 12067                              <1> 
 12068                              <1> unlink_swap_block:
 12069                              <1> 	; 15/09/2015
 12070                              <1> 	; 30/04/2015
 12071                              <1> 	; 18/04/2015
 12072                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12073                              <1> 	;
 12074                              <1> 	; INPUT -> 
 12075                              <1> 	;	EAX = swap disk/file offset address
 12076                              <1> 	;	      (bit 1 to bit 31)
 12077                              <1> 	; OUTPUT ->
 12078                              <1> 	;	[swpd_free] is increased
 12079                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
 12080                              <1> 	;
 12081                              <1> 	; Modified Registers -> EAX
 12082                              <1> 	;
 12083 000035F8 53                  <1> 	push	ebx
 12084 000035F9 52                  <1> 	push	edx
 12085                              <1> 	;
 12086 000035FA C1E804              <1> 	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
 12087                              <1> 				     ; 3 bits right
 12088                              <1> 				     ; to get swap block/page number
 12089 000035FD 89C2                <1> 	mov	edx, eax
 12090                              <1> 	; 15/09/2015
 12091 000035FF C1EA03              <1> 	shr	edx, 3		     ; to get offset to S.A.T.
 12092                              <1> 				     ; (1 allocation bit = 1 page)
 12093                              <1> 				     ; (1 allocation bytes = 8 pages)
 12094 00003602 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 12095                              <1> 				     ; (to get 32 bit position)			
 12096                              <1> 	;
 12097 00003605 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
 12098 0000360A 01D3                <1> 	add	ebx, edx
 12099 0000360C 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 12100                              <1> 				     ; (allocation bit position)	 
 12101 0000360F 3B05[26850000]      <1> 	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
 12102                              <1> 				     ; than the address in 'swpd_next' ?
 12103                              <1> 				     ; (next/first free block value)		
 12104 00003615 7305                <1> 	jnb	short uswpbl_1	     ; no	
 12105 00003617 A3[26850000]        <1> 	mov	[swpd_next], eax     ; yes	
 12106                              <1> uswpbl_1:
 12107 0000361C 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate block
 12108                              <1> 				     ; set relevant bit to 1.
 12109                              <1> 				     ; set CF to the previous bit value	
 12110 0000361F F5                  <1> 	cmc			     ; complement carry flag	
 12111 00003620 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
 12112                              <1> 				     ; if the block is already deallocated
 12113                              <1> 				     ; before.	
 12114 00003622 FF05[22850000]      <1>         inc     dword [swpd_free]
 12115                              <1> uswpbl_2:
 12116 00003628 5A                  <1> 	pop	edx
 12117 00003629 5B                  <1> 	pop	ebx
 12118 0000362A C3                  <1> 	retn
 12119                              <1> 
 12120                              <1> link_swap_block:
 12121                              <1> 	; 01/07/2015
 12122                              <1> 	; 18/04/2015
 12123                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12124                              <1> 	;
 12125                              <1> 	; INPUT -> none
 12126                              <1> 	;
 12127                              <1> 	; OUTPUT ->
 12128                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
 12129                              <1> 	;	      in sectors (corresponding 
 12130                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
 12131                              <1> 	;
 12132                              <1> 	;	CF = 1 and EAX = 0 
 12133                              <1> 	; 		   if there is not a free block to be allocated	
 12134                              <1> 	;
 12135                              <1> 	; Modified Registers -> none (except EAX)
 12136                              <1> 	;
 12137                              <1> 
 12138                              <1> 	;mov	eax, [swpd_free]
 12139                              <1> 	;and	eax, eax
 12140                              <1> 	;jz	short out_of_swpspc
 12141                              <1> 	;
 12142 0000362B 53                  <1> 	push	ebx
 12143 0000362C 51                  <1> 	push	ecx
 12144                              <1> 	;
 12145 0000362D BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
 12146 00003632 89D9                <1> 	mov	ecx, ebx
 12147 00003634 031D[26850000]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
 12148                              <1> 				 ; next_free_swap_block >> 5
 12149 0000363A 030D[2A850000]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
 12150                              <1> 				 ; (total_swap_blocks - 1) >> 5
 12151                              <1> lswbl_scan:
 12152 00003640 39CB                <1> 	cmp	ebx, ecx
 12153 00003642 770A                <1> 	ja	short lswbl_notfound
 12154                              <1> 	;
 12155 00003644 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 12156                              <1> 			   ; Clears ZF if a bit is found set (1) and 
 12157                              <1> 			   ; loads the destination with an index to
 12158                              <1> 			   ; first set bit. (0 -> 31) 
 12159                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 12160                              <1> 	; 01/07/2015
 12161 00003647 751C                <1> 	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
 12162                              <1> 			 ;
 12163                              <1> 			 ; NOTE:  a Swap Disk Allocation Table bit 
 12164                              <1> 			 ;	  with value of 1 means 
 12165                              <1> 			 ;	  the corresponding page is free 
 12166                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
 12167 00003649 83C304              <1> 	add	ebx, 4
 12168                              <1> 			 ; We return back for searching next page block
 12169                              <1> 			 ; NOTE: [swpd_free] is not ZERO; so, 
 12170                              <1> 			 ;	 we always will find at least 1 free block here.
 12171 0000364C EBF2                <1> 	jmp    	short lswbl_scan
 12172                              <1> 	;
 12173                              <1> lswbl_notfound:	
 12174 0000364E 81E900000D00        <1> 	sub	ecx, swap_alloc_table
 12175 00003654 890D[26850000]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
 12176                              <1> 				 ; (unlink_swap_block procedure will change it)
 12177 0000365A 31C0                <1> 	xor	eax, eax
 12178 0000365C A3[22850000]        <1> 	mov	[swpd_free], eax
 12179 00003661 F9                  <1> 	stc
 12180                              <1> lswbl_ok:
 12181 00003662 59                  <1> 	pop	ecx
 12182 00003663 5B                  <1> 	pop	ebx
 12183 00003664 C3                  <1> 	retn
 12184                              <1> 	;
 12185                              <1> ;out_of_swpspc:
 12186                              <1> ;	stc
 12187                              <1> ;	retn
 12188                              <1> 
 12189                              <1> lswbl_found:
 12190 00003665 89D9                <1> 	mov	ecx, ebx
 12191 00003667 81E900000D00        <1> 	sub	ecx, swap_alloc_table
 12192 0000366D 890D[26850000]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
 12193                              <1> 				 ; address/offset (to the next)
 12194 00003673 FF0D[22850000]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
 12195                              <1> 	;
 12196 00003679 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 12197                              <1> 				 ; is copied into the Carry Flag and then cleared
 12198                              <1> 				 ; in the destination.
 12199                              <1> 				 ;
 12200                              <1> 				 ; Reset the bit which is corresponding to the 
 12201                              <1> 				 ; (just) allocated block.
 12202 0000367C C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
 12203 0000367F 01C8                <1> 	add	eax, ecx	 ; = block number
 12204 00003681 C1E003              <1> 	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
 12205                              <1> 				 ; 1 block =  8 sectors
 12206                              <1> 	;
 12207                              <1> 	; EAX = offset address of swap disk/file sector (beginning of the block)
 12208                              <1> 	;
 12209                              <1> 	; NOTE: The relevant page table entry will be updated
 12210                              <1> 	;       according to this EAX value...
 12211                              <1> 	;
 12212 00003684 EBDC                <1> 	jmp	short lswbl_ok
 12213                              <1> 
 12214                              <1> logical_disk_read:
 12215                              <1> 	; 20/07/2015
 12216                              <1> 	; 09/03/2015 (temporary code here)
 12217                              <1> 	;
 12218                              <1> 	; INPUT ->
 12219                              <1> 	; 	ESI = Logical disk description table address
 12220                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12221                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12222                              <1> 	; 	ECX = Sector count
 12223                              <1> 	;
 12224                              <1> 	;
 12225 00003686 C3                  <1> 	retn
 12226                              <1> 
 12227                              <1> logical_disk_write:
 12228                              <1> 	; 20/07/2015
 12229                              <1> 	; 09/03/2015 (temporary code here)
 12230                              <1> 	;
 12231                              <1> 	; INPUT ->
 12232                              <1> 	; 	ESI = Logical disk description table address
 12233                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12234                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12235                              <1> 	; 	ECX = Sector count
 12236                              <1> 	;
 12237 00003687 C3                  <1> 	retn
 12238                              <1> 
 12239                              <1> get_physical_addr:
 12240                              <1> 	; 18/10/2015
 12241                              <1> 	; 29/07/2015
 12242                              <1> 	; 20/07/2015
 12243                              <1> 	; 04/06/2015
 12244                              <1> 	; 20/05/2015
 12245                              <1> 	; 28/04/2015
 12246                              <1> 	; 18/04/2015
 12247                              <1> 	; Get physical address
 12248                              <1> 	;     (allocates a new page for user if it is not present)
 12249                              <1> 	;	
 12250                              <1> 	; (This subroutine is needed for mapping user's virtual 
 12251                              <1> 	; (buffer) address to physical address (of the buffer).)
 12252                              <1> 	; ('sys write', 'sys read' system calls...)
 12253                              <1> 	;
 12254                              <1> 	; INPUT ->
 12255                              <1> 	;	EBX = virtual address
 12256                              <1> 	;	u.pgdir = page directory (physical) address
 12257                              <1> 	;
 12258                              <1> 	; OUTPUT ->
 12259                              <1> 	;	EAX = physical address 
 12260                              <1> 	;	EBX = linear address	
 12261                              <1> 	;	EDX = physical address of the page frame
 12262                              <1> 	;	      (with attribute bits)
 12263                              <1> 	;	ECX = byte count within the page frame
 12264                              <1> 	;
 12265                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
 12266                              <1> 	;
 12267 00003688 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
 12268                              <1> 	;
 12269 0000368E A1[AB740000]        <1> 	mov	eax, [u.pgdir]
 12270 00003693 E878FAFFFF          <1> 	call	get_pte
 12271                              <1> 		; EDX = Page table entry address (if CF=0)
 12272                              <1> 	        ;       Page directory entry address (if CF=1)
 12273                              <1> 		;       (Bit 0 value is 0 if PT is not present)
 12274                              <1> 		; EAX = Page table entry value (page address)
 12275                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
 12276 00003698 731C                <1> 	jnc	short gpa_1
 12277                              <1> 	;
 12278 0000369A E856F9FFFF          <1> 	call	allocate_page
 12279 0000369F 725B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
 12280                              <1> gpa_0:
 12281 000036A1 E8C9F9FFFF          <1> 	call 	clear_page
 12282                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 12283 000036A6 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
 12284                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
 12285                              <1> 			   ; (user, writable, present page)	
 12286 000036A8 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
 12287 000036AA A1[AB740000]        <1> 	mov	eax, [u.pgdir]	
 12288 000036AF E85CFAFFFF          <1> 	call	get_pte
 12289 000036B4 7246                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12290                              <1> gpa_1:
 12291                              <1> 	; EAX = PTE value, EDX = PTE address
 12292 000036B6 A801                <1> 	test 	al, PTE_A_PRESENT
 12293 000036B8 751A                <1> 	jnz	short gpa_3
 12294 000036BA 09C0                <1> 	or	eax, eax
 12295 000036BC 7430                <1> 	jz	short gpa_4  ; Allocate a new page
 12296                              <1> 	; 20/07/2015
 12297 000036BE 55                  <1> 	push	ebp
 12298 000036BF 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
 12299                              <1> 	; reload swapped page
 12300 000036C1 E83C000000          <1> 	call	reload_page ; 28/04/2015
 12301 000036C6 5D                  <1> 	pop	ebp
 12302 000036C7 7224                <1> 	jc	short gpa_retn
 12303                              <1> gpa_2:
 12304                              <1> 	; 20/07/2015
 12305                              <1> 	; 20/05/2015
 12306                              <1> 	; add this page to swap queue
 12307 000036C9 50                  <1> 	push	eax 
 12308                              <1> 	; EBX = virtual address
 12309 000036CA E8E3FEFFFF          <1> 	call 	add_to_swap_queue
 12310 000036CF 58                  <1> 	pop	eax
 12311                              <1> 		; PTE address in EDX
 12312                              <1> 		; virtual address in EBX
 12313                              <1> 	; EAX = memory page address
 12314 000036D0 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
 12315                              <1> 				  ; present flag, bit 0 = 1
 12316                              <1> 				  ; user flag, bit 2 = 1	
 12317                              <1> 				  ; writable flag, bit 1 = 1
 12318 000036D2 8902                <1> 	mov	[edx], eax  ; Update PTE value
 12319                              <1> gpa_3:
 12320                              <1> 	; 18/10/2015
 12321 000036D4 89D9                <1> 	mov	ecx, ebx
 12322 000036D6 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
 12323 000036DC 89C2                <1> 	mov 	edx, eax
 12324 000036DE 662500F0            <1> 	and	ax, PTE_A_CLEAR
 12325 000036E2 01C8                <1> 	add	eax, ecx
 12326 000036E4 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
 12327 000036E6 81C100100000        <1> 	add	ecx, PAGE_SIZE
 12328 000036EC F8                  <1> 	clc
 12329                              <1> gpa_retn:
 12330 000036ED C3                  <1> 	retn	
 12331                              <1> gpa_4:	
 12332 000036EE E802F9FFFF          <1> 	call	allocate_page
 12333 000036F3 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12334 000036F5 E875F9FFFF          <1> 	call	clear_page
 12335 000036FA EBCD                <1> 	jmp	short gpa_2
 12336                              <1> 
 12337                              <1> gpa_im_err:	
 12338 000036FC B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12339                              <1> 				  ; Major error = 0 (No protection fault)	
 12340 00003701 C3                  <1> 	retn
 12341                              <1> 
 12342                              <1> reload_page:
 12343                              <1> 	; 20/07/2015
 12344                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
 12345                              <1> 	;
 12346                              <1> 	; Reload (Restore) swapped page at memory
 12347                              <1> 	;
 12348                              <1> 	; INPUT -> 
 12349                              <1> 	;	EBP = Virtual (linear) memory address
 12350                              <1> 	;	EAX = PTE value (swap disk sector address)
 12351                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
 12352                              <1> 	; OUTPUT ->
 12353                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
 12354                              <1> 	;
 12355                              <1> 	;	CF = 1 and EAX = error code
 12356                              <1> 	;
 12357                              <1> 	; Modified Registers -> none (except EAX)
 12358                              <1> 	;
 12359 00003702 D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
 12360 00003704 53                  <1> 	push	ebx      ;
 12361 00003705 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
 12362 00003707 E8E9F8FFFF          <1> 	call	allocate_page
 12363 0000370C 720C                <1> 	jc	short rlp_im_err
 12364 0000370E 93                  <1> 	xchg 	eax, ebx	
 12365                              <1> 	; EBX = Physical memory (page) address
 12366                              <1> 	; EAX = Swap disk (offset) address
 12367                              <1> 	; EBP = Virtual (linear) memory address
 12368 0000370F E81AFDFFFF          <1> 	call	swap_in
 12369 00003714 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
 12370 00003716 89D8                <1> 	mov	eax, ebx	
 12371                              <1> rlp_retn:
 12372 00003718 5B                  <1> 	pop	ebx
 12373 00003719 C3                  <1> 	retn
 12374                              <1> 	
 12375                              <1> rlp_im_err:	
 12376 0000371A B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12377                              <1> 				  ; Major error = 0 (No protection fault)	
 12378 0000371F EBF7                <1> 	jmp	short rlp_retn
 12379                              <1> 
 12380                              <1> rlp_swp_err:
 12381 00003721 B804000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
 12382 00003726 EBF0                <1> 	jmp	short rlp_retn
 12383                              <1> 
 12384                              <1> 
 12385                              <1> copy_page_dir:
 12386                              <1> 	; 19/09/2015
 12387                              <1> 	; temporary - 07/09/2015
 12388                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12389                              <1> 	;
 12390                              <1> 	; INPUT -> 
 12391                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 12392                              <1> 	;		    page directory.
 12393                              <1> 	; OUTPUT ->
 12394                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 12395                              <1> 	;	       page directory.
 12396                              <1> 	;	(New page directory with new page table entries.)
 12397                              <1> 	;	(New page tables with read only copies of the parent's
 12398                              <1> 	;	pages.)
 12399                              <1> 	;	EAX = 0 -> Error (CF = 1)
 12400                              <1> 	;
 12401                              <1> 	; Modified Registers -> none (except EAX)
 12402                              <1> 	;
 12403 00003728 E8C8F8FFFF          <1> 	call	allocate_page
 12404 0000372D 723E                <1> 	jc	short cpd_err
 12405                              <1> 	;
 12406 0000372F 55                  <1> 	push	ebp ; 20/07/2015
 12407 00003730 56                  <1> 	push	esi
 12408 00003731 57                  <1> 	push	edi
 12409 00003732 53                  <1> 	push	ebx
 12410 00003733 51                  <1> 	push	ecx
 12411 00003734 8B35[AB740000]      <1> 	mov	esi, [u.pgdir]
 12412 0000373A 89C7                <1> 	mov	edi, eax
 12413 0000373C 50                  <1> 	push	eax ; save child's page directory address
 12414                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 12415                              <1> 	; (use same system space for all user page tables) 
 12416 0000373D A5                  <1> 	movsd
 12417 0000373E BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 12418 00003743 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 12419                              <1> cpd_0:	
 12420 00003748 AD                  <1> 	lodsd
 12421                              <1> 	;or	eax, eax
 12422                              <1>         ;jnz     short cpd_1
 12423 00003749 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 12424 0000374B 7508                <1> 	jnz	short cpd_1
 12425                              <1>  	; (virtual address at the end of the page table)	
 12426 0000374D 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 12427 00003753 EB0F                <1> 	jmp	short cpd_2
 12428                              <1> cpd_1:	
 12429 00003755 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 12430 00003759 89C3                <1> 	mov	ebx, eax
 12431                              <1> 	; EBX = Parent's page table address
 12432 0000375B E81F000000          <1> 	call	copy_page_table
 12433 00003760 720C                <1> 	jc	short cpd_p_err
 12434                              <1> 	; EAX = Child's page table address
 12435 00003762 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 12436                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 12437                              <1> 			 ; (present, writable, user)
 12438                              <1> cpd_2:
 12439 00003764 AB                  <1> 	stosd
 12440 00003765 E2E1                <1> 	loop	cpd_0
 12441                              <1> 	;
 12442 00003767 58                  <1> 	pop	eax  ; restore child's page directory address
 12443                              <1> cpd_3:
 12444 00003768 59                  <1> 	pop	ecx
 12445 00003769 5B                  <1> 	pop	ebx
 12446 0000376A 5F                  <1> 	pop	edi
 12447 0000376B 5E                  <1> 	pop	esi
 12448 0000376C 5D                  <1> 	pop	ebp
 12449                              <1> cpd_err:
 12450 0000376D C3                  <1> 	retn
 12451                              <1> cpd_p_err:
 12452                              <1> 	; release the allocated pages missing (recover free space)
 12453 0000376E 58                  <1> 	pop	eax  ; the new page directory address (physical)
 12454 0000376F 8B1D[AB740000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 12455 00003775 E8B4F9FFFF          <1> 	call 	deallocate_page_dir
 12456 0000377A 29C0                <1> 	sub	eax, eax ; 0
 12457 0000377C F9                  <1> 	stc
 12458 0000377D EBE9                <1> 	jmp	short cpd_3	
 12459                              <1> 
 12460                              <1> copy_page_table:
 12461                              <1> 	; 19/09/2015
 12462                              <1> 	; temporary - 07/09/2015
 12463                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12464                              <1> 	;
 12465                              <1> 	; INPUT -> 
 12466                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 12467                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
 12468                              <1> 	; OUTPUT ->
 12469                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 12470                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 12471                              <1> 	;	CF = 1 -> error 
 12472                              <1> 	;
 12473                              <1> 	; Modified Registers -> EBP (except EAX)
 12474                              <1> 	;
 12475 0000377F E871F8FFFF          <1> 	call	allocate_page
 12476 00003784 725A                <1> 	jc	short cpt_err
 12477                              <1> 	;
 12478 00003786 50                  <1> 	push	eax ; *
 12479                              <1> 	;push 	ebx
 12480 00003787 56                  <1> 	push	esi
 12481 00003788 57                  <1> 	push	edi
 12482 00003789 52                  <1> 	push	edx
 12483 0000378A 51                  <1> 	push	ecx
 12484                              <1> 	;
 12485 0000378B 89DE                <1> 	mov	esi, ebx
 12486 0000378D 89C7                <1> 	mov	edi, eax
 12487 0000378F 89C2                <1> 	mov	edx, eax
 12488 00003791 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 12489                              <1> cpt_0:
 12490 00003797 AD                  <1> 	lodsd
 12491 00003798 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 12492 0000379A 750B                <1> 	jnz	short cpt_1
 12493 0000379C 21C0                <1> 	and	eax, eax
 12494 0000379E 7430                <1> 	jz	short cpt_2
 12495                              <1> 	; ebp = virtual (linear) address of the memory page
 12496 000037A0 E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
 12497 000037A5 7234                <1> 	jc	short cpt_p_err
 12498                              <1> cpt_1:
 12499 000037A7 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 12500 000037AB 89C1                <1> 	mov	ecx, eax
 12501                              <1> 	; Allocate a new page for the child process
 12502 000037AD E843F8FFFF          <1> 	call	allocate_page
 12503 000037B2 7227                <1> 	jc	short cpt_p_err
 12504 000037B4 57                  <1> 	push	edi
 12505 000037B5 56                  <1> 	push	esi
 12506 000037B6 89CE                <1> 	mov	esi, ecx
 12507 000037B8 89C7                <1> 	mov	edi, eax
 12508 000037BA B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 12509 000037BF F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 12510 000037C1 5E                  <1> 	pop	esi
 12511 000037C2 5F                  <1> 	pop	edi
 12512                              <1> 	; 
 12513 000037C3 53                  <1> 	push	ebx
 12514 000037C4 50                  <1> 	push	eax
 12515 000037C5 89EB                <1> 	mov	ebx, ebp
 12516                              <1> 	; ebx = virtual address of the memory page
 12517 000037C7 E8E6FDFFFF          <1> 	call	add_to_swap_queue
 12518 000037CC 58                  <1> 	pop	eax
 12519 000037CD 5B                  <1> 	pop	ebx
 12520                              <1> 	;
 12521                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 12522 000037CE 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 12523                              <1> cpt_2:
 12524 000037D0 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 12525                              <1> 	;
 12526 000037D1 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 12527                              <1> 	;
 12528 000037D7 39D7                <1> 	cmp	edi, edx
 12529 000037D9 72BC                <1> 	jb	short cpt_0
 12530                              <1> cpt_p_err:
 12531 000037DB 59                  <1> 	pop	ecx
 12532 000037DC 5A                  <1> 	pop	edx
 12533 000037DD 5F                  <1> 	pop	edi
 12534 000037DE 5E                  <1> 	pop	esi
 12535                              <1> 	;pop	ebx
 12536 000037DF 58                  <1> 	pop	eax ; *
 12537                              <1> cpt_err:
 12538 000037E0 C3                  <1> 	retn
 12539                              <1> 
 12540                              <1> 
 12541                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
 12542                              <1> 
 12543                              <1> ;; Data:
 12544                              <1> 
 12545                              <1> ; 09/03/2015
 12546                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
 12547                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
 12548                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 12549                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 12550                              <1> ;swpd_next:  dd 0 ; next free page block
 12551                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
 12552                                  %include 'sysdefs.inc' ; 09/03/2015
 12553                              <1> ; Retro UNIX 386 v1 Kernel - SYSDEFS.INC
 12554                              <1> ; Last Modification: 04/02/2016
 12555                              <1> ;
 12556                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 12557                              <1> ; (Modified from 
 12558                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 12559                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 12560                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
 12561                              <1> ; ----------------------------------------------------------------------------
 12562                              <1> ;
 12563                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 12564                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 12565                              <1> ; <Bell Laboratories (17/3/1972)>
 12566                              <1> ; <Preliminary Release of UNIX Implementation Document>
 12567                              <1> ;
 12568                              <1> ; ****************************************************************************
 12569                              <1> 
 12570                              <1> nproc 	equ	16  ; number of processes
 12571                              <1> nfiles 	equ	50
 12572                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
 12573                              <1> nbuf	equ	6   ; number of buffers (04/02/2016)
 12574                              <1> 
 12575                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
 12576                              <1> ;core	equ 	0  	    ; 19/04/2013	
 12577                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
 12578                              <1> 	; (if total size of argument list and arguments is 128 bytes)
 12579                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
 12580                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
 12581                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
 12582                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
 12583                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
 12584                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
 12585                              <1> 	; '/core' dump file size = 32768 bytes
 12586                              <1>  
 12587                              <1> ; 08/03/2014 
 12588                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)		 	 
 12589                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
 12590                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
 12591                              <1> 
 12592                              <1> ; 30/08/2013
 12593                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
 12594                              <1> 
 12595                              <1> ; 05/02/2014
 12596                              <1> ; process status
 12597                              <1> ;SFREE 	equ 0
 12598                              <1> ;SRUN	equ 1
 12599                              <1> ;SWAIT	equ 2
 12600                              <1> ;SZOMB	equ 3
 12601                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
 12602                              <1> 
 12603                              <1> ; 09/03/2015
 12604                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
 12605                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
 12606                              <1> swap_alloc_table equ 0D0000h  ;  swap allocation table address ; temporary
 12607                              <1> 
 12608                              <1> ; 17/09/2015
 12609                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
 12610                              <1> 
 12611                              <1> ; 21/09/2015 (36) 
 12612                              <1> ; 01/07/2015 (35)
 12613                              <1> ; 14/07/2013 (0-34)
 12614                              <1> ; UNIX v1 system calls
 12615                              <1> _rele 	equ 0
 12616                              <1> _exit 	equ 1
 12617                              <1> _fork 	equ 2
 12618                              <1> _read 	equ 3
 12619                              <1> _write	equ 4
 12620                              <1> _open	equ 5
 12621                              <1> _close 	equ 6
 12622                              <1> _wait 	equ 7
 12623                              <1> _creat 	equ 8
 12624                              <1> _link 	equ 9
 12625                              <1> _unlink	equ 10
 12626                              <1> _exec	equ 11
 12627                              <1> _chdir	equ 12
 12628                              <1> _time 	equ 13
 12629                              <1> _mkdir 	equ 14
 12630                              <1> _chmod	equ 15
 12631                              <1> _chown	equ 16
 12632                              <1> _break	equ 17
 12633                              <1> _stat	equ 18
 12634                              <1> _seek	equ 19
 12635                              <1> _tell 	equ 20
 12636                              <1> _mount	equ 21
 12637                              <1> _umount	equ 22
 12638                              <1> _setuid	equ 23
 12639                              <1> _getuid	equ 24
 12640                              <1> _stime	equ 25
 12641                              <1> _quit	equ 26	
 12642                              <1> _intr	equ 27
 12643                              <1> _fstat	equ 28
 12644                              <1> _emt 	equ 29
 12645                              <1> _mdate 	equ 30
 12646                              <1> _stty 	equ 31
 12647                              <1> _gtty	equ 32
 12648                              <1> _ilgins	equ 33
 12649                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
 12650                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
 12651                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
 12652                              <1> 
 12653                              <1> %macro sys 1-4
 12654                              <1>     ; 13/04/2015
 12655                              <1>     ; Retro UNIX 386 v1 system call.		
 12656                              <1>     mov eax, %1
 12657                              <1>     %if %0 >= 2   
 12658                              <1>         mov ebx, %2
 12659                              <1>         %if %0 >= 3    
 12660                              <1>             mov ecx, %3
 12661                              <1>             %if %0 = 4
 12662                              <1>                mov edx, %4   
 12663                              <1>             %endif
 12664                              <1>         %endif
 12665                              <1>     %endif
 12666                              <1>     int 30h	   
 12667                              <1> %endmacro
 12668                              <1> 
 12669                              <1> ; 13/05/2015 - ERROR CODES
 12670                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
 12671                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
 12672                              <1> ; 14/05/2015
 12673                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
 12674                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
 12675                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
 12676                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
 12677                              <1> ; 16/05/2015		
 12678                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
 12679                              <1> ; 18/05/2015
 12680                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
 12681                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
 12682                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
 12683                              <1> ; 07/06/2015
 12684                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
 12685                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
 12686                              <1> ; 09/06/2015
 12687                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
 12688                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
 12689                              <1> ; 16/06/2015
 12690                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
 12691                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
 12692                              <1> ; 22/06/2015
 12693                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
 12694                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
 12695                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
 12696                              <1> ; 23/06/2015
 12697                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
 12698                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
 12699                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
 12700                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
 12701                              <1> ; 27/06/2015
 12702                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
 12703                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
 12704                              <1> ; 29/06/2015
 12705                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
 12706                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error	
 12707                              <1> 
 12708                              <1> ; 26/08/2015
 12709                              <1> ; 24/07/2015
 12710                              <1> ; 24/06/2015
 12711                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
 12712                              <1> ; 01/07/2015
 12713                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
 12714                              <1> ;	 					 		
 12715                                  %include 'u0.s'        ; 15/03/2015
 12716                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
 12717                              <1> ; Last Modification: 21/11/2015
 12718                              <1> ; ----------------------------------------------------------------------------
 12719                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 12720                              <1> ; (v0.1 - Beginning: 11/07/2012)
 12721                              <1> ;
 12722                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 12723                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 12724                              <1> ; <Bell Laboratories (17/3/1972)>
 12725                              <1> ; <Preliminary Release of UNIX Implementation Document>
 12726                              <1> ;
 12727                              <1> ; Retro UNIX 8086 v1 - U0.ASM (28/07/2014) //// UNIX v1 -> u0.s
 12728                              <1> ;
 12729                              <1> ; ****************************************************************************
 12730                              <1> 
 12731                              <1> sys_init:
 12732                              <1> 	; 18/10/2015
 12733                              <1> 	; 28/08/2015
 12734                              <1> 	; 24/08/2015
 12735                              <1> 	; 14/08/2015
 12736                              <1> 	; 24/07/2015 
 12737                              <1> 	; 02/07/2015
 12738                              <1> 	; 01/07/2015
 12739                              <1> 	; 23/06/2015
 12740                              <1> 	; 15/04/2015
 12741                              <1> 	; 13/04/2015
 12742                              <1> 	; 11/03/2015 (Retro UNIX 386 v1 - Beginning)
 12743                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 12744                              <1> 	;
 12745                              <1> 	;call	ldrv_init ; Logical drive description tables initialization
 12746                              <1> 	;
 12747                              <1> 	; 14/02/2014
 12748                              <1> 	; 14/07/2013
 12749 000037E1 66B82900            <1> 	mov	ax, 41
 12750 000037E5 66A3[48740000]      <1> 	mov	[rootdir], ax
 12751 000037EB 66A3[5C740000]      <1> 	mov	[u.cdir], ax
 12752 000037F1 2401                <1> 	and	al, 1 ; 15/04/2015
 12753 000037F3 A2[A1740000]        <1> 	mov	[u.uno], al
 12754 000037F8 66A3[46740000]      <1> 	mov	[mpid], ax
 12755 000037FE 66A3[46710000]      <1> 	mov	[p.pid], ax
 12756 00003804 A2[D6710000]        <1> 	mov	[p.stat], al ; SRUN, 05/02/2014
 12757                              <1> 	;
 12758 00003809 B004                <1> 	mov	al, time_count ; 30/08/2013
 12759 0000380B A2[94740000]        <1> 	mov	[u.quant], al ; 14/07/2013
 12760                              <1> 	; 02/07/2015
 12761 00003810 A1[78700000]        <1> 	mov	eax, [k_page_dir]
 12762                              <1> 	;sub	eax, eax
 12763 00003815 A3[AB740000]        <1> 	mov	[u.pgdir], eax ; reset
 12764                              <1> 	; 18/10/2015
 12765                              <1> 	;mov	[u.ppgdir], eax ; 0
 12766                              <1>         ;
 12767 0000381A E869030000          <1>  	call	epoch
 12768 0000381F A3[9C820000]        <1> 	mov	[s.time], eax ; 13/03/2015
 12769                              <1> 	; 17/07/2013
 12770 00003824 E8C3060000          <1> 	call 	bf_init ; buffer initialization 
 12771                              <1> 	; 23/06/2015
 12772 00003829 E8C7F7FFFF          <1> 	call	allocate_page
 12773                              <1> 	;;jc	error
 12774 0000382E 0F829C000000        <1>         jc      panic   ; jc short panic (01/07/2015)
 12775 00003834 A3[A2740000]        <1> 	mov	[u.upage], eax ; user structure page	
 12776 00003839 A3[E6710000]        <1> 	mov	[p.upage], eax
 12777                              <1> 	;
 12778 0000383E E82CF8FFFF          <1> 	call	clear_page
 12779                              <1> 	;
 12780                              <1> 	; 14/08/2015
 12781 00003843 FA                  <1> 	cli
 12782                              <1> 	; 14/03/2015
 12783                              <1> 	; 17/01/2014
 12784 00003844 E8F1010000          <1> 	call	sp_init ; serial port initialization
 12785                              <1> 	; 14/08/2015
 12786 00003849 FB                  <1> 	sti
 12787                              <1> 	;
 12788                              <1> 	; 30/06/2015
 12789                              <1> 	;mov	esi, kernel_init_ok_msg
 12790                              <1> 	;call 	print_msg
 12791                              <1> 	;
 12792 0000384A 30DB                <1> 	xor	bl, bl ; video page 0
 12793                              <1> vp_clr_nxt:  ; clear video pages (reset cursor positions)
 12794 0000384C E8122E0000          <1> 	call 	vp_clr  ; 17/07/2013
 12795 00003851 FEC3                <1> 	inc	bl
 12796 00003853 80FB08              <1> 	cmp	bl, 8
 12797 00003856 72F4                <1> 	jb	short vp_clr_nxt
 12798                              <1> 	;
 12799                              <1> 	; 24/07/2015
 12800                              <1> 	;push    KDATA
 12801                              <1>         ;push    esp
 12802                              <1> 	;mov	[tss.esp0], esp
 12803                              <1>         ;mov     word [tss.ss0], KDATA
 12804                              <1> 	;
 12805                              <1> 	; 24/08/2015
 12806                              <1> 	;; temporary (01/07/2015)
 12807 00003858 C605[94740000]04    <1> 	mov	byte [u.quant], time_count ; 4 
 12808                              <1> 			       ; it is not needed here !
 12809                              <1> 	;;inc	byte [u.kcall] ; 'the caller is kernel' sign
 12810 0000385F FE0D[4F740000]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
 12811                              <1> 			      ; 0 = executing a system call
 12812                              <1> 	;;sys 	_msg, kernel_init_ok_msg, 255, 0
 12813                              <1> 	;
 12814                              <1> 	;;; 06/08/2015
 12815                              <1> 	;;;call	getch ; wait for a key stroke
 12816                              <1> 	;;mov 	ecx, 0FFFFFFFh	
 12817                              <1> ;;sys_init_msg_wait:
 12818                              <1> ;;	push 	ecx
 12819                              <1> ;;	mov	al, 1
 12820                              <1> ;;	mov 	ah, [ptty] ; active (current) video page
 12821                              <1> ;;	call	getc_n
 12822                              <1> ;;	pop	ecx
 12823                              <1> ;;	jnz	short sys_init_msg_ok
 12824                              <1> ;;	loop	sys_init_msg_wait
 12825                              <1> 	;
 12826                              <1> ;;sys_init_msg_ok:
 12827                              <1> 	; 28/08/2015 (initial settings for the 1st 'rswap')
 12828 00003865 6A10                <1> 	push	KDATA ; ss
 12829 00003867 54                  <1> 	push	esp
 12830 00003868 9C                  <1> 	pushfd
 12831 00003869 6A08                <1> 	push	KCODE ; cs
 12832 0000386B 68[9F380000]        <1> 	push	init_exec ; eip
 12833 00003870 8925[50740000]      <1> 	mov	[u.sp], esp
 12834 00003876 1E                  <1> 	push	ds
 12835 00003877 06                  <1> 	push	es
 12836 00003878 0FA0                <1> 	push	fs
 12837 0000387A 0FA8                <1> 	push	gs	
 12838 0000387C 60                  <1> 	pushad
 12839 0000387D 8925[54740000]      <1> 	mov	[u.usp], esp
 12840 00003883 E85C1B0000          <1> 	call	wswap ; save current user (u) structure, user registers
 12841                              <1> 		      ; and interrupt return components (for IRET)
 12842 00003888 61                  <1> 	popad
 12843 00003889 6658                <1> 	pop	ax ; gs
 12844 0000388B 6658                <1> 	pop	ax ; fs
 12845 0000388D 6658                <1> 	pop	ax ; es
 12846 0000388F 6658                <1> 	pop	ax ; ds	
 12847 00003891 58                  <1> 	pop	eax ; eip (init_exec)
 12848 00003892 6658                <1> 	pop	ax ; cs (KCODE)
 12849 00003894 58                  <1> 	pop	eax ; E-FLAGS
 12850 00003895 58                  <1> 	pop	eax ; esp
 12851 00003896 6658                <1> 	pop	ax ; ss (KDATA)
 12852                              <1> 	;
 12853 00003898 31C0                <1> 	xor	eax, eax ; 0
 12854 0000389A A3[AF740000]        <1> 	mov	[u.ppgdir], eax ; reset (to zero) for '/etc/init'
 12855                              <1> 	;
 12856                              <1> 	; 02/07/2015
 12857                              <1> 	; [u.pgdir ] = [k_page_dir]
 12858                              <1> 	; [u.ppgdir] = 0 (page dir of the parent process)
 12859                              <1> 	;     (The caller is os kernel sign for 'sysexec')
 12860                              <1> init_exec:
 12861                              <1> 	; 13/03/2013
 12862                              <1> 	; 24/07/2013
 12863 0000389F BB[C6380000]        <1> 	mov	ebx, init_file
 12864 000038A4 B9[BE380000]        <1> 	mov	ecx, init_argp
 12865                              <1> 	; EBX contains 'etc/init' asciiz file name address  
 12866                              <1> 	; ECX contains address of argument list pointer
 12867                              <1> 	;
 12868                              <1> 	;dec 	byte [sysflg] ; FFh = ready for system call
 12869                              <1> 			      ; 0 = executing a system call
 12870                              <1> 	sys	_exec  ; execute file
 12871                              <2> 
 12872                              <2> 
 12873 000038A9 B80B000000          <2>  mov eax, %1
 12874                              <2>  %if %0 >= 2
 12875                              <2>  mov ebx, %2
 12876                              <2>  %if %0 >= 3
 12877                              <2>  mov ecx, %3
 12878                              <2>  %if %0 = 4
 12879                              <2>  mov edx, %4
 12880                              <2>  %endif
 12881                              <2>  %endif
 12882                              <2>  %endif
 12883 000038AE CD30                <2>  int 30h
 12884 000038B0 731E                <1> 	jnc	short panic
 12885                              <1> 	;
 12886 000038B2 BE[866D0000]        <1> 	mov	esi, etc_init_err_msg
 12887 000038B7 E837000000          <1> 	call 	print_msg
 12888 000038BC EB1C                <1> 	jmp	short key_to_reboot
 12889                              <1> 
 12890                              <1> ;align 4
 12891                              <1> init_argp:
 12892 000038BE [C6380000]00000000  <1> 	dd 	init_file, 0  ; 23/06/2015 (dw -> dd)
 12893                              <1> init_file:
 12894                              <1> 	; 24/08/2015
 12895 000038C6 2F6574632F696E6974- <1> 	db 	'/etc/init', 0
 12896 000038CF 00                  <1>
 12897                              <1> panic:
 12898                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 12899                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 12900 000038D0 BE[6B6D0000]        <1> 	mov 	esi, panic_msg
 12901 000038D5 E819000000          <1> 	call 	print_msg
 12902                              <1> key_to_reboot:
 12903                              <1> 	; 15/11/2015
 12904 000038DA E8BB2B0000          <1> 	call 	getch 
 12905                              <1> 		; wait for a character from the current tty
 12906                              <1> 	;
 12907 000038DF B00A                <1> 	mov	al, 0Ah
 12908 000038E1 8A1D[A6700000]      <1> 	mov	bl, [ptty] ; [active_page]
 12909 000038E7 B407                <1> 	mov	ah, 07h ; Black background, 
 12910                              <1> 			; light gray forecolor
 12911 000038E9 E8ECDBFFFF          <1> 	call 	write_tty
 12912 000038EE E96CD8FFFF          <1> 	jmp	cpu_reset 
 12913                              <1> 
 12914                              <1> print_msg:
 12915                              <1> 	; 01/07/2015
 12916                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 12917                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 12918                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
 12919                              <1> 	;
 12920                              <1> 	;
 12921 000038F3 AC                  <1> 	lodsb
 12922                              <1> pmsg1:
 12923 000038F4 56                  <1> 	push 	esi
 12924 000038F5 0FB61D[A6700000]    <1> 	movzx	ebx, byte [ptty]
 12925 000038FC B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
 12926 000038FE E8D7DBFFFF          <1> 	call 	write_tty
 12927 00003903 5E                  <1> 	pop	esi
 12928 00003904 AC                  <1> 	lodsb
 12929 00003905 20C0                <1> 	and 	al, al
 12930 00003907 75EB                <1> 	jnz 	short pmsg1
 12931 00003909 C3                  <1> 	retn
 12932                              <1> 	
 12933                              <1> ctrlbrk:
 12934                              <1> 	; 12/11/2015
 12935                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 12936                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
 12937                              <1> 	;
 12938                              <1> 	; INT 1Bh (control+break) handler		
 12939                              <1> 	;
 12940                              <1>       	; Retro Unix 8086 v1 feature only!
 12941                              <1>       	;
 12942 0000390A 66833D[96740000]00  <1> 	cmp 	word [u.intr], 0
 12943 00003912 7645                <1> 	jna 	short cbrk4
 12944                              <1> cbrk0:
 12945                              <1> 	; 12/11/2015
 12946                              <1> 	; 06/12/2013
 12947 00003914 66833D[98740000]00  <1> 	cmp 	word [u.quit], 0
 12948 0000391C 743B                <1> 	jz	short cbrk4
 12949                              <1> 	;
 12950                              <1> 	; 20/09/2013	
 12951 0000391E 6650                <1> 	push 	ax
 12952 00003920 A0[A6700000]        <1> 	mov	al, [ptty]
 12953                              <1> 	;
 12954                              <1> 	; 12/11/2015
 12955                              <1> 	;
 12956                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
 12957                              <1> 	; or ctrl+break from console (pseudo) tty
 12958                              <1> 	; (!redirection!)
 12959                              <1> 	;
 12960 00003925 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
 12961 00003927 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
 12962                              <1> 	;	
 12963                              <1> 	; Serial port interrupt handler sets [ptty]
 12964                              <1> 	; to the port's tty number (as temporary).
 12965                              <1> 	;
 12966                              <1> 	; If active process is using a stdin or 
 12967                              <1> 	; stdout redirection (by the shell),
 12968                              <1>         ; console tty keyboard must be available
 12969                              <1> 	; to terminate running process,
 12970                              <1> 	; in order to prevent a deadlock. 
 12971                              <1> 	;
 12972 00003929 52                  <1> 	push	edx
 12973 0000392A 0FB615[A1740000]    <1> 	movzx	edx, byte [u.uno]
 12974 00003931 3A82[A5710000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
 12975 00003937 5A                  <1> 	pop	edx
 12976 00003938 7412                <1> 	je	short cbrk2
 12977                              <1> cbrk1:
 12978 0000393A FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
 12979                              <1> 	; 06/12/2013
 12980 0000393C 3A05[88740000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
 12981 00003942 7408                <1> 	je	short cbrk2	
 12982 00003944 3A05[89740000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
 12983 0000394A 750B                <1> 	jne	short cbrk3	
 12984                              <1> cbrk2:
 12985                              <1> 	;; 06/12/2013
 12986                              <1> 	;mov	ax, [u.quit]
 12987                              <1> 	;and	ax, ax
 12988                              <1> 	;jz	short cbrk3
 12989                              <1> 	;
 12990 0000394C 6631C0              <1> 	xor	ax, ax ; 0
 12991 0000394F 6648                <1> 	dec	ax
 12992                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
 12993 00003951 66A3[98740000]      <1> 	mov	[u.quit], ax
 12994                              <1> cbrk3:
 12995 00003957 6658                <1> 	pop	ax
 12996                              <1> cbrk4:
 12997 00003959 C3                  <1> 	retn
 12998                              <1> 
 12999                              <1> com2_int:
 13000                              <1> 	; 07/11/2015 
 13001                              <1> 	; 24/10/2015
 13002                              <1> 	; 23/10/2015
 13003                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13004                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13005                              <1> 	; < serial port 2 interrupt handler >
 13006                              <1> 	;
 13007 0000395A 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13008                              <1> 	;push	eax
 13009 0000395D 66B80900            <1> 	mov	ax, 9
 13010 00003961 EB07                <1> 	jmp	short comm_int
 13011                              <1> com1_int:
 13012                              <1> 	; 07/11/2015
 13013                              <1> 	; 24/10/2015
 13014 00003963 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13015                              <1> 	; 23/10/2015
 13016                              <1> 	;push	eax
 13017 00003966 66B80800            <1> 	mov	ax, 8
 13018                              <1> comm_int:
 13019                              <1> 	; 20/11/2015
 13020                              <1> 	; 18/11/2015
 13021                              <1> 	; 17/11/2015
 13022                              <1> 	; 16/11/2015
 13023                              <1> 	; 09/11/2015
 13024                              <1> 	; 08/11/2015
 13025                              <1> 	; 07/11/2015
 13026                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
 13027                              <1> 	; 01/11/2015
 13028                              <1> 	; 26/10/2015
 13029                              <1> 	; 23/10/2015
 13030 0000396A 53                  <1> 	push	ebx
 13031 0000396B 56                  <1> 	push	esi
 13032 0000396C 57                  <1> 	push	edi
 13033 0000396D 1E                  <1> 	push 	ds
 13034 0000396E 06                  <1> 	push 	es
 13035                              <1> 	; 18/11/2015
 13036 0000396F 0F20DB              <1> 	mov	ebx, cr3
 13037 00003972 53                  <1> 	push	ebx ; ****
 13038                              <1> 	;
 13039 00003973 51                  <1> 	push	ecx ; ***
 13040 00003974 52                  <1> 	push	edx ; **
 13041                              <1> 	;
 13042 00003975 BB10000000          <1> 	mov	ebx, KDATA
 13043 0000397A 8EDB                <1> 	mov	ds, bx
 13044 0000397C 8EC3                <1> 	mov	es, bx
 13045                              <1> 	;
 13046 0000397E 8B0D[78700000]      <1> 	mov	ecx, [k_page_dir]
 13047 00003984 0F22D9              <1> 	mov	cr3, ecx
 13048                              <1> 	; 20/11/2015
 13049                              <1> 	; Interrupt identification register
 13050 00003987 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
 13051                              <1> 	;
 13052 0000398B 3C08                <1> 	cmp 	al, 8 
 13053 0000398D 7702                <1> 	ja 	short com_i0
 13054                              <1> 	;
 13055                              <1> 	; 20/11/2015
 13056                              <1> 	; 17/11/2015
 13057                              <1> 	; 16/11/2015
 13058                              <1> 	; 15/11/2015
 13059                              <1> 	; 24/10/2015
 13060                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13061                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13062                              <1> 	; < serial port 1 interrupt handler >
 13063                              <1> 	;
 13064 0000398F FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
 13065                              <1> com_i0:
 13066                              <1> 	;push	eax ; *
 13067                              <1> 	; 07/11/2015
 13068 00003991 A2[E6700000]        <1> 	mov 	byte [ccomport], al
 13069                              <1> 	; 09/11/2015
 13070 00003996 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
 13071                              <1> 	; 17/11/2015
 13072                              <1>  	; reset request for response status
 13073 00003999 88A3[DC700000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
 13074                              <1> 	;
 13075                              <1> 	; 20/11/2015
 13076 0000399F EC                  <1> 	in	al, dx		; read interrupt id. register
 13077 000039A0 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13078 000039A2 2404                <1> 	and	al, 4		; received data available?	
 13079 000039A4 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
 13080                              <1> 	;
 13081                              <1> 	; 20/11/2015
 13082 000039A6 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
 13083 000039A9 EC                  <1> 	in	al, dx     	; read character
 13084                              <1> 	;JMP	$+2	   	; I/O DELAY
 13085                              <1> 	; 08/11/2015
 13086                              <1> 	; 07/11/2015
 13087 000039AA 89DE                <1> 	mov	esi, ebx 
 13088 000039AC 89DF                <1> 	mov	edi, ebx
 13089 000039AE 81C6[E0700000]      <1> 	add 	esi, rchar - 8 ; points to last received char
 13090 000039B4 81C7[E2700000]      <1> 	add	edi, schar - 8 ; points to last sent char
 13091 000039BA 8806                <1> 	mov	[esi], al ; received char (current char)
 13092                              <1> 	; query
 13093 000039BC 20C0                <1> 	and	al, al
 13094 000039BE 7527                <1> 	jnz	short com_i2
 13095                              <1>    	; response
 13096                              <1> 	; 17/11/2015
 13097                              <1> 	; set request for response status
 13098 000039C0 FE83[DC700000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
 13099                              <1> 	;
 13100 000039C6 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
 13101 000039CA EC                  <1> 	in	al, dx	   	; read line status register 
 13102 000039CB EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13103 000039CD 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
 13104 000039CF 7445                <1> 	jz	short com_eoi 	; no
 13105 000039D1 B0FF                <1> 	mov 	al, 0FFh   	; response			
 13106 000039D3 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
 13107 000039D7 EE                  <1> 	out	dx, al	   	; send on serial port
 13108                              <1> 	; 17/11/2015
 13109 000039D8 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
 13110 000039DB 7502                <1> 	jne 	short com_i1    ; no
 13111 000039DD 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
 13112                              <1> com_i1:
 13113                              <1> 	; 17/11/2015
 13114                              <1> 	; reset request for response status (again)
 13115 000039DF FE8B[DC700000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
 13116 000039E5 EB2F                <1> 	jmp	short com_eoi
 13117                              <1> com_i2:	
 13118                              <1> 	; 08/11/2015
 13119 000039E7 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
 13120 000039E9 7417                <1> 	je	short com_i3	; (check for response signal)
 13121                              <1> 	; 07/11/2015
 13122 000039EB 3C04                <1> 	cmp	al, 04h	; EOT
 13123 000039ED 751C                <1> 	jne	short com_i4	
 13124                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
 13125                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
 13126                              <1> 	; 08/11/2015
 13127                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
 13128 000039EF 861D[A6700000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
 13129 000039F5 E810FFFFFF          <1> 	call 	ctrlbrk
 13130 000039FA 861D[A6700000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
 13131                              <1> 	;mov	al, 04h ; EOT
 13132                              <1> 	; 08/11/2015
 13133 00003A00 EB09                <1> 	jmp	short com_i4	
 13134                              <1> com_i3:
 13135                              <1> 	; 08/11/2015
 13136                              <1> 	; If 0FFh has been received just after a query
 13137                              <1> 	; (schar, ZERO), it is a response signal.
 13138                              <1> 	; 17/11/2015
 13139 00003A02 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
 13140 00003A05 7704                <1> 	ja	short com_i4 ; no
 13141                              <1> 	; reset query status (schar)
 13142 00003A07 8807                <1> 	mov	[edi], al ; 0FFh
 13143 00003A09 FEC0                <1> 	inc	al ; 0
 13144                              <1> com_i4:
 13145                              <1> 	; 27/07/2014
 13146                              <1> 	; 09/07/2014
 13147 00003A0B D0E3                <1> 	shl	bl, 1	
 13148 00003A0D 81C3[A8700000]      <1> 	add	ebx, ttychr
 13149                              <1> 	; 23/07/2014 (always overwrite)
 13150                              <1> 	;;cmp	word [ebx], 0
 13151                              <1> 	;;ja	short com_eoi
 13152                              <1> 	;
 13153 00003A13 668903              <1> 	mov	[ebx], ax   ; Save ascii code
 13154                              <1> 			    ; scan code = 0
 13155                              <1> com_eoi:
 13156                              <1> 	;mov	al, 20h
 13157                              <1> 	;out	20h, al	   ; end of interrupt
 13158                              <1> 	;
 13159                              <1> 	; 07/11/2015
 13160                              <1>       	;pop	eax ; *
 13161 00003A16 A0[E6700000]        <1> 	mov	al, byte [ccomport] ; current COM port
 13162                              <1> 	 ; al = tty number (8 or 9)
 13163 00003A1B E89F1A0000          <1>         call	wakeup
 13164                              <1> com_iret:
 13165                              <1> 	; 23/10/2015
 13166 00003A20 5A                  <1> 	pop	edx ; **
 13167 00003A21 59                  <1> 	pop	ecx ; ***
 13168                              <1> 	; 18/11/2015
 13169                              <1> 	;pop	eax ; ****
 13170                              <1> 	;mov	cr3, eax
 13171                              <1> 	;jmp	iiret
 13172 00003A22 E94AD0FFFF          <1> 	jmp	iiretp
 13173                              <1> 
 13174                              <1> hfgchr:
 13175 00003A27 303132333435363738- <1> 	db '0123456789ABCDEF?*'
 13176 00003A30 394142434445463F2A  <1>
 13177 00003A39 00                  <1> 	db 0
 13178                              <1> 
 13179                              <1> ;iiretp: ; 01/09/2015
 13180                              <1> ;	; 28/08/2015
 13181                              <1> ;	pop	eax ; (*) page directory
 13182                              <1> ;	mov	cr3, eax
 13183                              <1> ;iiret:
 13184                              <1> ;	; 22/08/2014
 13185                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
 13186                              <1> ;	out	20h, al	; 8259 PORT
 13187                              <1> ;	;
 13188                              <1> ;	pop	es
 13189                              <1> ;	pop	ds
 13190                              <1> ;	pop	edi
 13191                              <1> ;	pop	esi
 13192                              <1> ;	pop	ebx ; 29/08/2014
 13193                              <1> ;	pop 	eax
 13194                              <1> ;	iretd
 13195                              <1> 
 13196                              <1> sp_init:
 13197                              <1> 	; 07/11/2015
 13198                              <1> 	; 29/10/2015
 13199                              <1> 	; 26/10/2015
 13200                              <1> 	; 23/10/2015
 13201                              <1> 	; 29/06/2015
 13202                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
 13203                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
 13204                              <1> 	; Initialization of Serial Port Communication Parameters
 13205                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13206                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13207                              <1> 	;
 13208                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13209                              <1> 	;
 13210                              <1> 	; INPUT:  (29/06/2015)
 13211                              <1> 	;	AL = 0 for COM1
 13212                              <1> 	;	     1 for COM2
 13213                              <1> 	;	AH = Communication parameters	
 13214                              <1> 	;
 13215                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13216                              <1> 	;	Bit	4	3	2	1	0
 13217                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13218                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13219                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13220                              <1> 	;		11 = even
 13221                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13222                              <1> 	;		Retro UNIX 386 v1 feature only !
 13223                              <1> 	;	Bit	7    6    5  | Baud rate
 13224                              <1> 	;		------------------------
 13225                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13226                              <1> 	;		0    0    1  | 9600 (12)
 13227                              <1> 	;		0    1    0  | 19200 (6) 
 13228                              <1> 	;		0    1	  1  | 38400 (3) 
 13229                              <1> 	;		1    0	  0  | 14400 (8)
 13230                              <1> 	;		1    0	  1  | 28800 (4)
 13231                              <1> 	;		1    1    0  | 57600 (2)
 13232                              <1> 	;		1    1    1  | 115200 (1) 	
 13233                              <1> 	
 13234                              <1> 	; References:	
 13235                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
 13236                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
 13237                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
 13238                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
 13239                              <1> 	;
 13240                              <1> 	; Set communication parameters for COM1 (= 03h)	
 13241                              <1> 	;
 13242 00003A3A BB[E2700000]        <1> 	mov	ebx, com1p		; COM1 parameters  
 13243 00003A3F 66BAF803            <1> 	mov	dx, 3F8h		; COM1
 13244                              <1> 	 ; 29/10/2015
 13245 00003A43 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13246 00003A47 E86F000000          <1> 	call	sp_i3	; call A4	
 13247 00003A4C A880                <1> 	test	al, 80h
 13248 00003A4E 7410                <1> 	jz	short sp_i0 ; OK..
 13249                              <1> 		; Error !
 13250                              <1> 	;mov	dx, 3F8h
 13251 00003A50 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
 13252 00003A53 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13253 00003A57 E85F000000          <1> 	call	sp_i3	; call A4	
 13254 00003A5C A880                <1> 	test	al, 80h
 13255 00003A5E 7508                <1> 	jnz	short sp_i1
 13256                              <1> sp_i0:
 13257                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
 13258                              <1>         ; (INT 14h initialization code disables interrupts.)
 13259                              <1> 	;
 13260 00003A60 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13261 00003A63 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
 13262                              <1> sp_i1:
 13263 00003A68 43                  <1> 	inc	ebx
 13264 00003A69 66BAF802            <1> 	mov	dx, 2F8h		; COM2
 13265                              <1> 	 ; 29/10/2015
 13266 00003A6D 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13267 00003A71 E845000000          <1> 	call	sp_i3	; call A4	
 13268 00003A76 A880                <1> 	test	al, 80h
 13269 00003A78 7410                <1> 	jz	short sp_i2 ; OK..
 13270                              <1> 		; Error !
 13271                              <1> 	;mov	dx, 2F8h
 13272 00003A7A 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
 13273 00003A7D 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13274 00003A81 E835000000          <1> 	call	sp_i3	; call A4	
 13275 00003A86 A880                <1> 	test	al, 80h
 13276 00003A88 7530                <1> 	jnz	short sp_i7
 13277                              <1> sp_i2:
 13278 00003A8A C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13279                              <1> sp_i6:
 13280                              <1> 	;; COM2 - enabling IRQ 3
 13281                              <1> 	; 07/11/2015
 13282                              <1> 	; 26/10/2015
 13283 00003A8D 9C                  <1> 	pushf
 13284 00003A8E FA                  <1> 	cli
 13285                              <1> 	;
 13286 00003A8F 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
 13287 00003A93 EC                  <1> 	in	al, dx 	   		; read register
 13288 00003A94 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13289 00003A96 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13290 00003A98 EE                  <1> 	out	dx, al     		; write back to register
 13291 00003A99 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13292 00003A9B 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
 13293 00003A9F EC                  <1> 	in	al, dx     		; read register
 13294 00003AA0 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13295                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13296 00003AA2 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13297 00003AA4 EE                  <1> 	out	dx, al 	   		; write back to register
 13298 00003AA5 EB00                <1> 	JMP	$+2        		; I/O DELAY
 13299 00003AA7 E421                <1> 	in	al, 21h    		; read interrupt mask register
 13300 00003AA9 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13301 00003AAB 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
 13302 00003AAD E621                <1> 	out	21h, al    		; write back to register
 13303                              <1> 	;
 13304                              <1> 	; 23/10/2015
 13305 00003AAF B8[5A390000]        <1> 	mov 	eax, com2_int
 13306 00003AB4 A3[4C3F0000]        <1> 	mov	[com2_irq3], eax
 13307                              <1> 	; 26/10/2015
 13308 00003AB9 9D                  <1> 	popf	
 13309                              <1> sp_i7:
 13310 00003ABA C3                  <1> 	retn
 13311                              <1> 
 13312                              <1> sp_i3:
 13313                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
 13314                              <1> 	; 28/10/2015
 13315 00003ABB FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
 13316 00003ABD B000                <1> 	mov	al, 0
 13317 00003ABF EE                  <1> 	out	dx, al			; disable serial port interrupt
 13318 00003AC0 EB00                <1> 	JMP	$+2			; I/O DELAY
 13319 00003AC2 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
 13320 00003AC5 B080                <1> 	mov	al, 80h			
 13321 00003AC7 EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
 13322                              <1> 	;-----	SET BAUD RATE DIVISOR
 13323                              <1> 	; 26/10/2015
 13324 00003AC8 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
 13325                              <1> 					; of the divisor value
 13326 00003ACB 88C8                <1> 	mov	al, cl	; 1
 13327 00003ACD EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
 13328                              <1> 					; 2 = 57600 baud
 13329                              <1> 					; 3 = 38400 baud
 13330                              <1> 					; 6 = 19200 baud
 13331                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
 13332 00003ACE EB00                <1> 	JMP	$+2			; I/O DELAY
 13333 00003AD0 28C0                <1> 	sub	al, al
 13334 00003AD2 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
 13335                              <1> 					; of the divisor value
 13336 00003AD4 EE                  <1> 	out	dx, al ; 0
 13337 00003AD5 EB00                <1> 	JMP	$+2			; I/O DELAY
 13338                              <1> 	;	
 13339 00003AD7 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
 13340                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
 13341 00003AD9 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
 13342 00003ADC EE                  <1> 	out	dx, al			
 13343 00003ADD EB00                <1> 	JMP	$+2			; I/O DELAY
 13344                              <1> 	; 29/10/2015
 13345 00003ADF FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
 13346 00003AE1 30C0                <1> 	xor	al, al			; 0
 13347 00003AE3 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
 13348 00003AE4 EB00                <1> 	JMP	$+2	
 13349                              <1> sp_i4:
 13350                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
 13351                              <1> 	; 29/06/2015 (line status after modem status)
 13352 00003AE6 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
 13353                              <1> sp_i4s:
 13354 00003AE9 EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
 13355 00003AEA EB00                <1> 	JMP	$+2			; I/O DELAY
 13356 00003AEC 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
 13357 00003AEE FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
 13358                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
 13359 00003AF0 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
 13360                              <1> 	; AL = Line status, AH = Modem status
 13361 00003AF1 C3                  <1> 	retn
 13362                              <1> 
 13363                              <1> sp_status:
 13364                              <1> 	; 29/06/2015
 13365                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
 13366                              <1> 	; Get serial port status
 13367 00003AF2 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
 13368 00003AF6 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
 13369                              <1> 					; dx = 2FEh for COM2
 13370 00003AF8 EBEF                <1> 	jmp	short sp_i4s
 13371                              <1> 
 13372                              <1> sp_setp: ; Set serial port communication parameters
 13373                              <1> 	; 07/11/2015
 13374                              <1> 	; 29/10/2015
 13375                              <1> 	; 29/06/2015
 13376                              <1> 	; Retro UNIX 386 v1 feature only !	
 13377                              <1> 	;
 13378                              <1> 	; INPUT:
 13379                              <1> 	;	AL = 0 for COM1
 13380                              <1> 	;	     1 for COM2
 13381                              <1> 	;	AH = Communication parameters (*)
 13382                              <1> 	; OUTPUT:
 13383                              <1> 	;	CL = Line status
 13384                              <1> 	;	CH = Modem status
 13385                              <1> 	;   If cf = 1 -> Error code in [u.error]
 13386                              <1> 	;		 'invalid parameter !' 
 13387                              <1> 	;		 	 or
 13388                              <1> 	;		 'device not ready !' error
 13389                              <1> 	;	
 13390                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13391                              <1> 	;	Bit	4	3	2	1	0
 13392                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13393                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13394                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13395                              <1> 	;		11 = even
 13396                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13397                              <1> 	;		Retro UNIX 386 v1 feature only !
 13398                              <1> 	;	Bit	7    6    5  | Baud rate
 13399                              <1> 	;		------------------------
 13400                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13401                              <1> 	;		0    0    1  | 9600 (12)
 13402                              <1> 	;		0    1    0  | 19200 (6) 
 13403                              <1> 	;		0    1	  1  | 38400 (3) 
 13404                              <1> 	;		1    0	  0  | 14400 (8)
 13405                              <1> 	;		1    0	  1  | 28800 (4)
 13406                              <1> 	;		1    1    0  | 57600 (2)
 13407                              <1> 	;		1    1    1  | 115200 (1) 
 13408                              <1> 	;
 13409                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13410                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13411                              <1> 	;
 13412                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13413                              <1> 	;
 13414 00003AFA 66BAF803            <1> 	mov	dx, 3F8h
 13415 00003AFE BB[E2700000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
 13416 00003B03 3C01                <1> 	cmp	al, 1
 13417 00003B05 776B                <1> 	ja 	short sp_invp_err
 13418 00003B07 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
 13419 00003B09 FECE                <1> 	dec	dh ; 2F8h
 13420 00003B0B 43                  <1> 	inc	ebx ; COM2 control byte offset
 13421                              <1> sp_setp1:
 13422                              <1> 	; 29/10/2015
 13423 00003B0C 8823                <1> 	mov	[ebx], ah
 13424 00003B0E 0FB6CC              <1> 	movzx 	ecx, ah
 13425 00003B11 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
 13426 00003B14 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
 13427 00003B17 8A81[813B0000]      <1> 	mov	al, [ecx+b_div_tbl]
 13428 00003B1D 6689C1              <1> 	mov	cx, ax
 13429 00003B20 E896FFFFFF          <1> 	call	sp_i3
 13430 00003B25 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
 13431 00003B28 A880                <1> 	test	al, 80h
 13432 00003B2A 740F                <1> 	jz	short sp_setp2
 13433 00003B2C C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
 13434                              <1> stp_dnr_err:
 13435 00003B2F C705[A7740000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
 13436 00003B37 0000                <1>
 13437                              <1> 	; CL = Line status, CH = Modem status
 13438 00003B39 F9                  <1> 	stc
 13439 00003B3A C3                  <1> 	retn
 13440                              <1> sp_setp2:
 13441 00003B3B 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
 13442 00003B3E 0F8649FFFFFF        <1>         jna     sp_i6 
 13443                              <1> 		      ; COM1 (3F?h)
 13444                              <1> sp_i5: 
 13445                              <1> 	; 07/11/2015
 13446                              <1> 	; 26/10/2015
 13447                              <1> 	; 29/06/2015
 13448                              <1> 	;
 13449                              <1> 	;; COM1 - enabling IRQ 4
 13450 00003B44 9C                  <1> 	pushf
 13451 00003B45 FA                  <1> 	cli
 13452 00003B46 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
 13453 00003B4A EC                  <1> 	in	al, dx 	   		; read register
 13454 00003B4B EB00                <1> 	JMP	$+2			; I/O DELAY
 13455 00003B4D 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13456 00003B4F EE                  <1> 	out	dx, al     		; write back to register
 13457 00003B50 EB00                <1> 	JMP	$+2			; I/O DELAY
 13458 00003B52 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
 13459 00003B56 EC                  <1> 	in	al, dx     		; read register
 13460 00003B57 EB00                <1> 	JMP	$+2			; I/O DELAY
 13461                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13462 00003B59 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13463 00003B5B EE                  <1> 	out	dx, al 	   		; write back to register
 13464 00003B5C EB00                <1> 	JMP	$+2        		; I/O DELAY
 13465 00003B5E E421                <1> 	in	al, 21h    		; read interrupt mask register
 13466 00003B60 EB00                <1> 	JMP	$+2			; I/O DELAY
 13467 00003B62 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
 13468 00003B64 E621                <1> 	out	21h, al    		; write back to register
 13469                              <1> 	;
 13470                              <1> 	; 23/10/2015
 13471 00003B66 B8[63390000]        <1> 	mov 	eax, com1_int
 13472 00003B6B A3[483F0000]        <1> 	mov	[com1_irq4], eax
 13473                              <1> 	; 26/10/2015
 13474 00003B70 9D                  <1> 	popf
 13475 00003B71 C3                  <1> 	retn
 13476                              <1> 
 13477                              <1> sp_invp_err:
 13478 00003B72 C705[A7740000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 13479 00003B7A 0000                <1>
 13480 00003B7C 31C9                <1> 	xor	ecx, ecx
 13481 00003B7E 49                  <1> 	dec	ecx ; 0FFFFh
 13482 00003B7F F9                  <1> 	stc
 13483 00003B80 C3                  <1> 	retn
 13484                              <1> 
 13485                              <1> ; 29/10/2015
 13486                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
 13487 00003B81 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
 13488                              <1> 
 13489                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (01/09/2014) 
 13490                              <1> epoch:
 13491                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13492                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1 - UNIX.ASM)
 13493                              <1> 	; 'epoch' procedure prototype: 
 13494                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13495                              <1> 	; 14/11/2012
 13496                              <1> 	; unixboot.asm (boot file configuration)
 13497                              <1> 	; version of "epoch" procedure in "unixproc.asm"
 13498                              <1> 	; 21/7/2012
 13499                              <1> 	; 15/7/2012
 13500                              <1> 	; 14/7/2012		
 13501                              <1> 	; Erdogan Tan - RETRO UNIX v0.1
 13502                              <1> 	; compute current date and time as UNIX Epoch/Time
 13503                              <1> 	; UNIX Epoch: seconds since 1/1/1970 00:00:00
 13504                              <1> 	;
 13505                              <1>         ;  ((Modified registers: EAX, EDX, ECX, EBX))  
 13506                              <1> 	;
 13507 00003B88 E81D010000          <1> 	call 	get_rtc_time		; Return Current Time
 13508 00003B8D 86E9                <1>         xchg 	ch,cl
 13509 00003B8F 66890D[E06D0000]    <1>         mov 	[hour], cx
 13510 00003B96 86F2                <1>         xchg 	dh,dl
 13511 00003B98 668915[E46D0000]    <1>         mov 	[second], dx
 13512                              <1> 	;
 13513 00003B9F E837010000          <1>         call 	get_rtc_date		; Return Current Date
 13514 00003BA4 86E9                <1>         xchg 	ch,cl
 13515 00003BA6 66890D[DA6D0000]    <1>         mov 	[year], cx
 13516 00003BAD 86F2                <1>         xchg 	dh,dl
 13517 00003BAF 668915[DC6D0000]    <1>         mov 	[month], dx
 13518                              <1> 	;
 13519 00003BB6 66B93030            <1> 	mov 	cx, 3030h
 13520                              <1> 	;
 13521 00003BBA A0[E06D0000]        <1> 	mov 	al, [hour] ; Hour
 13522                              <1>         	; AL <= BCD number)
 13523 00003BBF D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13524                              <1> 					; AH = AL / 10h
 13525                              <1> 					; AL = AL MOD 10h
 13526 00003BC1 D50A                <1>         aad 	; AX= AH*10+AL
 13527 00003BC3 A2[E06D0000]        <1> 	mov 	[hour], al
 13528 00003BC8 A0[E16D0000]        <1> 	mov 	al, [hour+1] ; Minute
 13529                              <1>         	; AL <= BCD number)
 13530 00003BCD D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13531                              <1> 					; AH = AL / 10h
 13532                              <1> 					; AL = AL MOD 10h
 13533 00003BCF D50A                <1>         aad 	; AX= AH*10+AL
 13534 00003BD1 A2[E26D0000]        <1> 	mov 	[minute], al
 13535 00003BD6 A0[E46D0000]        <1> 	mov 	al, [second] ; Second
 13536                              <1>         	; AL <= BCD number)
 13537 00003BDB D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13538                              <1> 					; AH = AL / 10h
 13539                              <1> 					; AL = AL MOD 10h
 13540 00003BDD D50A                <1>         aad 	; AX= AH*10+AL
 13541 00003BDF A2[E46D0000]        <1> 	mov 	[second], al
 13542 00003BE4 66A1[DA6D0000]      <1> 	mov 	ax, [year] ; Year (century)
 13543 00003BEA 6650                <1>         push 	ax
 13544                              <1> 	   	; AL <= BCD number)
 13545 00003BEC D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13546                              <1> 					; AH = AL / 10h
 13547                              <1> 					; AL = AL MOD 10h
 13548 00003BEE D50A                <1>         aad 	; AX= AH*10+AL
 13549 00003BF0 B464                <1> 	mov 	ah, 100
 13550 00003BF2 F6E4                <1> 	mul 	ah
 13551 00003BF4 66A3[DA6D0000]      <1> 	mov 	[year], ax
 13552 00003BFA 6658                <1> 	pop	ax
 13553 00003BFC 88E0                <1> 	mov	al, ah
 13554                              <1>         	; AL <= BCD number)
 13555 00003BFE D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13556                              <1> 					; AH = AL / 10h
 13557                              <1> 					; AL = AL MOD 10h
 13558 00003C00 D50A                <1>         aad 	; AX= AH*10+AL
 13559 00003C02 660105[DA6D0000]    <1> 	add 	[year], ax
 13560 00003C09 A0[DC6D0000]        <1> 	mov 	al, [month] ; Month
 13561                              <1>            	; AL <= BCD number)
 13562 00003C0E D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13563                              <1> 					; AH = AL / 10h
 13564                              <1> 					; AL = AL MOD 10h
 13565 00003C10 D50A                <1>         aad 	; AX= AH*10+AL
 13566 00003C12 A2[DC6D0000]        <1> 	mov 	[month], al	
 13567 00003C17 A0[DD6D0000]        <1>         mov     al, [month+1]      	; Day
 13568                              <1>            	; AL <= BCD number)
 13569 00003C1C D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13570                              <1> 					; AH = AL / 10h
 13571                              <1> 					; AL = AL MOD 10h
 13572 00003C1E D50A                <1>         aad 	; AX= AH*10+AL
 13573 00003C20 A2[DE6D0000]        <1>         mov     [day], al
 13574                              <1> 	
 13575                              <1> convert_to_epoch:
 13576                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit modification)
 13577                              <1> 	; 09/04/2013 (retro UNIX 8086 v1)
 13578                              <1> 	;
 13579                              <1> 	; ((Modified registers: EAX, EDX, EBX)) 
 13580                              <1> 	;
 13581                              <1> 	; Derived from DALLAS Semiconductor
 13582                              <1> 	; Application Note 31 (DS1602/DS1603)
 13583                              <1> 	; 6 May 1998
 13584 00003C25 29C0                <1> 	sub 	eax, eax
 13585 00003C27 66A1[DA6D0000]      <1> 	mov 	ax, [year]
 13586 00003C2D 662DB207            <1> 	sub 	ax, 1970
 13587 00003C31 BA6D010000          <1> 	mov 	edx, 365
 13588 00003C36 F7E2                <1> 	mul 	edx
 13589 00003C38 31DB                <1> 	xor 	ebx, ebx
 13590 00003C3A 8A1D[DC6D0000]      <1> 	mov 	bl, [month]
 13591 00003C40 FECB                <1> 	dec 	bl
 13592 00003C42 D0E3                <1> 	shl 	bl, 1
 13593                              <1> 	;sub	edx, edx
 13594 00003C44 668B93[E66D0000]    <1> 	mov 	dx, [EBX+DMonth]
 13595 00003C4B 8A1D[DE6D0000]      <1>         mov     bl, [day]
 13596 00003C51 FECB                <1> 	dec 	bl
 13597 00003C53 01D0                <1> 	add 	eax, edx
 13598 00003C55 01D8                <1> 	add 	eax, ebx
 13599                              <1> 			; EAX = days since 1/1/1970
 13600 00003C57 668B15[DA6D0000]    <1> 	mov 	dx, [year]
 13601 00003C5E 6681EAB107          <1> 	sub 	dx, 1969
 13602 00003C63 66D1EA              <1> 	shr 	dx, 1
 13603 00003C66 66D1EA              <1> 	shr 	dx, 1		
 13604                              <1> 		; (year-1969)/4
 13605 00003C69 01D0                <1> 	add 	eax, edx
 13606                              <1> 			; + leap days since 1/1/1970
 13607 00003C6B 803D[DC6D0000]02    <1> 	cmp 	byte [month], 2	; if past february
 13608 00003C72 7610                <1> 	jna 	short cte1
 13609 00003C74 668B15[DA6D0000]    <1> 	mov 	dx, [year]
 13610 00003C7B 6683E203            <1> 	and 	dx, 3 ; year mod 4
 13611 00003C7F 7503                <1> 	jnz 	short cte1		
 13612                              <1> 			; and if leap year
 13613 00003C81 83C001              <1> 	add 	eax, 1 	; add this year's leap day (february 29)
 13614                              <1> cte1: 			; compute seconds since 1/1/1970
 13615 00003C84 BA18000000          <1> 	mov 	edx, 24
 13616 00003C89 F7E2                <1> 	mul	edx
 13617 00003C8B 8A15[E06D0000]      <1> 	mov 	dl, [hour]
 13618 00003C91 01D0                <1> 	add 	eax, edx
 13619                              <1> 		; EAX = hours since 1/1/1970 00:00:00
 13620                              <1> 	;mov	ebx, 60
 13621 00003C93 B33C                <1> 	mov	bl, 60
 13622 00003C95 F7E3                <1> 	mul	ebx
 13623 00003C97 8A15[E26D0000]      <1> 	mov 	dl, [minute]
 13624 00003C9D 01D0                <1> 	add 	eax, edx
 13625                              <1> 		; EAX = minutes since 1/1/1970 00:00:00
 13626                              <1> 	;mov 	ebx, 60
 13627 00003C9F F7E3                <1> 	mul	ebx
 13628 00003CA1 8A15[E46D0000]      <1> 	mov 	dl, [second]
 13629 00003CA7 01D0                <1> 	add 	eax, edx
 13630                              <1>  		; EAX -> seconds since 1/1/1970 00:00:00
 13631 00003CA9 C3                  <1> 	retn
 13632                              <1> 
 13633                              <1> get_rtc_time:
 13634                              <1> 	; 15/03/2015
 13635                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13636                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13637                              <1> 	; INT 1Ah
 13638                              <1> 	; (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,	:
 13639                              <1> 	;       (CH) = HOURS IN BCD (00-23)			:
 13640                              <1> 	;       (CL) = MINUTES IN BCD (00-59)			:
 13641                              <1> 	;       (DH) = SECONDS IN BCD (00-59)			:
 13642                              <1> 	;       (DL) = DAYLIGHT SAVINGS ENABLE (00-01).		:
 13643                              <1> 	;								
 13644                              <1> RTC_20: 				; GET RTC TIME
 13645 00003CAA FA                  <1> 	cli
 13646 00003CAB E85CCFFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13647 00003CB0 7227                <1> 	JC	short RTC_29		; EXIT IF ERROR (CY= 1)
 13648                              <1> 
 13649 00003CB2 B000                <1> 	MOV	AL,CMOS_SECONDS 	; SET ADDRESS OF SECONDS
 13650 00003CB4 E83BCFFFFF          <1> 	CALL	CMOS_READ		; GET SECONDS
 13651 00003CB9 88C6                <1> 	MOV	DH,AL			; SAVE
 13652 00003CBB B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
 13653 00003CBD E832CFFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 13654 00003CC2 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
 13655 00003CC4 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
 13656 00003CC6 B002                <1> 	MOV	AL,CMOS_MINUTES 	; SET ADDRESS OF MINUTES
 13657 00003CC8 E827CFFFFF          <1> 	CALL	CMOS_READ		; GET MINUTES
 13658 00003CCD 88C1                <1> 	MOV	CL,AL			; SAVE
 13659 00003CCF B004                <1> 	MOV	AL,CMOS_HOURS		; SET ADDRESS OF HOURS
 13660 00003CD1 E81ECFFFFF          <1> 	CALL	CMOS_READ		; GET HOURS
 13661 00003CD6 88C5                <1> 	MOV	CH,AL			; SAVE
 13662 00003CD8 F8                  <1> 	CLC				; SET CY= 0
 13663                              <1> RTC_29:
 13664 00003CD9 FB                  <1> 	sti
 13665 00003CDA C3                  <1> 	RETn				; RETURN WITH RESULT IN CARRY FLAG
 13666                              <1> 
 13667                              <1> get_rtc_date:
 13668                              <1> 	; 15/03/2015
 13669                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13670                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13671                              <1> 	; INT 1Ah
 13672                              <1> 	; (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,:
 13673                              <1> 	;      (CH) = CENTURY IN BCD (19 OR 20) 		       :
 13674                              <1> 	;      (CL) = YEAR IN BCD (00-99)			       :
 13675                              <1> 	;      (DH) = MONTH IN BCD (01-12)			       :
 13676                              <1> 	;      (DL) = DAY IN BCD (01-31).		
 13677                              <1> 	;
 13678                              <1> RTC_40: 				; GET RTC DATE
 13679 00003CDB FA                  <1> 	cli
 13680 00003CDC E82BCFFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13681 00003CE1 7225                <1> 	JC	short RTC_49		; EXIT IF ERROR (CY= 1)
 13682                              <1> 
 13683 00003CE3 B007                <1> 	MOV	AL,CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
 13684 00003CE5 E80ACFFFFF          <1> 	CALL	CMOS_READ		; READ DAY OF MONTH
 13685 00003CEA 88C2                <1> 	MOV	DL,AL			; SAVE
 13686 00003CEC B008                <1> 	MOV	AL,CMOS_MONTH		; ADDRESS MONTH
 13687 00003CEE E801CFFFFF          <1> 	CALL	CMOS_READ		; READ MONTH
 13688 00003CF3 88C6                <1> 	MOV	DH,AL			; SAVE
 13689 00003CF5 B009                <1> 	MOV	AL,CMOS_YEAR		; ADDRESS YEAR
 13690 00003CF7 E8F8CEFFFF          <1> 	CALL	CMOS_READ		; READ YEAR
 13691 00003CFC 88C1                <1> 	MOV	CL,AL			; SAVE
 13692 00003CFE B032                <1> 	MOV	AL,CMOS_CENTURY 	; ADDRESS CENTURY LOCATION
 13693 00003D00 E8EFCEFFFF          <1> 	CALL	CMOS_READ		; GET CENTURY BYTE
 13694 00003D05 88C5                <1> 	MOV	CH,AL			; SAVE
 13695 00003D07 F8                  <1> 	CLC				; SET CY=0
 13696                              <1> RTC_49:
 13697 00003D08 FB                  <1> 	sti
 13698 00003D09 C3                  <1> 	RETn				; RETURN WITH RESULTS IN CARRY FLAG
 13699                              <1> 
 13700                              <1> set_date_time:
 13701                              <1> convert_from_epoch:
 13702                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13703                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 13704                              <1> 	; 'convert_from_epoch' procedure prototype: 
 13705                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13706                              <1> 	;
 13707                              <1> 	; ((Modified registers: EAX, EDX, ECX, EBX))	
 13708                              <1> 	;
 13709                              <1> 	; Derived from DALLAS Semiconductor
 13710                              <1> 	; Application Note 31 (DS1602/DS1603)
 13711                              <1> 	; 6 May 1998
 13712                              <1> 	;
 13713                              <1> 	; INPUT:
 13714                              <1> 	; EAX = Unix (Epoch) Time
 13715                              <1> 	;
 13716 00003D0A 31D2                <1> 	xor 	edx, edx
 13717 00003D0C B93C000000          <1> 	mov 	ecx, 60
 13718 00003D11 F7F1                <1> 	div	ecx
 13719                              <1> 	;mov 	[imin], eax   ; whole minutes
 13720                              <1> 			  ; since 1/1/1970
 13721 00003D13 668915[E46D0000]    <1> 	mov 	[second], dx  ; leftover seconds
 13722 00003D1A 29D2                <1> 	sub 	edx, edx
 13723 00003D1C F7F1                <1> 	div	ecx
 13724                              <1> 	;mov 	[ihrs], eax   ; whole hours
 13725                              <1> 	;		      ; since 1/1/1970
 13726 00003D1E 668915[E26D0000]    <1> 	mov 	[minute], dx  ; leftover minutes
 13727 00003D25 31D2                <1> 	xor	edx, edx
 13728                              <1> 	;mov 	cx, 24
 13729 00003D27 B118                <1> 	mov 	cl, 24
 13730 00003D29 F7F1                <1> 	div	ecx
 13731                              <1> 	;mov 	[iday], ax   ; whole days
 13732                              <1> 			     ; since 1/1/1970
 13733 00003D2B 668915[E06D0000]    <1> 	mov 	[hour], dx   ; leftover hours
 13734 00003D32 05DB020000          <1> 	add 	eax, 365+366 ; whole day since
 13735                              <1> 			     ; 1/1/1968 	
 13736                              <1> 	;mov 	[iday], ax
 13737 00003D37 50                  <1> 	push 	eax
 13738 00003D38 29D2                <1> 	sub	edx, edx
 13739 00003D3A B9B5050000          <1> 	mov 	ecx, (4*365)+1 ; 4 years = 1461 days
 13740 00003D3F F7F1                <1> 	div	ecx
 13741 00003D41 59                  <1> 	pop 	ecx
 13742                              <1> 	;mov 	[lday], ax   ; count of quadyrs (4 years)
 13743 00003D42 6652                <1> 	push 	dx
 13744                              <1> 	;mov 	[qday], dx   ; days since quadyr began
 13745 00003D44 6683FA3C            <1> 	cmp 	dx, 31 + 29  ; if past feb 29 then
 13746 00003D48 F5                  <1> 	cmc		     ; add this quadyr's leap day
 13747 00003D49 83D000              <1> 	adc 	eax, 0	     ; to # of qadyrs (leap days)
 13748                              <1> 	;mov 	[lday], ax   ; since 1968			  
 13749                              <1> 	;mov 	cx, [iday]
 13750 00003D4C 91                  <1> 	xchg 	ecx, eax     ; ECX = lday, EAX = iday		  
 13751 00003D4D 29C8                <1> 	sub 	eax, ecx     ; iday - lday
 13752 00003D4F B96D010000          <1> 	mov 	ecx, 365
 13753 00003D54 31D2                <1> 	xor	edx, edx
 13754                              <1> 	; EAX = iday-lday, EDX = 0
 13755 00003D56 F7F1                <1> 	div	ecx
 13756                              <1> 	;mov 	[iyrs], ax   ; whole years since 1968
 13757                              <1> 	;jday = iday - (iyrs*365) - lday
 13758                              <1> 	;mov [jday], dx      ; days since 1/1 of current year
 13759                              <1> 	;add	eax, 1968
 13760 00003D58 6605B007            <1> 	add 	ax, 1968     ; compute year
 13761 00003D5C 66A3[DA6D0000]      <1> 	mov 	[year], ax
 13762 00003D62 6689D1              <1> 	mov 	cx, dx
 13763                              <1> 	;mov 	dx, [qday]
 13764 00003D65 665A                <1> 	pop 	dx
 13765 00003D67 6681FA6D01          <1> 	cmp 	dx, 365	     ; if qday <= 365 and qday >= 60	
 13766 00003D6C 7709                <1> 	ja 	short cfe1   ; jday = jday +1
 13767 00003D6E 6683FA3C            <1> 	cmp 	dx, 60       ; if past 2/29 and leap year then
 13768 00003D72 F5                  <1>         cmc		     ; add a leap day to the # of whole
 13769 00003D73 6683D100            <1> 	adc 	cx, 0        ; days since 1/1 of current year
 13770                              <1> cfe1:			
 13771                              <1> 	;mov 	[jday], cx
 13772 00003D77 66BB0C00            <1> 	mov 	bx, 12       ; estimate month
 13773 00003D7B 66BA6E01            <1> 	mov 	dx, 366      ; mday, max. days since 1/1 is 365
 13774 00003D7F 6683E003            <1> 	and 	ax, 11b      ; year mod 4 (and dx, 3) 
 13775                              <1> cfe2:	; Month calculation  ; 0 to 11  (11 to 0)	
 13776 00003D83 6639D1              <1> 	cmp 	cx, dx       ; mday = # of days passed from 1/1
 13777 00003D86 731D                <1> 	jnb 	short cfe3
 13778 00003D88 664B                <1> 	dec 	bx           ; month = month - 1
 13779 00003D8A 66D1E3              <1> 	shl 	bx, 1 
 13780 00003D8D 668B93[E66D0000]    <1> 	mov 	dx, [EBX+DMonth] ; # elapsed days at 1st of month
 13781 00003D94 66D1EB              <1> 	shr 	bx, 1        ; bx = month - 1 (0 to 11)
 13782 00003D97 6683FB01            <1> 	cmp	bx, 1        ; if month > 2 and year mod 4  = 0	
 13783 00003D9B 76E6                <1> 	jna 	short cfe2   ; then mday = mday + 1
 13784 00003D9D 08C0                <1> 	or 	al, al       ; if past 2/29 and leap year then
 13785 00003D9F 75E2                <1> 	jnz 	short cfe2   ; add leap day (to mday)
 13786 00003DA1 6642                <1> 	inc 	dx           ; mday = mday + 1
 13787 00003DA3 EBDE                <1> 	jmp 	short cfe2
 13788                              <1> cfe3:
 13789 00003DA5 6643                <1> 	inc 	bx	     ; -> bx = month, 1 to 12
 13790 00003DA7 66891D[DC6D0000]    <1> 	mov 	[month], bx
 13791 00003DAE 6629D1              <1> 	sub 	cx, dx	     ; day = jday - mday + 1	
 13792 00003DB1 6641                <1> 	inc 	cx 			  
 13793 00003DB3 66890D[DE6D0000]    <1> 	mov 	[day], cx
 13794                              <1> 	
 13795                              <1> 	; eax, ebx, ecx, edx is changed at return
 13796                              <1> 	; output ->
 13797                              <1> 	; [year], [month], [day], [hour], [minute], [second]
 13798                              <1> 	
 13799                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13800                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 13801                              <1> set_date:
 13802 00003DBA A0[DB6D0000]        <1>         mov     al, [year+1]
 13803 00003DBF D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13804 00003DC1 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13805                              <1> 			     ; AL = AH * 10h + AL
 13806 00003DC3 88C5                <1> 	mov 	ch, al ; century (BCD)
 13807 00003DC5 A0[DA6D0000]        <1> 	mov 	al, [year]
 13808 00003DCA D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13809 00003DCC D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13810                              <1> 			     ; AL = AH * 10h + AL
 13811 00003DCE 88C1                <1> 	mov 	cl, al ; year (BCD)
 13812 00003DD0 A0[DC6D0000]        <1>         mov 	al, [month]
 13813 00003DD5 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13814 00003DD7 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13815                              <1> 			     ; AL = AH * 10h + AL
 13816 00003DD9 88C6                <1> 	mov 	dh, al ; month (BCD)
 13817 00003DDB A0[DE6D0000]        <1> 	mov 	al, [day]
 13818 00003DE0 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13819 00003DE2 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13820                              <1> 			     ; AL = AH * 10h + AL
 13821 00003DE4 88C6                <1> 	mov 	dh, al ; day (BCD)
 13822                              <1> 	; Set real-time clock date
 13823 00003DE6 E879000000          <1> 	call	set_rtc_date
 13824                              <1> set_time:
 13825                              <1>         ; Read real-time clock time 
 13826                              <1> 	; (get day light saving time bit status)
 13827 00003DEB FA                  <1>  	cli
 13828 00003DEC E81BCEFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13829                              <1> 	; cf = 1 -> al = 0
 13830 00003DF1 7207                <1>         jc      short stime1
 13831 00003DF3 B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
 13832 00003DF5 E8FACDFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 13833                              <1> stime1:
 13834 00003DFA FB                  <1> 	sti
 13835 00003DFB 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
 13836 00003DFD 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
 13837                              <1> 	; DL = 1 or 0 (day light saving time)
 13838                              <1> 	;	
 13839 00003DFF A0[E06D0000]        <1> 	mov 	al, [hour]
 13840 00003E04 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13841 00003E06 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13842                              <1> 			     ; AL = AH * 10h + AL
 13843 00003E08 88C5                <1> 	mov 	ch, al ; hour (BCD)
 13844 00003E0A A0[E26D0000]        <1>         mov     al, [minute]
 13845 00003E0F D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13846 00003E11 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13847                              <1> 			     ; AL = AH * 10h + AL
 13848 00003E13 88C1                <1> 	mov 	cl, al       ; minute (BCD)
 13849 00003E15 A0[E46D0000]        <1>         mov     al, [second]
 13850 00003E1A D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 13851 00003E1C D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 13852                              <1> 			     ; AL = AH * 10h + AL
 13853 00003E1E 88C6                <1> 	mov 	dh, al	     ; second (BCD)
 13854                              <1> 	; Set real-time clock time
 13855                              <1>  	; call	set_rtc_time
 13856                              <1> set_rtc_time:
 13857                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 13858                              <1> 	; 15/03/2015
 13859                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13860                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13861                              <1> 	; INT 1Ah
 13862                              <1> 	; (AH) = 03H  SET THE REAL TIME CLOCK USING,			:
 13863                              <1> 	;      (CH) = HOURS IN BCD (00-23)			       	:
 13864                              <1> 	;      (CL) = MINUTES IN BCD (00-59)			       	:
 13865                              <1> 	;      (DH) = SECONDS IN BCD (00-59)			       	:
 13866                              <1> 	;      (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.    :
 13867                              <1> 	;								:
 13868                              <1> 	;  NOTE: (DL)= 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED. :
 13869                              <1> 	;        (DL)= 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN  :
 13870                              <1> 	;         APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN :
 13871                              <1> 	;         OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.	  :
 13872                              <1> 	;
 13873                              <1> RTC_30: 				; SET RTC TIME
 13874 00003E20 FA                  <1> 	cli
 13875 00003E21 E8E6CDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13876 00003E26 7305                <1> 	JNC	short RTC_35		; GO AROUND IF CLOCK OPERATING
 13877 00003E28 E886000000          <1> 	CALL	RTC_STA 		; ELSE TRY INITIALIZING CLOCK
 13878                              <1> RTC_35:
 13879 00003E2D 88F4                <1> 	MOV	AH,DH			; GET TIME BYTE - SECONDS
 13880 00003E2F B000                <1> 	MOV	AL,CMOS_SECONDS 	; ADDRESS SECONDS
 13881 00003E31 E89E000000          <1> 	CALL	CMOS_WRITE		; UPDATE SECONDS
 13882 00003E36 88CC                <1> 	MOV	AH,CL			; GET TIME BYTE - MINUTES
 13883 00003E38 B002                <1> 	MOV	AL,CMOS_MINUTES 	; ADDRESS MINUTES
 13884 00003E3A E895000000          <1> 	CALL	CMOS_WRITE		; UPDATE MINUTES
 13885 00003E3F 88EC                <1> 	MOV	AH,CH			; GET TIME BYTE - HOURS
 13886 00003E41 B004                <1> 	MOV	AL,CMOS_HOURS		; ADDRESS HOURS
 13887 00003E43 E88C000000          <1> 	CALL	CMOS_WRITE		; UPDATE ADDRESS
 13888                              <1> 	;MOV	AX,X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 13889 00003E48 66B80B0B            <1> 	MOV	AX,257*CMOS_REG_B 	; 
 13890 00003E4C E8A3CDFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT TIME
 13891 00003E51 2462                <1> 	AND	AL,01100010B		; MASK FOR VALID BIT POSITIONS
 13892 00003E53 0C02                <1> 	OR	AL,00000010B		; TURN ON 24 HOUR MODE
 13893 00003E55 80E201              <1> 	AND	DL,00000001B		; USE ONLY THE DSE BIT
 13894 00003E58 08D0                <1> 	OR	AL,DL			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
 13895 00003E5A 86E0                <1> 	XCHG	AH,AL			; PLACE IN WORK REGISTER AND GET ADDRESS
 13896 00003E5C E873000000          <1> 	CALL	CMOS_WRITE		; SET NEW ALARM BITS
 13897 00003E61 F8                  <1> 	CLC				; SET CY= 0
 13898 00003E62 FB                  <1> 	sti
 13899 00003E63 C3                  <1> 	RETn				; RETURN WITH CY= 0
 13900                              <1> 
 13901                              <1> set_rtc_date:
 13902                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 13903                              <1> 	; 15/03/2015
 13904                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13905                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13906                              <1> 	; INT 1Ah
 13907                              <1> 	; (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING, :
 13908                              <1> 	;     (CH) = CENTURY IN BCD (19 OR 20)			   :
 13909                              <1> 	;     (CL) = YEAR IN BCD (00-99)			   :
 13910                              <1> 	;     (DH) = MONTH IN BCD (01-12)			   :
 13911                              <1> 	;     (DL) = DAY IN BCD (01-31).
 13912                              <1> 	;
 13913                              <1> RTC_50: 				; SET RTC DATE
 13914 00003E64 FA                  <1> 	cli
 13915 00003E65 E8A2CDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13916 00003E6A 7305                <1> 	JNC	short RTC_55		; GO AROUND IF NO ERROR
 13917 00003E6C E842000000          <1> 	CALL	RTC_STA 		; ELSE INITIALIZE CLOCK
 13918                              <1> RTC_55:
 13919 00003E71 66B80600            <1> 	MOV	AX,CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
 13920 00003E75 E85A000000          <1> 	CALL	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
 13921 00003E7A 88D4                <1> 	MOV	AH,DL			; GET DAY OF MONTH BYTE
 13922 00003E7C B007                <1> 	MOV	AL,CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
 13923 00003E7E E851000000          <1> 	CALL	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
 13924 00003E83 88F4                <1> 	MOV	AH,DH			; GET MONTH
 13925 00003E85 B008                <1> 	MOV	AL,CMOS_MONTH		; ADDRESS MONTH BYTE
 13926 00003E87 E848000000          <1> 	CALL	CMOS_WRITE		; WRITE MONTH REGISTER
 13927 00003E8C 88CC                <1> 	MOV	AH,CL			; GET YEAR BYTE
 13928 00003E8E B009                <1> 	MOV	AL,CMOS_YEAR		; ADDRESS YEAR REGISTER
 13929 00003E90 E83F000000          <1> 	CALL	CMOS_WRITE		; WRITE YEAR REGISTER
 13930 00003E95 88EC                <1> 	MOV	AH,CH			; GET CENTURY BYTE
 13931 00003E97 B032                <1> 	MOV	AL,CMOS_CENTURY 	; ADDRESS CENTURY BYTE
 13932 00003E99 E836000000          <1> 	CALL	CMOS_WRITE		; WRITE CENTURY LOCATION
 13933                              <1> 	;MOV	AX,X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 13934 00003E9E 66B80B0B            <1> 	MOV	AX,257*CMOS_REG_B 	; 
 13935 00003EA2 E84DCDFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT SETTINGS
 13936 00003EA7 247F                <1> 	AND	AL,07FH 		; CLEAR 'SET BIT'
 13937 00003EA9 86E0                <1> 	XCHG	AH,AL			; MOVE TO WORK REGISTER
 13938 00003EAB E824000000          <1> 	CALL	CMOS_WRITE		; AND START CLOCK UPDATING
 13939 00003EB0 F8                  <1> 	CLC				; SET CY= 0
 13940 00003EB1 FB                  <1> 	sti
 13941 00003EB2 C3                  <1> 	RETn				; RETURN CY=0
 13942                              <1> 
 13943                              <1> 	; 15/03/2015
 13944                              <1> RTC_STA:				; INITIALIZE REAL TIME CLOCK
 13945 00003EB3 B426                <1> 	mov	ah, 26h
 13946 00003EB5 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK
 13947 00003EB7 E818000000          <1> 	CALL	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
 13948 00003EBC B482                <1> 	mov	ah, 82h
 13949 00003EBE B00B                <1> 	mov 	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION
 13950 00003EC0 E80F000000          <1> 	CALL	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
 13951 00003EC5 B00C                <1> 	MOV	AL,CMOS_REG_C		; ADDRESS REGISTER C
 13952 00003EC7 E828CDFFFF          <1> 	CALL	CMOS_READ		; READ REGISTER C TO INITIALIZE
 13953 00003ECC B00D                <1> 	MOV	AL,CMOS_REG_D		; ADDRESS REGISTER D
 13954 00003ECE E821CDFFFF          <1> 	CALL	CMOS_READ		; READ REGISTER D TO INITIALIZE
 13955 00003ED3 C3                  <1> 	RETn
 13956                              <1> 
 13957                              <1> 	; 15/03/2015
 13958                              <1> 	; IBM PC/XT Model 286 BIOS source code ----- 10/06/85 (test4.asm)
 13959                              <1> CMOS_WRITE:			; WRITE (AH) TO LOCATION (AL)
 13960 00003ED4 9C                  <1> 	pushf			; SAVE INTERRUPT ENABLE STATUS AND FLAGS
 13961                              <1> 	;push	ax		; SAVE WORK REGISTER VALUES
 13962 00003ED5 D0C0                <1> 	rol	al, 1		; MOVE NMI BIT TO LOW POSITION
 13963 00003ED7 F9                  <1> 	stc			; FORCE NMI BIT ON IN CARRY FLAG
 13964 00003ED8 D0D8                <1> 	rcr	al, 1		; HIGH BIT ON TO DISABLE NMI - OLD IN CY
 13965 00003EDA FA                  <1> 	cli			; DISABLE INTERRUPTS
 13966 00003EDB E670                <1> 	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
 13967 00003EDD 88E0                <1> 	mov	al, ah		; GET THE DATA BYTE TO WRITE
 13968 00003EDF E671                <1> 	out	CMOS_DATA, al	; PLACE IN REQUESTED CMOS LOCATION
 13969 00003EE1 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
 13970 00003EE3 D0D8                <1> 	rcr	al, 1		; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
 13971 00003EE5 E670                <1> 	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
 13972 00003EE7 90                  <1> 	nop			; I/O DELAY
 13973 00003EE8 E471                <1> 	in	al, CMOS_DATA	; OPEN STANDBY LATCH
 13974                              <1> 	;pop	ax		; RESTORE WORK REGISTERS
 13975 00003EEA 9D                  <1> 	popf	
 13976 00003EEB C3                  <1> 	RETn
 13977                              <1> 
 13978                              <1> bf_init:
 13979                              <1> 	; 14/08/2015
 13980                              <1> 	; 02/07/2015
 13981                              <1> 	; 01/07/2015
 13982                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 13983                              <1> 	; Buffer (pointer) initialization !
 13984                              <1> 	; 
 13985                              <1> 	; 17/07/2013 - 24/07/2013
 13986                              <1> 	; Retro UNIX 8086 v1 (U9.ASM)
 13987                              <1> 	; (Retro UNIX 8086 v1 feature only !)
 13988                              <1> 	;
 13989 00003EEC BF[1A740000]        <1> 	mov	edi, bufp 
 13990 00003EF1 B8[08810000]        <1> 	mov	eax, buffer + (nbuf*520) 
 13991 00003EF6 29D2                <1> 	sub	edx, edx
 13992 00003EF8 FECA                <1> 	dec	dl
 13993 00003EFA 31C9                <1> 	xor	ecx, ecx
 13994 00003EFC 49                  <1> 	dec	ecx
 13995                              <1> bi0:
 13996 00003EFD 2D08020000          <1> 	sub	eax, 520 ; 8 header + 512 data
 13997 00003F02 AB                  <1> 	stosd
 13998 00003F03 89C6                <1> 	mov	esi, eax
 13999 00003F05 8916                <1> 	mov	[esi], edx ; 000000FFh
 14000                              <1> 			    ; Not a valid device sign
 14001 00003F07 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14002                              <1> 		      ; Not a valid block number sign 	 	
 14003 00003F0A 3D[D8740000]        <1> 	cmp	eax, buffer
 14004 00003F0F 77EC                <1> 	ja	short bi0
 14005 00003F11 B8[08810000]        <1> 	mov	eax, sb0
 14006 00003F16 AB                  <1> 	stosd
 14007 00003F17 B8[10830000]        <1> 	mov	eax, sb1
 14008 00003F1C AB                  <1> 	stosd
 14009 00003F1D 89C6                <1> 	mov	esi, eax ; offset sb1
 14010 00003F1F 8916                <1> 	mov	[esi], edx ; 000000FFh
 14011                              <1> 			    ; Not a valid device sign
 14012 00003F21 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14013                              <1> 		      ; Not a valid block number sign 	 
 14014                              <1> 	; 14/08/2015
 14015                              <1> 	;call 	rdev_init
 14016                              <1> 	;retn
 14017                              <1> 
 14018                              <1> rdev_init: ; root device, super block buffer initialization
 14019                              <1> 	; 14/08/2015
 14020                              <1> 	; Retro UNIX 386 v1 feature only !
 14021                              <1> 	;
 14022                              <1> 	; NOTE: Disk partitions (file systems), logical
 14023                              <1> 	; drive initialization, partition's start sector etc.
 14024                              <1> 	; will be coded here, later in 'ldrv_init'	
 14025                              <1> 
 14026 00003F24 0FB605[2A6B0000]    <1> 	movzx	eax, byte [boot_drv]
 14027                              <1> rdi_0:
 14028 00003F2B 3C80                <1> 	cmp	al, 80h
 14029 00003F2D 7202                <1> 	jb	short rdi_1
 14030 00003F2F 2C7E                <1> 	sub	al, 7Eh ; 80h = 2 (hd0), 81h = 3 (hd1)
 14031                              <1> rdi_1:
 14032 00003F31 A2[40740000]        <1> 	mov	[rdev], al
 14033 00003F36 BB[08810000]        <1>         mov	ebx, sb0 ; super block buffer
 14034 00003F3B 8903                <1> 	mov 	[ebx], eax
 14035 00003F3D B001                <1> 	mov	al, 1 ; eax = 1
 14036 00003F3F 894304              <1> 	mov	[ebx+4], eax ; super block address on disk
 14037 00003F42 E82B240000          <1> 	call 	diskio
 14038 00003F47 C3                  <1> 	retn
 14039                              <1> 
 14040                              <1> ; 23/10/2015
 14041                              <1> com1_irq4:
 14042 00003F48 [503F0000]          <1> 	dd dummy_retn
 14043                              <1> com2_irq3:
 14044 00003F4C [503F0000]          <1> 	dd dummy_retn
 14045                              <1> 
 14046                              <1> dummy_retn:
 14047 00003F50 C3                  <1> 	retn
 14048                                  %include 'u1.s'        ; 10/05/2015
 14049                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS1.INC
 14050                              <1> ; Last Modification: 23/11/2015
 14051                              <1> ; ----------------------------------------------------------------------------
 14052                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 14053                              <1> ; (v0.1 - Beginning: 11/07/2012)
 14054                              <1> ;
 14055                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 14056                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 14057                              <1> ; <Bell Laboratories (17/3/1972)>
 14058                              <1> ; <Preliminary Release of UNIX Implementation Document>
 14059                              <1> ;
 14060                              <1> ; Retro UNIX 8086 v1 - U1.ASM (12/07/2014) //// UNIX v1 -> u1.s
 14061                              <1> ;
 14062                              <1> ; ****************************************************************************
 14063                              <1> 
 14064                              <1> unkni: ; / used for all system calls
 14065                              <1> sysent: ; < enter to system call >
 14066                              <1> 	 ;19/10/2015
 14067                              <1> 	; 21/09/2015
 14068                              <1> 	; 01/07/2015
 14069                              <1> 	; 19/05/2015
 14070                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14071                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 14072                              <1> 	;
 14073                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
 14074                              <1> 	; The trap type is determined and an indirect jump is made to 
 14075                              <1> 	; the appropriate system call handler. If there is a trap inside
 14076                              <1> 	; the system a jump to panic is made. All user registers are saved 
 14077                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
 14078                              <1> 	; instructor is decoded to get the the system code part (see
 14079                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
 14080                              <1> 	; the indirect jump address is calculated. If a bad system call is
 14081                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
 14082                              <1> 	; is called. If the call is legitimate control passes to the
 14083                              <1> 	; appropriate system routine.
 14084                              <1> 	;
 14085                              <1> 	; Calling sequence:
 14086                              <1> 	;	Through a trap caused by any sys call outside the system.
 14087                              <1> 	; Arguments:
 14088                              <1> 	;	Arguments of particular system call.	
 14089                              <1> 	; ...............................................................
 14090                              <1> 	;	
 14091                              <1> 	; Retro UNIX 8086 v1 modification: 
 14092                              <1> 	;       System call number is in EAX register.
 14093                              <1> 	;
 14094                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14095                              <1> 	;	registers depending of function details.
 14096                              <1>   	;
 14097                              <1> 	; 16/04/2015
 14098 00003F51 368925[50740000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
 14099                              <1> 	; save user registers
 14100 00003F58 1E                  <1> 	push	ds
 14101 00003F59 06                  <1> 	push	es
 14102 00003F5A 0FA0                <1> 	push	fs
 14103 00003F5C 0FA8                <1> 	push	gs
 14104 00003F5E 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
 14105                              <1> 	;
 14106                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
 14107                              <1> 	; 	(ESPACE is size of space in kernel stack 
 14108                              <1> 	;	for saving/restoring user registers.)
 14109                              <1> 	;
 14110 00003F5F 50                  <1> 	push	eax ; 01/07/2015
 14111 00003F60 66B81000            <1> 	mov     ax, KDATA
 14112 00003F64 8ED8                <1>         mov     ds, ax
 14113 00003F66 8EC0                <1>         mov     es, ax
 14114 00003F68 8EE0                <1>         mov     fs, ax
 14115 00003F6A 8EE8                <1>         mov     gs, ax
 14116 00003F6C A1[78700000]        <1> 	mov	eax, [k_page_dir]
 14117 00003F71 0F22D8              <1> 	mov	cr3, eax
 14118 00003F74 58                  <1> 	pop	eax ; 01/07/2015
 14119                              <1> 	; 19/10/2015
 14120 00003F75 FC                  <1> 	cld
 14121                              <1> 	;
 14122 00003F76 FE05[4F740000]      <1> 	inc	byte [sysflg]
 14123                              <1> 		; incb sysflg / indicate a system routine is in progress
 14124 00003F7C FB                  <1>         sti 	; 18/01/2014
 14125 00003F7D 0F854DF9FFFF        <1> 	jnz     panic ; 24/05/2013
 14126                              <1> 		; beq 1f
 14127                              <1> 		; jmp panic ; / called if trap inside system
 14128                              <1> ;1:
 14129                              <1> 	; 16/04/2015
 14130 00003F83 A3[58740000]        <1> 	mov	[u.r0], eax
 14131 00003F88 8925[54740000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
 14132                              <1> 	;
 14133                              <1> 		; mov $s.syst+2,clockp
 14134                              <1> 		; mov r0,-(sp) / save user registers 
 14135                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
 14136                              <1> 			   ; / in u.r0
 14137                              <1> 		; mov r1,-(sp)
 14138                              <1> 		; mov r2,-(sp)
 14139                              <1> 		; mov r3,-(sp)
 14140                              <1> 		; mov r4,-(sp)
 14141                              <1> 		; mov r5,-(sp)
 14142                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
 14143                              <1> 		             ; / arithmetic unit
 14144                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
 14145                              <1> 		             ; / extended arithmetic unit
 14146                              <1> 		; mov sc,-(sp) / "step count" register for the extended
 14147                              <1> 		             ; / arithmetic unit
 14148                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
 14149                              <1> 		; mov 18.(sp),r0 / store pc in r0
 14150                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
 14151                              <1> 		; sub $sys,r0 / get xxx code
 14152 00003F8E C1E002              <1> 	shl	eax, 2
 14153                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
 14154 00003F91 3D94000000          <1> 	cmp	eax, end_of_syscalls - syscalls
 14155                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
 14156                              <1> 	;jnb	short badsys
 14157                              <1> 		; bhis badsys / yes, bad system call
 14158 00003F96 F5                  <1> 	cmc
 14159 00003F97 9C                  <1> 	pushf	
 14160 00003F98 50                  <1> 	push	eax
 14161 00003F99 8B2D[50740000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
 14162 00003F9F B0FE                <1> 	mov	al, 0FEh ; 11111110b
 14163 00003FA1 1400                <1> 	adc	al, 0 ; al = al + cf
 14164 00003FA3 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
 14165                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
 14166                              <1> 				 ; / and clear carry bit
 14167 00003FA6 5D                  <1> 	pop	ebp ; eax
 14168 00003FA7 9D                  <1> 	popf
 14169 00003FA8 0F8248010000        <1>         jc      badsys
 14170 00003FAE A1[58740000]        <1> 	mov	eax, [u.r0]
 14171                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
 14172 00003FB3 FFA5[B93F0000]      <1> 	jmp	dword [ebp+syscalls]
 14173                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
 14174                              <1> 		            ; / to proper system routine.
 14175                              <1> syscalls: ; 1:
 14176                              <1> 	; 21/09/2015
 14177                              <1> 	; 01/07/2015
 14178                              <1> 	; 16/04/2015 (32 bit address modification) 
 14179 00003FB9 [C0400000]          <1> 	dd sysrele	; / 0
 14180 00003FBD [66410000]          <1> 	dd sysexit 	; / 1
 14181 00003FC1 [8B420000]          <1> 	dd sysfork 	; / 2
 14182 00003FC5 [9E430000]          <1> 	dd sysread 	; / 3
 14183 00003FC9 [B9430000]          <1> 	dd syswrite 	; / 4
 14184 00003FCD [23440000]          <1> 	dd sysopen 	; / 5
 14185 00003FD1 [53450000]          <1> 	dd sysclose 	; / 6
 14186 00003FD5 [0D420000]          <1> 	dd syswait 	; / 7
 14187 00003FD9 [D3440000]          <1> 	dd syscreat 	; / 8
 14188 00003FDD [7A480000]          <1> 	dd syslink 	; / 9
 14189 00003FE1 [3C490000]          <1> 	dd sysunlink 	; / 10
 14190 00003FE5 [0C4A0000]          <1> 	dd sysexec 	; / 11
 14191 00003FE9 [73500000]          <1> 	dd syschdir 	; / 12
 14192 00003FED [57510000]          <1> 	dd systime 	; / 13
 14193 00003FF1 [0A450000]          <1> 	dd sysmkdir 	; / 14
 14194 00003FF5 [C5500000]          <1> 	dd syschmod 	; / 15
 14195 00003FF9 [27510000]          <1> 	dd syschown 	; / 16
 14196 00003FFD [8A510000]          <1> 	dd sysbreak 	; / 17
 14197 00004001 [E44D0000]          <1> 	dd sysstat 	; / 18
 14198 00004005 [4F520000]          <1> 	dd sysseek 	; / 19
 14199 00004009 [61520000]          <1> 	dd systell 	; / 20
 14200 0000400D [5E5D0000]          <1> 	dd sysmount 	; / 21
 14201 00004011 [105E0000]          <1> 	dd sysumount 	; / 22
 14202 00004015 [DF520000]          <1> 	dd syssetuid 	; / 23
 14203 00004019 [10530000]          <1> 	dd sysgetuid 	; / 24
 14204 0000401D [66510000]          <1> 	dd sysstime 	; / 25
 14205 00004021 [D3520000]          <1> 	dd sysquit 	; / 26
 14206 00004025 [C7520000]          <1> 	dd sysintr 	; / 27
 14207 00004029 [C04D0000]          <1> 	dd sysfstat 	; / 28
 14208 0000402D [6F450000]          <1> 	dd sysemt 	; / 29
 14209 00004031 [9D450000]          <1> 	dd sysmdate 	; / 30
 14210 00004035 [E8450000]          <1> 	dd sysstty 	; / 31
 14211 00004039 [67470000]          <1> 	dd sysgtty 	; / 32
 14212 0000403D [98450000]          <1> 	dd sysilgins 	; / 33
 14213 00004041 [4C660000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
 14214                              <1> 			     ; 11/06/2014
 14215 00004045 [7B660000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
 14216                              <1> 			     ; 01/07/2015
 14217 00004049 [52670000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
 14218                              <1> 			     ; 21/09/2015 - get last error number
 14219                              <1> end_of_syscalls:
 14220                              <1> 
 14221                              <1> error:
 14222                              <1> 	; 17/09/2015
 14223                              <1> 	; 03/09/2015
 14224                              <1> 	; 01/09/2015
 14225                              <1> 	; 09/06/2015
 14226                              <1> 	; 13/05/2015
 14227                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14228                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 14229                              <1> 	;
 14230                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
 14231                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
 14232                              <1> 	;
 14233                              <1> 	; INPUTS -> none
 14234                              <1> 	; OUTPUTS ->
 14235                              <1> 	;	processor status - carry (c) bit is set (means error)
 14236                              <1> 	;
 14237                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
 14238                              <1> 	; 	      Because, jumps to error procedure
 14239                              <1> 	;	      disrupts push-pop nesting balance)
 14240                              <1> 	;
 14241 0000404D 8B2D[50740000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
 14242 00004053 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
 14243                              <1> 				 ; (system call will return with cf = 1)
 14244                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
 14245                              <1> 		               ; / users stack
 14246                              <1> 	; 17/09/2015
 14247 00004057 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
 14248                              <1> 				 ; for saving/restoring user registers	
 14249                              <1> 	;cmp	ebp, [u.usp]
 14250                              <1> 	;je	short err0	
 14251 0000405A 892D[54740000]      <1> 	mov	[u.usp], ebp
 14252                              <1> ;err0:
 14253                              <1> 	; 01/09/2015
 14254 00004060 8B25[54740000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
 14255                              <1> 				    ; 10/04/2013
 14256                              <1> 				    ; (If an I/O error occurs during disk I/O,
 14257                              <1> 				    ; related procedures will jump to 'error'
 14258                              <1> 				    ; procedure directly without returning to 
 14259                              <1> 				    ; the caller procedure. So, stack pointer
 14260                              <1>                                     ; must be restored here.)
 14261                              <1> 	; 13/05/2015
 14262                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
 14263                              <1> 	;	'get last error' system call later. 	
 14264                              <1> 
 14265                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
 14266 00004066 C605[B9740000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
 14267                              <1> 
 14268                              <1> sysret: ; < return from system call>
 14269                              <1> 	; 10/09/2015
 14270                              <1> 	; 29/07/2015
 14271                              <1> 	; 25/06/2015
 14272                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14273                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 14274                              <1> 	;
 14275                              <1> 	; 'sysret' first checks to see if process is about to be 
 14276                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
 14277                              <1> 	; If not, following happens:	 
 14278                              <1> 	; 	1) The user's stack pointer is restored.
 14279                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
 14280                              <1> 	;	   i-node has been modified. If it has, it is written out
 14281                              <1> 	;	   via 'ppoke'.
 14282                              <1> 	;	3) If the super block has been modified, it is written out
 14283                              <1> 	;	   via 'ppoke'.				
 14284                              <1> 	;	4) If the dismountable file system's super block has been
 14285                              <1> 	;	   modified, it is written out to the specified device
 14286                              <1> 	;	   via 'ppoke'.
 14287                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
 14288                              <1> 	;	   during his execution. If so, 'tswap' is called to give
 14289                              <1> 	;	   another user a chance to run.
 14290                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
 14291                              <1> 	;	    (See 'sysrele' for conclusion.)		
 14292                              <1> 	;
 14293                              <1> 	; Calling sequence:
 14294                              <1> 	;	jump table or 'br sysret'
 14295                              <1> 	; Arguments: 
 14296                              <1> 	;	-	
 14297                              <1> 	; ...............................................................
 14298                              <1> 	;	
 14299                              <1> 	; ((AX=r1 for 'iget' input))
 14300                              <1> 	;	
 14301 0000406D 6631C0              <1> 	xor	ax, ax ; 04/05/2013
 14302                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
 14303 00004070 FEC0                <1> 	inc	al ; 04/05/2013
 14304 00004072 3805[A0740000]      <1> 	cmp	[u.bsys], al ; 1
 14305                              <1> 		; tstb u.bsys / is a process about to be terminated because
 14306 00004078 0F83E8000000        <1>         jnb     sysexit ; 04/05/2013
 14307                              <1> 		; bne sysexit / of an error? yes, go to sysexit
 14308                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
 14309                              <1> 		; mov u.sp,sp / no point stack to users stack
 14310 0000407E FEC8                <1> 	dec 	al ; mov ax, 0
 14311                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
 14312 00004080 E867160000          <1> 	call	iget
 14313                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
 14314                              <1> 		            ; / it is written out
 14315 00004085 6631C0              <1> 	xor 	ax, ax ; 0
 14316 00004088 3805[4D740000]      <1> 	cmp	[smod], al ; 0
 14317                              <1> 		; tstb	smod / has the super block been modified
 14318 0000408E 7614                <1> 	jna	short sysret1
 14319                              <1> 		; beq	1f / no, 1f
 14320 00004090 A2[4D740000]        <1> 	mov	[smod], al ; 0
 14321                              <1> 		; clrb smod / yes, clear smod
 14322 00004095 BB[08810000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
 14323 0000409A 66810B0002          <1>    	or	word [ebx], 200h ;;
 14324                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
 14325                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
 14326                              <1> 		      	      ; / output
 14327                              <1> 	; AX = 0
 14328 0000409F E8B3210000          <1> 	call 	poke ; 07/08/2013
 14329                              <1> 	; call	ppoke
 14330                              <1> 	; AX = 0
 14331                              <1> 		; jsr r0,ppoke / write out modified super block to disk
 14332                              <1> sysret1: ;1:
 14333 000040A4 3805[4E740000]      <1> 	cmp	[mmod], al ; 0
 14334                              <1> 		; tstb	mmod / has the super block for the dismountable file
 14335                              <1> 		           ; / system
 14336 000040AA 7614                <1> 	jna	short sysrel0
 14337                              <1> 		; beq 1f / been modified?  no, 1f
 14338 000040AC A2[4E740000]        <1> 	mov	[mmod], al ; 0	
 14339                              <1> 		; clrb	mmod / yes, clear mmod
 14340                              <1>         ;mov    ax, [mntd]
 14341                              <1>         ;;mov   al, [mdev] ; 26/04/2013
 14342 000040B1 BB[10830000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
 14343                              <1>         ;;mov	[ebx], al
 14344                              <1> 	;mov    [sb1], al
 14345                              <1> 		; movb	mntd,sb1 / set the I/O queue
 14346 000040B6 66810B0002          <1> 	or	word [ebx], 200h
 14347                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
 14348                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
 14349 000040BB E897210000          <1> 	call	poke ; 07/08/2013
 14350                              <1> 	;call	ppoke 
 14351                              <1> 		; jsr r0,ppoke / write it out to its device
 14352                              <1>         ;xor    al, al ; 26/04/2013       
 14353                              <1> ;1:
 14354                              <1> 		; tstb uquant / is the time quantum 0?
 14355                              <1> 		; bne 1f / no, don't swap it out
 14356                              <1> 
 14357                              <1> sysrele: ; < release >
 14358                              <1> 	; 14/10/2015
 14359                              <1> 	; 01/09/2015
 14360                              <1> 	; 24/07/2015
 14361                              <1> 	; 14/05/2015
 14362                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14363                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
 14364                              <1> 	;
 14365                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
 14366                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
 14367                              <1> 	; turns off the system flag. It then checked to see if there is
 14368                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
 14369                              <1> 	; the output gets flashed (see isintr) and interrupt action is
 14370                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
 14371                              <1> 	; the user, a rti is made.
 14372                              <1> 	;
 14373                              <1> 	; Calling sequence:
 14374                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
 14375                              <1> 	; Arguments:
 14376                              <1> 	;	-	
 14377                              <1> 	; ...............................................................
 14378                              <1> 	;	
 14379                              <1> 	; 23/02/2014 (swapret)
 14380                              <1> 	; 22/09/2013
 14381                              <1> sysrel0: ;1:
 14382 000040C0 803D[94740000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
 14383                              <1> 		; tstb uquant / is the time quantum 0?
 14384 000040C7 7705                <1>         ja      short swapret
 14385                              <1> 		; bne 1f / no, don't swap it out
 14386                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
 14387 000040C9 E894120000          <1> 	call	tswap
 14388                              <1> 		; jsr r0,tswap / yes, swap it out
 14389                              <1> ;
 14390                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
 14391                              <1> swapret: ;1:
 14392                              <1> 	; 10/09/2015
 14393                              <1> 	; 01/09/2015
 14394                              <1> 	; 14/05/2015
 14395                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
 14396                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
 14397                              <1> 	; cli
 14398                              <1> 	; 24/07/2015
 14399                              <1> 	;
 14400                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
 14401                              <1> 	;; mov	esp, [u.usp]
 14402                              <1> 
 14403                              <1> 	; 22/09/2013
 14404 000040CE E879140000          <1> 	call	isintr
 14405                              <1> 	; 20/10/2013
 14406 000040D3 7405                <1> 	jz	short sysrel1
 14407 000040D5 E875000000          <1> 	call	intract
 14408                              <1> 		; jsr r0,isintr / is there an interrupt from the user
 14409                              <1> 		;     br intract / yes, output gets flushed, take interrupt
 14410                              <1> 		               ; / action
 14411                              <1> sysrel1:
 14412 000040DA FA                  <1> 	cli ; 14/10/2015
 14413 000040DB FE0D[4F740000]      <1> 	dec	byte [sysflg]
 14414                              <1> 		; decb sysflg / turn system flag off
 14415 000040E1 A1[AB740000]        <1> 	mov     eax, [u.pgdir]
 14416 000040E6 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
 14417                              <1> 			  ; (others are different than kernel page tables) 
 14418                              <1> 	; 10/09/2015
 14419 000040E9 61                  <1> 	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
 14420                              <1> 		; mov (sp)+,sc / restore user registers
 14421                              <1> 		; mov (sp)+,mq
 14422                              <1> 		; mov (sp)+,ac
 14423                              <1> 		; mov (sp)+,r5
 14424                              <1> 		; mov (sp)+,r4
 14425                              <1> 		; mov (sp)+,r3
 14426                              <1> 		; mov (sp)+,r2
 14427                              <1> 	;
 14428 000040EA A1[58740000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
 14429 000040EF 0FA9                <1> 	pop	gs
 14430 000040F1 0FA1                <1> 	pop	fs
 14431 000040F3 07                  <1> 	pop	es
 14432 000040F4 1F                  <1> 	pop	ds
 14433 000040F5 CF                  <1> 	iretd	
 14434                              <1> 		; rti / no, return from interrupt
 14435                              <1> 
 14436                              <1> badsys:
 14437                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14438                              <1> 	; (Major Modification: 'core' dumping procedure in
 14439                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
 14440                              <1> 	;	has been changed to print 'Invalid System Call !'
 14441                              <1> 	;	message on the user's console tty.)
 14442                              <1> 	; (EIP, EAX values will be shown on screen with error message)
 14443                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
 14444                              <1> 	; (EAX = Function number)  
 14445                              <1> 	;
 14446 000040F6 FE05[A0740000]      <1> 	inc	byte [u.bsys]
 14447                              <1> 	;
 14448 000040FC 8B1D[50740000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
 14449 00004102 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
 14450 00004104 E8D4D7FFFF          <1> 	call	dwordtohex
 14451 00004109 8915[CE6D0000]      <1> 	mov	[bsys_msg_eip], edx
 14452 0000410F A3[D26D0000]        <1> 	mov	[bsys_msg_eip+4], eax
 14453 00004114 A1[58740000]        <1> 	mov	eax, [u.r0]
 14454 00004119 E8BFD7FFFF          <1> 	call	dwordtohex
 14455 0000411E 8915[BE6D0000]      <1> 	mov	[bsys_msg_eax], edx
 14456 00004124 A3[C26D0000]        <1> 	mov	[bsys_msg_eax+4], eax
 14457 00004129 31C0                <1> 	xor	eax, eax
 14458 0000412B C705[78740000]-     <1>         mov     dword [u.base], badsys_msg ; "Invalid System call !"
 14459 00004131 [9F6D0000]          <1>
 14460 00004135 8B1D[68740000]      <1> 	mov	ebx, [u.fofp]
 14461 0000413B 8903                <1> 	mov	[ebx], eax
 14462                              <1> 	;mov	eax, 1 ; inode number of console tty (for user)	
 14463 0000413D 40                  <1> 	inc	eax
 14464 0000413E C705[7C740000]3B00- <1> 	mov	dword [u.count], BSYS_M_SIZE
 14465 00004146 0000                <1>
 14466                              <1> 		; writei
 14467                              <1> 		; INPUTS ->
 14468                              <1> 		;    r1 - inode number
 14469                              <1> 		;    u.count - byte count to be written
 14470                              <1> 		;    u.base - points to user buffer
 14471                              <1> 		;    u.fofp - points to word with current file offset
 14472                              <1> 		; OUTPUTS ->
 14473                              <1> 		;    u.count - cleared
 14474                              <1> 		;    u.nread - accumulates total bytes passed back	
 14475                              <1> 		;
 14476                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
 14477 00004148 E875190000          <1> 	call	writei
 14478                              <1> 	;mov	eax, 1
 14479 0000414D EB17                <1> 	jmp	sysexit
 14480                              <1> 
 14481                              <1> 		; incb u.bsys / turn on the user's bad-system flag
 14482                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
 14483                              <1> 		; jsr r0,namei / get the i-number for the core image file
 14484                              <1> 		; br 1f / error
 14485                              <1> 		; neg r1 / negate the i-number to open the core image file
 14486                              <1> 		       ; / for writing
 14487                              <1> 		; jsr r0,iopen / open the core image file
 14488                              <1> 		; jsr r0,itrunc / free all associated blocks
 14489                              <1> 		; br 2f
 14490                              <1> ;1:
 14491                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
 14492                              <1> 		; jsr r0,maknod / make an i-node
 14493                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
 14494                              <1> ;2:
 14495                              <1> 		; mov $core,u.base / move address core to u.base
 14496                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
 14497                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
 14498                              <1> 		; clr u.off / clear user offset
 14499                              <1> 		; jsr r0,writei / write out the core image to the user
 14500                              <1> 		; mov $user,u.base / pt. u.base to user
 14501                              <1> 		; mov $64.,u.count / u.count = 64
 14502                              <1> 		; jsr r0,writei / write out all the user parameters
 14503                              <1> 		; neg r1 / make i-number positive
 14504                              <1> 		; jsr r0,iclose / close the core image file
 14505                              <1> 		; br sysexit /
 14506                              <1> ;3:
 14507                              <1> 		; <core\0\0>
 14508                              <1> 
 14509                              <1> intract: ; / interrupt action
 14510                              <1> 	; 14/10/2015
 14511                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14512                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
 14513                              <1> 	;
 14514                              <1> 	; Retro UNIX 8086 v1 modification !
 14515                              <1> 	; (Process/task switching and quit routine by using
 14516                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 14517                              <1> 	;
 14518                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
 14519                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
 14520                              <1> 	;		'intract' will jump to 'sysexit'.
 14521                              <1> 	;	    Intract will return to the caller 
 14522                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
 14523                              <1> 	; 14/10/2015
 14524 0000414F FB                  <1> 	sti
 14525                              <1> 	; 07/12/2013	
 14526 00004150 66FF05[98740000]    <1> 	inc 	word [u.quit]
 14527 00004157 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
 14528 00004159 66FF0D[98740000]    <1> 	dec	word [u.quit]
 14529                              <1> 	; 16/04/2015
 14530 00004160 C3                  <1> 	retn
 14531                              <1> intrct0:	
 14532 00004161 58                  <1> 	pop	eax ; call intract -> retn
 14533                              <1> 	;
 14534 00004162 31C0                <1> 	xor 	eax, eax
 14535 00004164 FEC0                <1> 	inc	al  ; mov ax, 1
 14536                              <1> ;;;
 14537                              <1> 	; UNIX v1 original 'intract' routine... 
 14538                              <1> 	; / interrupt action
 14539                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
 14540                              <1> 		; bne 1f / no, 1f
 14541                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
 14542                              <1> 	; 1: / now in user area
 14543                              <1> 		; mov r1,-(sp) / save r1
 14544                              <1> 		; mov u.ttyp,r1 
 14545                              <1> 			; / pointer to tty buffer in control-to r1
 14546                              <1> 		; cmpb 6(r1),$177
 14547                              <1> 			; / is the interrupt char equal to "del"
 14548                              <1> 		; beq 1f / yes, 1f
 14549                              <1> 		; clrb 6(r1) 
 14550                              <1> 		        ; / no, clear the byte 
 14551                              <1> 			; / (must be a quit character)
 14552                              <1> 		; mov (sp)+,r1 / restore r1
 14553                              <1> 		; clr u.quit / clear quit flag
 14554                              <1> 		; bis $20,2(sp) 
 14555                              <1> 		    	; / set trace for quit (sets t bit of 
 14556                              <1> 			; / ps-trace trap)
 14557                              <1> 		; rti   ;  / return from interrupt
 14558                              <1> 	; 1: / interrupt char = del
 14559                              <1> 		; clrb 6(r1) / clear the interrupt byte 
 14560                              <1> 			   ; / in the buffer
 14561                              <1> 		; mov (sp)+,r1 / restore r1
 14562                              <1> 		; cmp u.intr,$core / should control be 
 14563                              <1> 				; / transferred to loc core?
 14564                              <1> 		; blo 1f
 14565                              <1> 		; jmp *u.intr / user to do rti yes, 
 14566                              <1> 				; / transfer to loc core
 14567                              <1> 	; 1:
 14568                              <1> 		; sys 1 / exit
 14569                              <1> 
 14570                              <1> sysexit: ; <terminate process>
 14571                              <1> 	; 01/09/2015
 14572                              <1> 	; 31/08/2015
 14573                              <1> 	; 14/05/2015
 14574                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14575                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 14576                              <1> 	;
 14577                              <1> 	; 'sysexit' terminates a process. First each file that
 14578                              <1> 	; the process has opened is closed by 'flose'. The process
 14579                              <1> 	; status is then set to unused. The 'p.pid' table is then
 14580                              <1> 	; searched to find children of the dying process. If any of
 14581                              <1> 	; children are zombies (died by not waited for), they are
 14582                              <1> 	; set free. The 'p.pid' table is then searched to find the
 14583                              <1> 	; dying process's parent. When the parent is found, it is
 14584                              <1> 	; checked to see if it is free or it is a zombie. If it is
 14585                              <1> 	; one of these, the dying process just dies. If it is waiting
 14586                              <1> 	; for a child process to die, it notified that it doesn't 
 14587                              <1> 	; have to wait anymore by setting it's status from 2 to 1
 14588                              <1> 	; (waiting to active). It is awakened and put on runq by
 14589                              <1> 	; 'putlu'. The dying process enters a zombie state in which
 14590                              <1> 	; it will never be run again but stays around until a 'wait'
 14591                              <1> 	; is completed by it's parent process. If the parent is not
 14592                              <1> 	; found, process just dies. This means 'swap' is called with
 14593                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
 14594                              <1> 	; to write out the process and 'rswap' reads the new process
 14595                              <1> 	; over the one that dies..i.e., the dying process is 
 14596                              <1> 	; overwritten and destroyed.	
 14597                              <1>  	;
 14598                              <1> 	; Calling sequence:
 14599                              <1> 	;	sysexit or conditional branch.
 14600                              <1> 	; Arguments:
 14601                              <1> 	;	-	
 14602                              <1> 	; ...............................................................
 14603                              <1> 	;	
 14604                              <1> 	; Retro UNIX 8086 v1 modification: 
 14605                              <1> 	;       System call number (=1) is in EAX register.
 14606                              <1> 	;
 14607                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14608                              <1> 	;       registers depending of function details.
 14609                              <1> 	;
 14610                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
 14611                              <1> 	;
 14612                              <1> ; / terminate process
 14613                              <1> 	; AX = 1
 14614 00004166 6648                <1> 	dec 	ax ; 0
 14615 00004168 66A3[96740000]      <1> 	mov	[u.intr], ax ; 0
 14616                              <1> 		; clr u.intr / clear interrupt control word
 14617                              <1> 		; clr r1 / clear r1
 14618                              <1> 	; AX = 0
 14619                              <1> sysexit_1: ; 1:
 14620                              <1> 	; AX = File descriptor
 14621                              <1> 		; / r1 has file descriptor (index to u.fp list)
 14622                              <1> 		; / Search the whole list
 14623 0000416E E8070D0000          <1> 	call	fclose
 14624                              <1> 		; jsr r0,fclose / close all files the process opened
 14625                              <1> 	;; ignore error return
 14626                              <1> 		; br .+2 / ignore error return
 14627                              <1> 	;inc	ax
 14628 00004173 FEC0                <1> 	inc	al
 14629                              <1> 		; inc r1 / increment file descriptor
 14630                              <1> 	;cmp	ax, 10
 14631 00004175 3C0A                <1> 	cmp	al, 10
 14632                              <1> 		; cmp r1,$10. / end of u.fp list?
 14633 00004177 72F5                <1> 	jb	short sysexit_1
 14634                              <1> 		; blt 1b / no, go back
 14635 00004179 0FB61D[A1740000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 14636                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
 14637 00004180 88A3[D5710000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 14638                              <1> 		; clrb p.stat-1(r1) / free the process
 14639                              <1> 	;shl	bx, 1
 14640 00004186 D0E3                <1> 	shl	bl, 1
 14641                              <1> 		; asl r1 / use r1 for index into the below tables
 14642 00004188 668B8B[44710000]    <1> 	mov	cx, [ebx+p.pid-2]
 14643                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
 14644 0000418F 668B93[64710000]    <1> 	mov	dx, [ebx+p.ppid-2]
 14645                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
 14646                              <1> 	; xor 	bx, bx ; 0
 14647 00004196 30DB                <1> 	xor	bl, bl ; 0
 14648                              <1> 		; clr r2
 14649 00004198 31F6                <1> 	xor	esi, esi ; 0
 14650                              <1> 		; clr r5 / initialize reg
 14651                              <1> sysexit_2: ; 1:
 14652                              <1> 	        ; / find children of this dying process, 
 14653                              <1> 		; / if they are zombies, free them
 14654                              <1> 	;add	bx, 2
 14655 0000419A 80C302              <1> 	add	bl, 2
 14656                              <1> 		; add $2,r2 / search parent process table 
 14657                              <1> 		          ; / for dying process's name
 14658 0000419D 66398B[64710000]    <1> 	cmp	[ebx+p.ppid-2], cx
 14659                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
 14660 000041A4 7513                <1> 	jne	short sysexit_4
 14661                              <1> 		; bne 3f / no
 14662                              <1> 	;shr	bx, 1
 14663 000041A6 D0EB                <1> 	shr	bl, 1
 14664                              <1> 		; asr r2 / yes, it is a parent
 14665 000041A8 80BB[D5710000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
 14666                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
 14667                              <1> 				     ; / dying process a zombie
 14668 000041AF 7506                <1> 	jne	short sysexit_3 
 14669                              <1> 		; bne 2f / no
 14670 000041B1 88A3[D5710000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 14671                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
 14672                              <1> sysexit_3: ; 2:
 14673                              <1> 	;shr	bx, 1
 14674 000041B7 D0E3                <1> 	shl	bl, 1
 14675                              <1> 		; asl r2
 14676                              <1> sysexit_4: ; 3:
 14677                              <1> 		; / search the process name table 
 14678                              <1> 		; / for the dying process's parent
 14679 000041B9 663993[44710000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
 14680                              <1> 		; cmp p.pid-2(r2),r4 / found it?
 14681 000041C0 7502                <1> 	jne	short sysexit_5
 14682                              <1> 		; bne 3f / no
 14683 000041C2 89DE                <1> 	mov	esi, ebx
 14684                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
 14685                              <1> 		          ; / process # x2) in r5
 14686                              <1> sysexit_5: ; 3:
 14687                              <1> 	;cmp	bx, nproc + nproc
 14688 000041C4 80FB20              <1> 	cmp	bl, nproc + nproc
 14689                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
 14690 000041C7 72D1                <1> 	jb	short sysexit_2
 14691                              <1> 		; blt 1b / no, go back
 14692                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
 14693 000041C9 21F6                <1> 	and	esi, esi ; r5=r1
 14694 000041CB 7431                <1> 	jz	short sysexit_6
 14695                              <1> 		; beq 2f / no parent has been found. 
 14696                              <1> 		       ; / The process just dies
 14697 000041CD 66D1EE              <1> 	shr	si, 1
 14698                              <1> 		; asr r1 / set up index to p.stat
 14699 000041D0 8A86[D5710000]      <1> 	mov	al, [esi+p.stat-1]
 14700                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
 14701 000041D6 20C0                <1> 	and	al, al
 14702 000041D8 7424                <1> 	jz	short sysexit_6
 14703                              <1> 		; beq 2f / if its been freed, 2f
 14704 000041DA 3C03                <1> 	cmp	al, 3
 14705                              <1> 		; cmp r2,$3 / is parent a zombie?
 14706 000041DC 7420                <1> 	je	short sysexit_6
 14707                              <1> 		; beq 2f / yes, 2f
 14708                              <1> 	; BH = 0
 14709 000041DE 8A1D[A1740000]      <1> 	mov	bl, [u.uno]
 14710                              <1> 		; movb u.uno,r3 / move dying process's number to r3
 14711 000041E4 C683[D5710000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
 14712                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
 14713                              <1> 	; 05/02/2014
 14714 000041EB 3C01                <1> 	cmp	al, 1 ; SRUN
 14715 000041ED 740F                <1> 	je	short sysexit_6
 14716                              <1> 	;cmp	al, 2
 14717                              <1> 		; cmp r2,$2 / is the parent waiting for 
 14718                              <1> 			  ; / this child to die
 14719                              <1> 	;jne	short sysexit_6	
 14720                              <1> 		; bne 2f / yes, notify parent not to wait any more
 14721                              <1> 	; 05/02/2014
 14722                              <1> 	; p.stat = 2 --> waiting
 14723                              <1> 	; p.stat = 4 --> sleeping
 14724 000041EF C686[D5710000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
 14725                              <1> 	;dec	byte [esi+p.stat-1]
 14726                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
 14727 000041F6 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
 14728                              <1> 	; 
 14729                              <1> 	;mov	ebx, runq + 4
 14730                              <1> 		; mov $runq+4,r2 / on the runq
 14731 000041F9 E83C120000          <1> 	call	putlu
 14732                              <1> 		; jsr r0, putlu
 14733                              <1> sysexit_6: ; 2:
 14734                              <1> 	; 31/08/2015
 14735                              <1> 		; / the process dies
 14736 000041FE C605[A1740000]00    <1> 	mov	byte [u.uno], 0
 14737                              <1> 		; clrb u.uno / put zero as the process number, 
 14738                              <1> 	           ; / so "swap" will
 14739 00004205 E862110000          <1> 	call	swap
 14740                              <1> 		; jsr r0,swap / overwrite process with another process
 14741                              <1> hlt_sys:
 14742                              <1> 	;sti ; 18/01/2014
 14743                              <1> hlts0:
 14744 0000420A F4                  <1> 	hlt
 14745 0000420B EBFD                <1> 	jmp	short hlts0
 14746                              <1> 		; 0 / and thereby kill it; halt?
 14747                              <1> 
 14748                              <1> 
 14749                              <1> syswait: ; < wait for a processs to die >
 14750                              <1> 	; 17/09/2015
 14751                              <1> 	; 02/09/2015
 14752                              <1> 	; 01/09/2015
 14753                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14754                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
 14755                              <1> 	;
 14756                              <1> 	; 'syswait' waits for a process die. 
 14757                              <1> 	; It works in following way:
 14758                              <1> 	;    1) From the parent process number, the parent's 
 14759                              <1> 	; 	process name is found. The p.ppid table of parent
 14760                              <1> 	;	names is then searched for this process name.
 14761                              <1> 	;	If a match occurs, r2 contains child's process
 14762                              <1> 	;	number. The child status is checked to see if it is
 14763                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
 14764                              <1> 	;	If it is, the child process is freed and it's name
 14765                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
 14766                              <1> 	;	If the child is not a zombie, nothing happens and
 14767                              <1> 	;	the search goes on through the p.ppid table until
 14768                              <1> 	;	all processes are checked or a zombie is found.
 14769                              <1> 	;    2) If no zombies are found, a check is made to see if
 14770                              <1> 	;	there are any children at all. If there are none,
 14771                              <1> 	;	an error return is made. If there are, the parent's
 14772                              <1> 	;	status is set to 2 (waiting for child to die),
 14773                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
 14774                              <1> 	;	is made to wait on the next process.
 14775                              <1> 	;
 14776                              <1> 	; Calling sequence:
 14777                              <1> 	;	?
 14778                              <1> 	; Arguments:
 14779                              <1> 	;	-
 14780                              <1> 	; Inputs: - 
 14781                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
 14782                              <1> 	; ...............................................................
 14783                              <1> 	;				
 14784                              <1> 	
 14785                              <1> ; / wait for a process to die
 14786                              <1> 
 14787                              <1> syswait_0:
 14788 0000420D 0FB61D[A1740000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 14789                              <1> 		; movb u.uno,r1 / put parents process number in r1
 14790 00004214 D0E3                <1> 	shl	bl, 1
 14791                              <1> 	;shl	bx, 1
 14792                              <1> 		; asl r1 / x2 to get index into p.pid table
 14793 00004216 668B83[44710000]    <1> 	mov	ax, [ebx+p.pid-2]
 14794                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
 14795 0000421D 31F6                <1> 	xor	esi, esi
 14796                              <1> 		; clr r2
 14797 0000421F 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
 14798                              <1> 	;xor 	cl, cl
 14799                              <1> 		; clr r3 / initialize reg 3
 14800                              <1> syswait_1: ; 1:
 14801 00004221 6683C602            <1> 	add	si, 2
 14802                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
 14803                              <1> 			  ; / search table of parent processes 
 14804                              <1> 			  ; / for this process name
 14805 00004225 663B86[64710000]    <1> 	cmp	ax, [esi+p.ppid-2]
 14806                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
 14807                              <1> 			            ; / process number
 14808 0000422C 7535                <1> 	jne	short syswait_3
 14809                              <1> 		;bne 3f / branch if no match of parent process name
 14810                              <1> 	;inc	cx
 14811 0000422E FEC1                <1> 	inc	cl
 14812                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
 14813 00004230 66D1EE              <1> 	shr	si, 1
 14814                              <1> 		; asr r2 / r2/2 to get index to p.stat table
 14815                              <1> 	; The possible states ('p.stat' values) of a process are:
 14816                              <1> 	;	0 = free or unused
 14817                              <1> 	;	1 = active
 14818                              <1> 	;	2 = waiting for a child process to die
 14819                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
 14820 00004233 80BE[D5710000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
 14821                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
 14822 0000423A 7524                <1> 	jne	short syswait_2
 14823                              <1> 		; bne 2f / no, skip it
 14824 0000423C 88BE[D5710000]      <1> 	mov	[esi+p.stat-1], bh ; 0
 14825                              <1> 		; clrb p.stat-1(r2) / yes, free it
 14826 00004242 66D1E6              <1> 	shl	si, 1
 14827                              <1> 		; asl r2 / r2x2 to get index into p.pid table
 14828 00004245 0FB786[44710000]    <1> 	movzx	eax, word [esi+p.pid-2]
 14829 0000424C A3[58740000]        <1> 	mov	[u.r0], eax
 14830                              <1> 		; mov p.pid-2(r2),*u.r0 
 14831                              <1> 			      ; / put childs process name in (u.r0)
 14832                              <1> 	;
 14833                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
 14834                              <1> 	;
 14835                              <1> 	; Parent process ID -p.ppid- field (of the child process)
 14836                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
 14837                              <1> 	; system call loop from the application/program if it calls
 14838                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
 14839                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
 14840                              <1> 	;
 14841                              <1> 	; Note: syswait will return with error if there is not a
 14842                              <1> 	;       zombie or running process to wait.	
 14843                              <1> 	;
 14844 00004251 6629C0              <1> 	sub	ax, ax
 14845 00004254 668986[64710000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
 14846 0000425B E910FEFFFF          <1> 	jmp	sysret0 ; ax = 0
 14847                              <1> 	;
 14848                              <1> 	;jmp	sysret
 14849                              <1> 		; br sysret1 / return cause child is dead
 14850                              <1> syswait_2: ; 2:
 14851 00004260 66D1E6              <1> 	shl	si, 1
 14852                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
 14853                              <1> syswait_3: ; 3:
 14854 00004263 6683FE20            <1> 	cmp	si, nproc+nproc
 14855                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
 14856 00004267 72B8                <1> 	jb	short syswait_1
 14857                              <1> 		; blt 1b / no, continue search
 14858                              <1> 	;and	cx, cx
 14859 00004269 20C9                <1> 	and	cl, cl
 14860                              <1> 		; tst r3 / one gets here if there are no children 
 14861                              <1> 		       ; / or children that are still active
 14862                              <1> 	; 30/10/2013
 14863 0000426B 750B                <1> 	jnz	short syswait_4
 14864                              <1> 	;jz	error
 14865                              <1> 		; beq error1 / there are no children, error
 14866 0000426D 890D[58740000]      <1> 	mov	[u.r0], ecx ; 0
 14867 00004273 E9D5FDFFFF          <1> 	jmp	error
 14868                              <1> syswait_4:
 14869 00004278 8A1D[A1740000]      <1> 	mov	bl, [u.uno]
 14870                              <1> 		; movb u.uno,r1 / there are children so put 
 14871                              <1> 			      ; / parent process number in r1
 14872 0000427E FE83[D5710000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
 14873                              <1> 		; incb p.stat-1(r1) / it is waiting for 
 14874                              <1> 				  ; / other children to die
 14875                              <1> 	; 04/11/2013
 14876 00004284 E8E3100000          <1> 	call	swap
 14877                              <1> 		; jsr r0,swap / swap it out, because it's waiting
 14878 00004289 EB82                <1> 	jmp	syswait_0
 14879                              <1> 		; br syswait / wait on next process
 14880                              <1> 
 14881                              <1> sysfork: ; < create a new process >
 14882                              <1> 	; 18/09/2015
 14883                              <1> 	; 04/09/2015
 14884                              <1> 	; 02/09/2015
 14885                              <1> 	; 01/09/2015
 14886                              <1> 	; 28/08/2015
 14887                              <1> 	; 14/05/2015
 14888                              <1> 	; 10/05/2015
 14889                              <1> 	; 09/05/2015
 14890                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
 14891                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 14892                              <1> 	;
 14893                              <1> 	; 'sysfork' creates a new process. This process is referred
 14894                              <1> 	; to as the child process. This new process core image is
 14895                              <1> 	; a copy of that of the caller of 'sysfork'. The only
 14896                              <1> 	; distinction is the return location and the fact that (u.r0)
 14897                              <1> 	; in the old process (parent) contains the process id (p.pid)
 14898                              <1> 	; of the new process (child). This id is used by 'syswait'.
 14899                              <1> 	; 'sysfork' works in the following manner: 	
 14900                              <1> 	;    1) The process status table (p.stat) is searched to find
 14901                              <1> 	;	a process number that is unused. If none are found
 14902                              <1> 	;	an error occurs.
 14903                              <1> 	;    2) when one is found, it becomes the child process number
 14904                              <1> 	;	and it's status (p.stat) is set to active.
 14905                              <1> 	;    3) If the parent had a control tty, the interrupt 
 14906                              <1> 	;	character in that tty buffer is cleared.
 14907                              <1> 	;    4) The child process is put on the lowest priority run 
 14908                              <1> 	;	queue via 'putlu'.
 14909                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
 14910                              <1> 	;	it is a unique number) and is put in the child's unique
 14911                              <1> 	;	identifier; process id (p.pid).
 14912                              <1> 	;    6) The process name of the parent is then obtained and
 14913                              <1> 	;	placed in the unique identifier of the parent process
 14914                              <1> 	;	name is then put in 'u.r0'.	
 14915                              <1> 	;    7) The child process is then written out on disk by
 14916                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
 14917                              <1> 	;	and the child is born. (The child process is written 
 14918                              <1> 	;	out on disk/drum with 'u.uno' being the child process
 14919                              <1> 	;	number.)
 14920                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
 14921                              <1> 	;    9) The child process name is put in 'u.r0'.
 14922                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
 14923                              <1> 	;	create the return address for the parent process.
 14924                              <1> 	;   11) The 'u.fp' list as then searched to see what files
 14925                              <1> 	;	the parent has opened. For each file the parent has
 14926                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
 14927                              <1> 	;	to indicate that the child process also has opened
 14928                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
 14929                              <1> 	;
 14930                              <1> 	; Calling sequence:
 14931                              <1> 	;	from shell ?
 14932                              <1> 	; Arguments:
 14933                              <1> 	;	-
 14934                              <1> 	; Inputs: -
 14935                              <1> 	; Outputs: *u.r0 - child process name
 14936                              <1> 	; ...............................................................
 14937                              <1> 	;	
 14938                              <1> 	; Retro UNIX 8086 v1 modification: 
 14939                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
 14940                              <1> 	;	= process id of child a parent process returns
 14941                              <1> 	;	= process id of parent when a child process returns
 14942                              <1> 	;
 14943                              <1> 	;       In original UNIX v1, sysfork is called and returns as
 14944                              <1> 	;	in following manner: (with an example: c library, fork)
 14945                              <1> 	;	
 14946                              <1> 	;	1:
 14947                              <1> 	;		sys	fork
 14948                              <1> 	;			br 1f  / child process returns here
 14949                              <1> 	;		bes	2f     / parent process returns here
 14950                              <1> 	;		/ pid of new process in r0
 14951                              <1> 	;		rts	pc
 14952                              <1> 	;	2: / parent process condionally branches here
 14953                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
 14954                              <1> 	;		rts	pc
 14955                              <1> 	;
 14956                              <1> 	;	1: / child process brances here
 14957                              <1> 	;		clr	r0   / pid = 0 in child process
 14958                              <1> 	;		rts	pc
 14959                              <1> 	;
 14960                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
 14961                              <1> 	;		// pid = fork();
 14962                              <1> 	;		//
 14963                              <1> 	;		// pid == 0 in child process; 
 14964                              <1> 	;		// pid == -1 means error return
 14965                              <1> 	;		// in child, 
 14966                              <1> 	;		//	parents id is in par_uid if needed
 14967                              <1> 	;		
 14968                              <1> 	;		_fork:
 14969                              <1> 	;			mov	$.fork,eax
 14970                              <1> 	;			int	$0x30
 14971                              <1> 	;			jmp	1f
 14972                              <1> 	;			jnc	2f
 14973                              <1> 	;			jmp	cerror
 14974                              <1> 	;		1:
 14975                              <1> 	;			mov	eax,_par_uid
 14976                              <1> 	;			xor	eax,eax
 14977                              <1> 	;		2:
 14978                              <1> 	;			ret
 14979                              <1> 	;
 14980                              <1> 	;	In Retro UNIX 8086 v1,
 14981                              <1> 	;	'sysfork' returns in following manner:
 14982                              <1> 	;	
 14983                              <1> 	;		mov	ax, sys_fork
 14984                              <1> 	;		mov	bx, offset @f ; routine for child
 14985                              <1> 	;		int	20h
 14986                              <1> 	;		jc	error
 14987                              <1> 	;		
 14988                              <1> 	;	; Routine for parent process here (just after 'jc')
 14989                              <1> 	;		mov	word ptr [pid_of_child], ax
 14990                              <1> 	;		jmp	next_routine_for_parent	
 14991                              <1> 	;
 14992                              <1> 	;	@@: ; routine for child process here				
 14993                              <1> 	;		....	
 14994                              <1> 	;	NOTE: 'sysfork' returns to specified offset
 14995                              <1> 	;	       for child process by using BX input.
 14996                              <1> 	;	      (at first, parent process will return then 
 14997                              <1> 	;	      child process will return -after swapped in-
 14998                              <1> 	;	      'syswait' is needed in parent process
 14999                              <1> 	;	      if return from child process will be waited for.)
 15000                              <1> 	;	  				
 15001                              <1> 	
 15002                              <1> ; / create a new process
 15003                              <1> 	; EBX = return address for child process 
 15004                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
 15005 0000428B 31F6                <1> 	xor 	esi, esi
 15006                              <1> 		; clr r1
 15007                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
 15008 0000428D 46                  <1> 	inc	esi
 15009                              <1> 		; inc r1
 15010 0000428E 80BE[D5710000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
 15011                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
 15012 00004295 760B                <1> 	jna	short sysfork_2	
 15013                              <1> 		; beq 1f / it's unused so branch
 15014 00004297 6683FE10            <1> 	cmp	si, nproc
 15015                              <1> 		; cmp r1,$nproc / all processes checked
 15016 0000429B 72F0                <1> 	jb	short sysfork_1
 15017                              <1> 		; blt 1b / no, branch back
 15018                              <1> 	;
 15019                              <1> 	; Retro UNIX 8086 v1. modification:
 15020                              <1> 	;	Parent process returns from 'sysfork' to address 
 15021                              <1> 	;	which is just after 'sysfork' system call in parent
 15022                              <1> 	;	process. Child process returns to address which is put
 15023                              <1> 	;	in BX register by parent process for 'sysfork'. 
 15024                              <1> 	;
 15025                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
 15026                              <1> 		             ; / to old process return
 15027                              <1> 		; br error1 / no room for a new process
 15028 0000429D E9ABFDFFFF          <1> 	jmp	error
 15029                              <1> sysfork_2: ; 1:
 15030 000042A2 E84EEDFFFF          <1> 	call	allocate_page
 15031 000042A7 0F82A0FDFFFF        <1> 	jc	error
 15032 000042AD 50                  <1> 	push	eax   ; UPAGE (user structure page) address
 15033                              <1> 	; Retro UNIX 386 v1 modification!
 15034 000042AE E84BEFFFFF          <1> 	call	duplicate_page_dir
 15035                              <1> 		; EAX = New page directory 
 15036 000042B3 730B                <1> 	jnc	short sysfork_3
 15037 000042B5 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15038 000042B6 E812EFFFFF          <1> 	call 	deallocate_page
 15039 000042BB E98DFDFFFF          <1> 	jmp	error
 15040                              <1> sysfork_3:
 15041                              <1> 	; Retro UNIX 386 v1 modification !
 15042 000042C0 56                  <1> 	push	esi
 15043 000042C1 E81E110000          <1> 	call	wswap ; save current user (u) structure, user registers
 15044                              <1> 		      ; and interrupt return components (for IRET)
 15045 000042C6 8705[AB740000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
 15046 000042CC A3[AF740000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
 15047 000042D1 5E                  <1> 	pop	esi
 15048 000042D2 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15049                              <1> 		; [u.usp] = esp
 15050 000042D3 89F7                <1> 	mov	edi, esi
 15051 000042D5 66C1E702            <1> 	shl	di, 2
 15052 000042D9 8987[E2710000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
 15053 000042DF A3[A2740000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
 15054                              <1> 	; 28/08/2015
 15055 000042E4 0FB605[A1740000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
 15056                              <1> 		; movb u.uno,-(sp) / save parent process number
 15057 000042EB 89C7                <1> 	mov	edi, eax
 15058 000042ED 50                  <1>         push	eax ; ** 
 15059 000042EE 8A87[A5710000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
 15060                              <1> 	; 18/09/2015
 15061                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
 15062                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
 15063 000042F4 668986[A5710000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
 15064                              <1> 				   ; ah - reset child's wait channel	
 15065 000042FB 89F0                <1> 	mov	eax, esi
 15066 000042FD A2[A1740000]        <1> 	mov	[u.uno], al ; child process number
 15067                              <1> 		;movb r1,u.uno / set child process number to r1
 15068 00004302 FE86[D5710000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
 15069                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
 15070                              <1> 				; / process to active status
 15071                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
 15072                              <1> 			      ; / control tty buffer in r2
 15073                              <1>                 ; beq 2f / branch, if no such tty assigned
 15074                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
 15075                              <1> 	; 2:
 15076 00004308 53                  <1> 	push	ebx  ; * return address for the child process
 15077                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15078                              <1> 	; (Retro UNIX 8086 v1 modification!)
 15079                              <1> 		; mov $runq+4,r2
 15080 00004309 E82C110000          <1> 	call	putlu 
 15081                              <1>  		; jsr r0,putlu / put child process on lowest priority 
 15082                              <1> 			   ; / run queue
 15083 0000430E 66D1E6              <1> 	shl	si, 1
 15084                              <1> 		; asl r1 / multiply r1 by 2 to get index 
 15085                              <1> 		       ; / into p.pid table
 15086 00004311 66FF05[46740000]    <1> 	inc	word [mpid]
 15087                              <1> 		; inc mpid / increment m.pid; get a new process name
 15088 00004318 66A1[46740000]      <1> 	mov	ax, [mpid]
 15089 0000431E 668986[44710000]    <1> 	mov	[esi+p.pid-2], ax
 15090                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
 15091                              <1> 				    ; / in child process' name slot
 15092 00004325 5A                  <1> 	pop	edx  ; * return address for the child process
 15093                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15094 00004326 5B                  <1>   	pop	ebx  ; **
 15095                              <1> 	;mov	ebx, [esp] ; ** parent process number
 15096                              <1> 		; movb (sp),r2 / put parent process number in r2
 15097 00004327 66D1E3              <1> 	shl 	bx, 1
 15098                              <1> 		;asl r2 / multiply by 2 to get index into below tables
 15099                              <1> 	;movzx eax, word [ebx+p.pid-2]
 15100 0000432A 668B83[44710000]    <1> 	mov	ax, [ebx+p.pid-2]
 15101                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
 15102                              <1> 				   ; / process
 15103 00004331 668986[64710000]    <1> 	mov	[esi+p.ppid-2], ax
 15104                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
 15105                              <1> 			  ; / in parent process slot for child
 15106 00004338 A3[58740000]        <1> 	mov	[u.r0], eax	
 15107                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
 15108                              <1> 			     ; / at location where r0 was saved
 15109 0000433D 8B2D[50740000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
 15110 00004343 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
 15111                              <1> 			   ; * return address for the child process
 15112                              <1> 		; mov $sysret1,-(sp) /
 15113                              <1> 		; mov sp,u.usp / contents of sp at the time when 
 15114                              <1> 			      ; / user is swapped out
 15115                              <1> 		; mov $sstack,sp / point sp to swapping stack space
 15116                              <1> 	; 04/09/2015 - 01/09/2015
 15117                              <1> 	; [u.usp] = esp
 15118 00004346 68[6D400000]        <1> 	push	sysret ; ***
 15119 0000434B 8925[54740000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
 15120                              <1> 			     ; (for child process)	
 15121 00004351 31C0                <1> 	xor 	eax, eax
 15122 00004353 66A3[88740000]      <1> 	mov 	[u.ttyp], ax ; 0
 15123                              <1> 	;
 15124 00004359 E886100000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
 15125                              <1> 		;jsr r0,wswap / put child process out on drum
 15126                              <1> 		;jsr r0,unpack / unpack user stack
 15127                              <1> 		;mov u.usp,sp / restore user stack pointer
 15128                              <1> 		; tst (sp)+ / bump stack pointer
 15129                              <1> 	; Retro UNIX 386 v1 modification !
 15130 0000435E 58                  <1> 	pop	eax ; ***
 15131 0000435F 66D1E3              <1> 	shl	bx, 1
 15132 00004362 8B83[E2710000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
 15133 00004368 E8A0100000          <1> 	call	rswap ; restore parent process 'u' structure, 
 15134                              <1> 		      ; registers and return address (for IRET)
 15135                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
 15136 0000436D 0FB705[46740000]    <1>         movzx   eax, word [mpid]
 15137 00004374 A3[58740000]        <1> 	mov	[u.r0], eax
 15138                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
 15139                              <1> 			       ; / where r0 was saved
 15140                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
 15141                              <1> 			          ; / process return
 15142                              <1> 	;xor	ebx, ebx
 15143 00004379 31F6                <1> 	xor     esi, esi
 15144                              <1> 		;clr r1
 15145                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
 15146                              <1> 	      ; / opened by the parent process
 15147                              <1> 	; 01/09/2015
 15148                              <1> 	;xor	bh, bh
 15149                              <1> 	;mov 	bl, [esi+u.fp]
 15150 0000437B 8A86[5E740000]      <1> 	mov 	al, [esi+u.fp]
 15151                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
 15152                              <1>         ;or      bl, bl
 15153 00004381 08C0                <1> 	or	al, al
 15154 00004383 740D                <1> 	jz	short sysfork_5	
 15155                              <1> 		; beq 2f / file has not been opened by parent, 
 15156                              <1> 		       ; / so branch
 15157 00004385 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
 15158 00004387 F6E4                <1> 	mul	ah
 15159                              <1> 	;movzx	ebx, ax
 15160 00004389 6689C3              <1> 	mov	bx, ax
 15161                              <1> 	;shl     bx, 3
 15162                              <1> 		; asl r2 / multiply by 8
 15163                              <1>        		; asl r2 / to get index into fsp table
 15164                              <1>        		; asl r2
 15165 0000438C FE83[24720000]      <1>   	inc     byte [ebx+fsp-2]
 15166                              <1> 		; incb fsp-2(r2) / increment number of processes
 15167                              <1> 			     ; / using file, because child will now be
 15168                              <1> 			     ; / using this file
 15169                              <1> sysfork_5: ; 2:
 15170 00004392 46                  <1>         inc     esi
 15171                              <1> 		; inc r1 / get next open file
 15172 00004393 6683FE0A            <1>         cmp     si, 10
 15173                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
 15174                              <1> 			  ; / can be opened
 15175 00004397 72E2                <1> 	jb	short sysfork_4	
 15176                              <1> 		; blt 1b / check next entry
 15177 00004399 E9CFFCFFFF          <1> 	jmp	sysret
 15178                              <1> 		; br sysret1
 15179                              <1> 
 15180                              <1> sysread: ; < read from file >
 15181                              <1> 	; 13/05/2015
 15182                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15183                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15184                              <1> 	;
 15185                              <1> 	; 'sysread' is given a buffer to read into and the number of
 15186                              <1> 	; characters to be read. If finds the file from the file
 15187                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
 15188                              <1> 	; is returned from a successful open call (sysopen).
 15189                              <1> 	; The i-number of file is obtained via 'rw1' and the data
 15190                              <1> 	; is read into core via 'readi'.
 15191                              <1> 	;
 15192                              <1> 	; Calling sequence:
 15193                              <1> 	;	sysread; buffer; nchars
 15194                              <1> 	; Arguments:
 15195                              <1> 	;	buffer - location of contiguous bytes where 
 15196                              <1> 	;		 input will be placed.
 15197                              <1> 	;	nchars - number of bytes or characters to be read.
 15198                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15199                              <1> 	; Outputs: *u.r0 - number of bytes read.	
 15200                              <1> 	; ...............................................................
 15201                              <1> 	;				
 15202                              <1> 	; Retro UNIX 8086 v1 modification: 
 15203                              <1> 	;       'sysread' system call has three arguments; so,
 15204                              <1> 	;	* 1st argument, file descriptor is in BX register
 15205                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15206                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15207                              <1> 	;
 15208                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15209                              <1> 	;	to the user with number of bytes read. 
 15210                              <1> 	;
 15211 0000439E E83D000000          <1> 	call	rw1
 15212 000043A3 0F82A4FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
 15213                              <1> 		; jsr r0,rw1 / get i-number of file to be read into r1
 15214 000043A9 F6C480              <1> 	test	ah, 80h
 15215                              <1> 		; tst r1 / negative i-number?
 15216 000043AC 0F859BFCFFFF        <1> 	jnz	error
 15217                              <1> 		; ble error1 / yes, error 1 to read
 15218                              <1> 			   ; / it should be positive
 15219 000043B2 E815150000          <1> 	call	readi
 15220                              <1> 		; jsr r0,readi / read data into core
 15221 000043B7 EB18                <1> 	jmp	short rw0
 15222                              <1> 		; br 1f
 15223                              <1> syswrite: ; < write to file >
 15224                              <1> 	; 13/05/2015
 15225                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15226                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15227                              <1> 	;
 15228                              <1> 	; 'syswrite' is given a buffer to write onto an output file
 15229                              <1> 	; and the number of characters to write. If finds the file
 15230                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
 15231                              <1> 	; descriptor is returned from a successful open or create call
 15232                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
 15233                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
 15234                              <1> 	;
 15235                              <1> 	; Calling sequence:
 15236                              <1> 	;	syswrite; buffer; nchars
 15237                              <1> 	; Arguments:
 15238                              <1> 	;	buffer - location of contiguous bytes to be writtten.
 15239                              <1> 	;	nchars - number of characters to be written.
 15240                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15241                              <1> 	; Outputs: *u.r0 - number of bytes written.	
 15242                              <1> 	; ...............................................................
 15243                              <1> 	;				
 15244                              <1> 	; Retro UNIX 8086 v1 modification: 
 15245                              <1> 	;       'syswrite' system call has three arguments; so,
 15246                              <1> 	;	* 1st argument, file descriptor is in BX register
 15247                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15248                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15249                              <1> 	;
 15250                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15251                              <1> 	;	to the user with number of bytes written. 
 15252                              <1> 	;
 15253 000043B9 E822000000          <1> 	call	rw1
 15254 000043BE 0F8289FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
 15255                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
 15256 000043C4 F6C480              <1>         test	ah, 80h
 15257                              <1> 		; tst r1 / positive i-number ?
 15258 000043C7 744E                <1>         jz	short rw3 ; 13/05/2015
 15259                              <1> 	;jz	error
 15260                              <1> 		; bge error1 / yes, error 1 
 15261                              <1> 			   ; / negative i-number means write
 15262 000043C9 66F7D8              <1>         neg	ax
 15263                              <1> 		; neg r1 / make it positive
 15264 000043CC E8F1160000          <1> 	call	writei
 15265                              <1>         	; jsr r0,writei / write data
 15266                              <1> rw0: ; 1:
 15267 000043D1 A1[80740000]        <1>         mov	eax, [u.nread]
 15268 000043D6 A3[58740000]        <1> 	mov	[u.r0], eax
 15269                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
 15270                              <1> 				  ; / into (u.r0)
 15271 000043DB E98DFCFFFF          <1> 	jmp	sysret
 15272                              <1>         	; br sysret1
 15273                              <1> rw1:	
 15274                              <1> 	; 14/05/2015
 15275                              <1> 	; 13/05/2015
 15276                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15277                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
 15278                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
 15279                              <1> 	;
 15280                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
 15281                              <1> 				;(in the user's virtual memory space)
 15282                              <1> 	;mov	[u.count], edx 
 15283                              <1> 		; jsr r0,arg; u.base / get buffer pointer
 15284                              <1>         	; jsr r0,arg; u.count / get no. of characters
 15285                              <1> 	;;mov	eax, ebx ; file descriptor
 15286                              <1> 		; mov *u.r0,r1 / put file descriptor 
 15287                              <1> 		             ; / (index to u.fp table) in r1
 15288                              <1> 	; 13/05/2015
 15289 000043E0 C705[58740000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
 15290 000043E8 0000                <1>
 15291                              <1> 	;
 15292                              <1> 	;; call	getf
 15293                              <1>         ; eBX = File descriptor
 15294 000043EA E8D60A0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
 15295                              <1> 		; jsr r0,getf / get i-number of the file in r1
 15296                              <1> 	; AX = I-number of the file ; negative i-number means write
 15297                              <1> 	; 13/05/2015
 15298 000043EF 6683F801            <1> 	cmp 	ax, 1
 15299 000043F3 7217                <1> 	jb	short rw2
 15300                              <1> 	;
 15301 000043F5 890D[78740000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
 15302                              <1> 				;(in the user's virtual memory space)
 15303 000043FB 8915[7C740000]      <1> 	mov	[u.count], edx 
 15304                              <1> 	; 14/05/2015
 15305 00004401 C705[A7740000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
 15306 00004409 0000                <1>
 15307 0000440B C3                  <1> 	retn
 15308                              <1>         	; rts r0
 15309                              <1> rw2:
 15310                              <1> 	; 13/05/2015
 15311 0000440C C705[A7740000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 15312 00004414 0000                <1>
 15313 00004416 C3                  <1> 	retn
 15314                              <1> rw3: 
 15315                              <1> 	; 13/05/2015
 15316 00004417 C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 15317 0000441F 0000                <1>
 15318 00004421 F9                  <1> 	stc
 15319 00004422 C3                  <1> 	retn
 15320                              <1> 
 15321                              <1> sysopen: ;<open file>
 15322                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15323                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
 15324                              <1> 	;
 15325                              <1> 	; 'sysopen' opens a file in following manner:
 15326                              <1> 	;    1) The second argument in a sysopen says whether to
 15327                              <1> 	;	open the file ro read (0) or write (>0).
 15328                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
 15329                              <1> 	;    3) The file is opened by 'iopen'.
 15330                              <1> 	;    4) Next housekeeping is performed on the fsp table
 15331                              <1> 	;	and the user's open file list - u.fp.
 15332                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
 15333                              <1> 	;	b) An entry for the file is created in the fsp table.
 15334                              <1> 	;	c) The number of this entry is put on u.fp list.
 15335                              <1> 	;	d) The file descriptor index to u.fp list is pointed
 15336                              <1> 	;	   to by u.r0.
 15337                              <1> 	;
 15338                              <1> 	; Calling sequence:
 15339                              <1> 	;	sysopen; name; mode
 15340                              <1> 	; Arguments:
 15341                              <1> 	;	name - file name or path name
 15342                              <1> 	;	mode - 0 to open for reading
 15343                              <1> 	;	       1 to open for writing
 15344                              <1> 	; Inputs: (arguments)
 15345                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
 15346                              <1> 	;		  is put into r0's location on the stack.	
 15347                              <1> 	; ...............................................................
 15348                              <1> 	;				
 15349                              <1> 	; Retro UNIX 8086 v1 modification: 
 15350                              <1> 	;       'sysopen' system call has two arguments; so,
 15351                              <1> 	;	* 1st argument, name is pointed to by BX register
 15352                              <1> 	;	* 2nd argument, mode is in CX register
 15353                              <1> 	;
 15354                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15355                              <1> 	;	to the user with the file descriptor/number 
 15356                              <1> 	;	(index to u.fp list).
 15357                              <1> 	;
 15358                              <1> 	;call	arg2
 15359                              <1> 	; * name - 'u.namep' points to address of file/path name
 15360                              <1> 	;          in the user's program segment ('u.segmnt')
 15361                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15362                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15363                              <1> 	;          which is on top of stack.
 15364                              <1> 	;
 15365                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
 15366                              <1> 	;
 15367                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
 15368                              <1> 
 15369 00004423 891D[70740000]      <1> 	mov	[u.namep], ebx
 15370 00004429 6651                <1> 	push	cx
 15371 0000442B E8CC0A0000          <1> 	call	namei
 15372                              <1> 		; jsr r0,namei / i-number of file in r1
 15373                              <1>      	;and	ax, ax
 15374                              <1> 	;jz	error ; File not found
 15375 00004430 723B                <1> 	jc	short fnotfound ; 14/05/2015
 15376                              <1> 	;jc	error ; 27/05/2013
 15377                              <1> 		; br  error2 / file not found
 15378 00004432 665A                <1>    	pop	dx ; mode
 15379 00004434 6652                <1> 	push	dx
 15380                              <1> 	;or	dx, dx
 15381 00004436 08D2                <1> 	or	dl, dl
 15382                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
 15383                              <1> 		         ; / 0 means, open for read)
 15384 00004438 7403                <1> 	jz	short sysopen_0
 15385                              <1> 		; beq 1f / yes, leave i-number positive
 15386 0000443A 66F7D8              <1> 	neg	ax
 15387                              <1>         	; neg r1 / open for writing so make i-number negative
 15388                              <1> sysopen_0: ;1:
 15389 0000443D E8291A0000          <1> 	call	iopen
 15390                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
 15391 00004442 665A                <1> 	pop	dx
 15392                              <1> 	;and	dx, dx
 15393 00004444 20D2                <1> 	and	dl, dl
 15394                              <1>         	; tst (sp)+ / pop the stack and test the mode
 15395 00004446 7403                <1> 	jz	short sysopen_2
 15396                              <1>         	; beq op1 / is open for read op1
 15397                              <1> sysopen_1: ;op0:
 15398 00004448 66F7D8              <1> 	neg	ax
 15399                              <1>         	; neg r1 
 15400                              <1> 		     ;/ make i-number positive if open for writing [???]
 15401                              <1> 	;; NOTE: iopen always make i-number positive.
 15402                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
 15403                              <1> sysopen_2: ;op1:
 15404 0000444B 31F6                <1>         xor     esi, esi
 15405                              <1>         	; clr r2 / clear registers
 15406 0000444D 31DB                <1>         xor     ebx, ebx
 15407                              <1> 		; clr r3
 15408                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
 15409 0000444F 389E[5E740000]      <1>         cmp     [esi+u.fp], bl ; 0
 15410                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
 15411 00004455 7625                <1>         jna      short sysopen_4
 15412                              <1> 		; beq 1f / if byte in list is 0 branch
 15413 00004457 46                  <1>         inc     esi
 15414                              <1> 		; inc r2 / bump r2 so next byte can be checked
 15415 00004458 6683FE0A            <1>         cmp     si, 10
 15416                              <1> 		; cmp r2,$10. / reached end of list?
 15417 0000445C 72F1                <1> 	jb	short sysopen_3
 15418                              <1> 		; blt 1b / no, go back
 15419                              <1> toomanyf:
 15420                              <1> 	; 14/05/2015
 15421 0000445E C705[A7740000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
 15422 00004466 0000                <1>
 15423 00004468 E9E0FBFFFF          <1> 	jmp	error
 15424                              <1>         	; br error2 / yes, error (no files open)
 15425                              <1> fnotfound: 
 15426                              <1> 	; 14/05/2015
 15427 0000446D C705[A7740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
 15428 00004475 0000                <1>
 15429 00004477 E9D1FBFFFF          <1> 	jmp	error
 15430                              <1> 
 15431                              <1> sysopen_4: ; 1:
 15432 0000447C 6683BB[26720000]00  <1>         cmp     word [ebx+fsp], 0
 15433                              <1> 		; tst fsp(r3) / scan fsp entries
 15434 00004484 7610                <1>         jna     short sysopen_5
 15435                              <1> 		; beq 1f / if 0 branch
 15436                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
 15437 00004486 6683C30A            <1>         add     bx, 10 ; fsp structure size = 10 bytes/entry
 15438                              <1> 		; add $8.,r3 / add 8 to r3 
 15439                              <1> 			; / to bump it to next entry mfsp table
 15440 0000448A 6681FBF401          <1>         cmp     bx, nfiles*10
 15441                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
 15442 0000448F 72EB                <1> 	jb	short sysopen_4
 15443                              <1>        		; blt 1b / no, back
 15444 00004491 E9B7FBFFFF          <1> 	jmp	error
 15445                              <1>         	; br error2 / yes, error
 15446                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
 15447 00004496 668983[26720000]    <1>         mov     [ebx+fsp], ax
 15448                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
 15449                              <1> 			; / into next available entry in fsp table,
 15450 0000449D 668B3D[3E740000]    <1> 	mov	di, [cdev] ; word ? byte ?
 15451 000044A4 6689BB[28720000]    <1>         mov     [ebx+fsp+2], di ; device number
 15452                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
 15453 000044AB 31FF                <1>         xor	edi, edi
 15454 000044AD 89BB[2A720000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
 15455                              <1> 		; clr fsp+4(r3)
 15456 000044B3 6689BB[2E720000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
 15457                              <1>        		; clr fsp+6(r3) / clear the next two words
 15458 000044BA 89D8                <1>   	mov	eax, ebx
 15459 000044BC B30A                <1> 	mov	bl, 10
 15460 000044BE F6F3                <1> 	div	bl 
 15461                              <1> 		; asr r3
 15462                              <1> 		; asr r3 / divide by 8 
 15463                              <1> 		; asr r3 ; / to get number of the fsp entry-1
 15464 000044C0 FEC0                <1> 	inc	al
 15465                              <1>         	; inc r3 / add 1 to get fsp entry number
 15466 000044C2 8886[5E740000]      <1>         mov     [esi+u.fp], al
 15467                              <1> 		; movb r3,u.fp(r2) / move entry number into 
 15468                              <1> 			; / next available slot in u.fp list
 15469 000044C8 8935[58740000]      <1>         mov     [u.r0], esi
 15470                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
 15471                              <1> 			     ; / into r0 loc on stack
 15472 000044CE E99AFBFFFF          <1>         jmp	sysret
 15473                              <1> 		; br sysret2
 15474                              <1> 
 15475                              <1> 	;
 15476                              <1> 	; 'fsp' table (10 bytes/entry)
 15477                              <1> 	; bit 15				   bit 0
 15478                              <1> 	; ---|-------------------------------------------
 15479                              <1> 	; r/w|		i-number of open file
 15480                              <1> 	; ---|-------------------------------------------
 15481                              <1> 	;		   device number
 15482                              <1> 	; -----------------------------------------------
 15483                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 15484                              <1> 	; -----------------------------------------------
 15485                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 15486                              <1> 	; ----------------------|------------------------
 15487                              <1> 	;  flag that says file 	| number of processes
 15488                              <1> 	;   has been deleted	| that have file open 
 15489                              <1> 	; ----------------------|------------------------
 15490                              <1> 	;
 15491                              <1> 
 15492                              <1> syscreat: ; < create file >
 15493                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15494                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
 15495                              <1> 	;
 15496                              <1> 	; 'syscreat' called with two arguments; name and mode.
 15497                              <1> 	; u.namep points to name of the file and mode is put
 15498                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
 15499                              <1> 	; If the file aready exists, it's mode and owner remain 
 15500                              <1> 	; unchanged, but it is truncated to zero length. If the file
 15501                              <1> 	; did not exist, an i-node is created with the new mode via
 15502                              <1> 	; 'maknod' whether or not the file already existed, it is
 15503                              <1> 	; open for writing. The fsp table is then searched for a free
 15504                              <1> 	; entry. When a free entry is found, proper data is placed
 15505                              <1> 	; in it and the number of this entry is put in the u.fp list.
 15506                              <1> 	; The index to the u.fp (also know as the file descriptor)
 15507                              <1> 	; is put in the user's r0. 			
 15508                              <1> 	;
 15509                              <1> 	; Calling sequence:
 15510                              <1> 	;	syscreate; name; mode
 15511                              <1> 	; Arguments:
 15512                              <1> 	;	name - name of the file to be created
 15513                              <1> 	;	mode - mode of the file to be created
 15514                              <1> 	; Inputs: (arguments)
 15515                              <1> 	; Outputs: *u.r0 - index to u.fp list 
 15516                              <1> 	;		   (the file descriptor of new file)
 15517                              <1> 	; ...............................................................
 15518                              <1> 	;				
 15519                              <1> 	; Retro UNIX 8086 v1 modification: 
 15520                              <1> 	;       'syscreate' system call has two arguments; so,
 15521                              <1> 	;	* 1st argument, name is pointed to by BX register
 15522                              <1> 	;	* 2nd argument, mode is in CX register
 15523                              <1> 	;
 15524                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15525                              <1> 	;	to the user with the file descriptor/number 
 15526                              <1> 	;	(index to u.fp list).
 15527                              <1> 	;
 15528                              <1> 	;call	arg2
 15529                              <1> 	; * name - 'u.namep' points to address of file/path name
 15530                              <1> 	;          in the user's program segment ('u.segmnt')
 15531                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15532                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15533                              <1> 	;          which is on top of stack.
 15534                              <1> 	;
 15535                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
 15536                              <1> 			    ; / on stack
 15537 000044D3 891D[70740000]      <1> 	mov	[u.namep], ebx ; file name address
 15538 000044D9 6651                <1> 	push	cx ; mode
 15539 000044DB E81C0A0000          <1> 	call 	namei        	
 15540                              <1> 		; jsr r0,namei / get the i-number
 15541                              <1>         ;and	ax, ax
 15542                              <1> 	;jz	short syscreat_1	       	
 15543 000044E0 7214                <1> 	jc	short syscreat_1
 15544                              <1> 		; br  2f / if file doesn't exist 2f
 15545 000044E2 66F7D8              <1> 	neg 	ax
 15546                              <1>         	; neg r1 / if file already exists make i-number 
 15547                              <1> 		       ; / negative (open for writing)
 15548 000044E5 E881190000          <1> 	call	iopen
 15549                              <1>         	; jsr r0,iopen /
 15550 000044EA E832130000          <1> 	call	itrunc
 15551                              <1>         	; jsr r0,itrunc / truncate to 0 length
 15552 000044EF 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
 15553 000044F1 E952FFFFFF          <1>         jmp     sysopen_1
 15554                              <1>         	; br op0
 15555                              <1> syscreat_1: ; 2: / file doesn't exist
 15556 000044F6 6658                <1> 	pop	ax
 15557                              <1>         	; mov (sp)+,r1 / put the mode in r1
 15558 000044F8 30E4                <1> 	xor	ah, ah	
 15559                              <1>         	; bic $!377,r1 / clear upper byte
 15560 000044FA E8D00C0000          <1> 	call 	maknod
 15561                              <1>         	; jsr r0,maknod / make an i-node for this file
 15562 000044FF 66A1[8A740000]      <1> 	mov	ax, [u.dirbuf]
 15563                              <1>         	; mov u.dirbuf,r1 / put i-number 
 15564                              <1> 			        ; / for this new file in r1
 15565 00004505 E93EFFFFFF          <1>         jmp     sysopen_1
 15566                              <1>         	; br op0 / open the file
 15567                              <1> 
 15568                              <1> sysmkdir: ; < make directory >
 15569                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15570                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 15571                              <1> 	;
 15572                              <1> 	; 'sysmkdir' creates an empty directory whose name is
 15573                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
 15574                              <1> 	; The special entries '.' and '..' are not present.
 15575                              <1> 	; Errors are indicated if the directory already exists or		
 15576                              <1> 	; user is not the super user. 
 15577                              <1> 	;
 15578                              <1> 	; Calling sequence:
 15579                              <1> 	;	sysmkdir; name; mode
 15580                              <1> 	; Arguments:
 15581                              <1> 	;	name - points to the name of the directory
 15582                              <1> 	;	mode - mode of the directory
 15583                              <1> 	; Inputs: (arguments)
 15584                              <1> 	; Outputs: -
 15585                              <1> 	;    (sets 'directory' flag to 1; 
 15586                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
 15587                              <1> 	; ...............................................................
 15588                              <1> 	;				
 15589                              <1> 	; Retro UNIX 8086 v1 modification: 
 15590                              <1> 	;       'sysmkdir' system call has two arguments; so,
 15591                              <1> 	;	* 1st argument, name is pointed to by BX register
 15592                              <1> 	;	* 2nd argument, mode is in CX register
 15593                              <1> 	;
 15594                              <1> 		
 15595                              <1> ; / make a directory
 15596                              <1> 
 15597                              <1> 	;call	arg2
 15598                              <1> 	; * name - 'u.namep' points to address of file/path name
 15599                              <1> 	;          in the user's program segment ('u.segmnt')
 15600                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15601                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15602                              <1> 	;          which is on top of stack.
 15603                              <1> 
 15604                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
 15605                              <1> 			    ; / on stack
 15606 0000450A 891D[70740000]      <1> 	mov	[u.namep], ebx
 15607 00004510 6651                <1> 	push	cx ; mode
 15608 00004512 E8E5090000          <1> 	call	namei
 15609                              <1>         	; jsr r0,namei / get the i-number
 15610                              <1>         	;     br .+4 / if file not found branch around error
 15611                              <1>         ;xor 	ax, ax
 15612                              <1> 	;jnz	error
 15613 00004517 731C                <1> 	jnc	short dir_exists ; 14/05/2015
 15614                              <1> 	;jnc	error	
 15615                              <1> 		; br  error2 / directory already exists (error)
 15616 00004519 803D[9E740000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 15617                              <1>         	;tstb u.uid / is user the super user
 15618 00004520 7622                <1> 	jna	short dir_access_err ; 14/05/2015
 15619                              <1> 	;jna	error
 15620                              <1>         	;bne error2 / no, not allowed
 15621 00004522 6658                <1> 	pop	ax
 15622                              <1>         	;mov (sp)+,r1 / put the mode in r1
 15623 00004524 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
 15624                              <1>         	;bic $!317,r1 / all but su and ex
 15625                              <1> 	;or	ax , 4000h ; 1011111111111111b
 15626 00004528 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
 15627                              <1>         	;bis $40000,r1 / directory flag
 15628 0000452B E89F0C0000          <1> 	call	maknod
 15629                              <1>         	;jsr r0,maknod / make the i-node for the directory
 15630 00004530 E938FBFFFF          <1> 	jmp	sysret
 15631                              <1>         	;br sysret2 /
 15632                              <1> dir_exists:
 15633                              <1> 	; 14/05/2015
 15634 00004535 C705[A7740000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
 15635 0000453D 0000                <1>
 15636 0000453F E909FBFFFF          <1> 	jmp	error
 15637                              <1> dir_access_err:
 15638                              <1> 	; 14/05/2015
 15639 00004544 C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 15640 0000454C 0000                <1>
 15641 0000454E E9FAFAFFFF          <1> 	jmp	error
 15642                              <1> 
 15643                              <1> sysclose: ;<close file>
 15644                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15645                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
 15646                              <1> 	;
 15647                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
 15648                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
 15649                              <1> 	; is put in r1 and 'fclose' is called.
 15650                              <1> 	;
 15651                              <1> 	; Calling sequence:
 15652                              <1> 	;	sysclose
 15653                              <1> 	; Arguments:
 15654                              <1> 	;	-  
 15655                              <1> 	; Inputs: *u.r0 - file descriptor
 15656                              <1> 	; Outputs: -
 15657                              <1> 	; ...............................................................
 15658                              <1> 	;				
 15659                              <1> 	; Retro UNIX 8086 v1 modification:
 15660                              <1> 	;	 The user/application program puts file descriptor
 15661                              <1> 	;        in BX register as 'sysclose' system call argument.
 15662                              <1> 	; 	 (argument transfer method 1)
 15663                              <1> 
 15664                              <1> 	; / close the file
 15665                              <1> 	
 15666 00004553 89D8                <1> 	mov 	eax, ebx
 15667 00004555 E820090000          <1> 	call 	fclose
 15668                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
 15669                              <1> 		; jsr r0,fclose / close the file
 15670                              <1>                	; br error2 / unknown file descriptor
 15671                              <1> 		; br sysret2
 15672                              <1> 	; 14/05/2015
 15673 0000455A 0F830DFBFFFF        <1> 	jnc	sysret
 15674 00004560 C705[A7740000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 15675 00004568 0000                <1>
 15676 0000456A E9DEFAFFFF          <1> 	jmp	error
 15677                              <1> 
 15678                              <1> sysemt:
 15679                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15680                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
 15681                              <1> 	;
 15682                              <1> 	; Retro UNIX 8086 v1 modification: 
 15683                              <1> 	;	'Enable Multi Tasking'  system call instead 
 15684                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
 15685                              <1> 	;
 15686                              <1> 	; Retro UNIX 8086 v1 feature only!
 15687                              <1> 	;	Using purpose: Kernel will start without time-out
 15688                              <1> 	;	(internal clock/timer) functionality.
 15689                              <1> 	;	Then etc/init will enable clock/timer for
 15690                              <1> 	;	multi tasking. (Then it will not be disabled again
 15691                              <1> 	;	except hardware reset/restart.)
 15692                              <1> 	;
 15693                              <1> 
 15694 0000456F 803D[9E740000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
 15695                              <1> 	;ja	error
 15696 00004576 0F877AFBFFFF        <1> 	ja	badsys ; 14/05/2015
 15697                              <1> emt_0:
 15698 0000457C FA                  <1> 	cli
 15699 0000457D 21DB                <1> 	and	ebx, ebx
 15700 0000457F 7410                <1> 	jz	short emt_2
 15701                              <1> 	; Enable multi tasking -time sharing-
 15702 00004581 B8[83540000]        <1> 	mov	eax, clock
 15703                              <1> emt_1:
 15704 00004586 A3[D8070000]        <1> 	mov	[x_timer], eax
 15705 0000458B FB                  <1> 	sti
 15706 0000458C E9DCFAFFFF          <1> 	jmp	sysret
 15707                              <1> emt_2:
 15708                              <1> 	; Disable multi tasking -time sharing-
 15709 00004591 B8[E0070000]        <1> 	mov	eax, u_timer
 15710 00004596 EBEE                <1> 	jmp	short emt_1
 15711                              <1> 
 15712                              <1> 	; Original UNIX v1 'sysemt' routine
 15713                              <1> ;sysemt:
 15714                              <1>         ;
 15715                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
 15716                              <1> 			 ; / in loc 30
 15717                              <1>         ;cmp    30,$core / was the argument a lower address 
 15718                              <1> 			; / than core
 15719                              <1>         ;blo    1f / yes, rtssym
 15720                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
 15721                              <1> 			; / and less than "ecore"
 15722                              <1>         ;blo    2f / yes, sysret2
 15723                              <1> ;1:
 15724                              <1>         ;mov    $rtssym,30
 15725                              <1> ;2:
 15726                              <1>         ;br     sysret2
 15727                              <1> 
 15728                              <1> sysilgins:
 15729                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15730                              <1> 	; 03/06/2013
 15731                              <1> 	; Retro UNIX 8086 v1 modification: 
 15732                              <1> 	;	not a valid system call ! (not in use)
 15733                              <1> 	;
 15734 00004598 E959FBFFFF          <1> 	jmp	badsys
 15735                              <1> 	;jmp	error
 15736                              <1> 	;;jmp 	sysret
 15737                              <1> 
 15738                              <1> 	; Original UNIX v1 'sysemt' routine
 15739                              <1> ;sysilgins: / calculate proper illegal instruction trap address
 15740                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
 15741                              <1> 			  ;/ put it in loc 8.,
 15742                              <1>         ;cmp    10,$core / making it the illegal instruction 
 15743                              <1> 		       ; / trap address
 15744                              <1>         ;blo    1f / is the address a user core address?  
 15745                              <1> 		; / yes, go to 2f
 15746                              <1>         ;cmp    10,$ecore
 15747                              <1>         ;blo    2f
 15748                              <1> ;1:
 15749                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
 15750                              <1> 		    ; / instruction trap address for the system
 15751                              <1> ;2:
 15752                              <1>         ;br     sysret2 / return to the caller via 'sysret'
 15753                              <1> 
 15754                              <1> sysmdate: ; < change the modification time of a file >
 15755                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 15756                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 15757                              <1> 	;
 15758                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
 15759                              <1> 	; file into core. The user is checked if he is the owner 
 15760                              <1> 	; or super user. If he is neither an error occurs.
 15761                              <1> 	; 'setimod' is then called to set the i-node modification
 15762                              <1> 	; byte and the modification time, but the modification time
 15763                              <1> 	; is overwritten by whatever get put on the stack during
 15764                              <1> 	; a 'systime' system call. This calls are restricted to
 15765                              <1> 	; the super user.		
 15766                              <1> 	;
 15767                              <1> 	; Calling sequence:
 15768                              <1> 	;	sysmdate; name
 15769                              <1> 	; Arguments:
 15770                              <1> 	;	name - points to the name of file
 15771                              <1> 	; Inputs: (arguments)
 15772                              <1> 	; Outputs: -
 15773                              <1> 	; ...............................................................
 15774                              <1> 	;				
 15775                              <1> 	; Retro UNIX 8086 v1 modification: 
 15776                              <1> 	;	 The user/application program puts address 
 15777                              <1> 	;	 of the file name in BX register 
 15778                              <1> 	;	 as 'sysmdate' system call argument.
 15779                              <1> 	;
 15780                              <1> ; / change the modification time of a file
 15781                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
 15782 0000459D 891D[70740000]      <1>         mov	[u.namep], ebx
 15783 000045A3 E854090000          <1> 	call	namei
 15784                              <1> 		; jsr r0,namei / get its i-number
 15785 000045A8 0F82BFFEFFFF        <1>         jc	fnotfound ; file not found !
 15786                              <1> 	;jc	error       
 15787                              <1> 		; br error2 / no, such file
 15788 000045AE E839110000          <1> 	call	iget
 15789                              <1> 		; jsr r0,iget / get i-node into core
 15790 000045B3 A0[9E740000]        <1> 	mov	al, [u.uid]
 15791 000045B8 3A05[29710000]      <1> 	cmp	al, [i.uid]
 15792                              <1>         	; cmpb u.uid,i.uid / is user same as owner
 15793 000045BE 7413                <1> 	je	short mdate_1
 15794                              <1>         	; beq 1f / yes
 15795 000045C0 20C0                <1> 	and	al, al
 15796                              <1> 		; tstb u.uid / no, is user the super user
 15797                              <1> 	;jnz	error
 15798                              <1> 		; bne error2 / no, error
 15799 000045C2 740F                <1> 	jz	short mdate_1
 15800 000045C4 C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 15801 000045CC 0000                <1>
 15802 000045CE E97AFAFFFF          <1> 	jmp	error
 15803                              <1> mdate_1: ;1:
 15804 000045D3 E827120000          <1> 	call	setimod
 15805                              <1>         	; jsr r0,setimod / fill in modification data,
 15806                              <1> 		               ; / time etc.
 15807 000045D8 BE[C0700000]        <1> 	mov	esi, p_time
 15808 000045DD BF[40710000]        <1> 	mov	edi, i.mtim
 15809 000045E2 A5                  <1> 	movsd
 15810                              <1> 		; mov 4(sp),i.mtim / move present time to
 15811                              <1>         	; mov 2(sp),i.mtim+2 / modification time
 15812 000045E3 E985FAFFFF          <1>         jmp	sysret
 15813                              <1> 		; br sysret2
 15814                              <1> 
 15815                              <1> sysstty: ; < set tty status and mode >
 15816                              <1> 	; 17/11/2015
 15817                              <1> 	; 12/11/2015
 15818                              <1> 	; 29/10/2015
 15819                              <1> 	; 17/10/2015
 15820                              <1> 	; 13/10/2015
 15821                              <1> 	; 29/06/2015
 15822                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
 15823                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 15824                              <1> 	;
 15825                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
 15826                              <1> 	; whose file descriptor is in (u.r0).
 15827                              <1> 	;
 15828                              <1> 	; Calling sequence:
 15829                              <1> 	;	sysstty; arg
 15830                              <1> 	; Arguments:
 15831                              <1> 	;	arg - address of 3 consequitive words that contain
 15832                              <1> 	;	      the source of status data	
 15833                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
 15834                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 15835                              <1> 	; ...............................................................
 15836                              <1> 	;	
 15837                              <1> 	; Retro UNIX 8086 v1 modification: 
 15838                              <1> 	;	'sysstty' system call will set the tty
 15839                              <1> 	;	(clear keyboard buffer and set cursor position)
 15840                              <1> 	;	 in following manner:
 15841                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
 15842                              <1> 	;
 15843                              <1> 	; Inputs:
 15844                              <1> 	;	BX = 0 --> means
 15845                              <1> 	;	   If CL = FFh
 15846                              <1> 	;	      set cursor position for console tty, only 
 15847                              <1> 	;	      CH will be ignored (char. will not be written)	
 15848                              <1> 	;	   If CH = 0 (CL < FFh)
 15849                              <1> 	;	      set console tty for (current) process
 15850                              <1> 	;	      CL = tty number (0 to 9)
 15851                              <1> 	;	      (If CH = 0, character will not be written)			
 15852                              <1> 	;          If CH > 0 (CL < FFh)	
 15853                              <1> 	;             CL = tty number (0 to 9)
 15854                              <1> 	;	      CH = character will be written
 15855                              <1> 	;	        at requested cursor position (in DX)	
 15856                              <1> 	;	   DX = cursor position for tty number 0 to 7.	
 15857                              <1>   	;		(only tty number 0 to 7) 
 15858                              <1> 	;          DL = communication parameters (for serial ports) 
 15859                              <1> 	;	        (only for COM1 and COM2 serial ports)
 15860                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
 15861                              <1> 	;			or set cursor position	
 15862                              <1> 	;	   DH = 0FFh -> DL is not valid
 15863                              <1> 	;		do not set serial port parameters 
 15864                              <1> 	;		or do not set cursor position
 15865                              <1> 	;
 15866                              <1> 	;	BX > 0 --> points to name of tty
 15867                              <1> 	;    	   CH > 0 -->
 15868                              <1> 	;		CH = character will be written in current 
 15869                              <1> 	;            	cursor position (for tty number from 0 to 7)
 15870                              <1> 	;	     	or character will be sent to serial port
 15871                              <1> 	;	     	(for tty number 8 or 9)
 15872                              <1> 	;		CL = color of the character if tty number < 8.
 15873                              <1> 	;    	   CH = 0 --> Do not write a character, 
 15874                              <1> 	;		set mode (tty 8 to 9) or 
 15875                              <1> 	;		set current cursor positions (tty 0 to 7) only. 
 15876                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
 15877                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
 15878                              <1> 	;		(DL is not valid)
 15879                              <1> 	;	   DL = communication parameters 
 15880                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
 15881                              <1> 	; Outputs:
 15882                              <1> 	;	cf = 0 -> OK
 15883                              <1> 	;	     AL = tty number (0 to 9)
 15884                              <1> 	;	     AH = line status if tty number is 8 or 9
 15885                              <1> 	;	     AH = process number (of the caller) 	
 15886                              <1> 	;	cf = 1 means error (requested tty is not ready)
 15887                              <1> 	;	     AH = FFh if the tty is locked 
 15888                              <1> 	;		  (owned by another process)
 15889                              <1> 	;	        = process number (of the caller) 
 15890                              <1> 	;		  (if < FFh and tty number < 8)
 15891                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 15892                              <1> 	;	     AH = line status if tty number is 8 or 9
 15893                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
 15894                              <1> 	;
 15895                              <1> 	; 27/06/2015 (32 bit modifications)
 15896                              <1> 	; 14/01/2014
 15897 000045E8 31C0                <1> 	xor 	eax, eax
 15898 000045EA 6648                <1> 	dec	ax ; 17/10/2015
 15899 000045EC A3[58740000]        <1> 	mov	[u.r0], eax ; 0FFFFh
 15900 000045F1 21DB                <1> 	and	ebx, ebx
 15901 000045F3 0F85CB000000        <1>         jnz     sysstty_6
 15902                              <1> ; set console tty
 15903                              <1> 	; 29/10/2015
 15904                              <1> 	; 17/01/2014 
 15905 000045F9 80F909              <1> 	cmp	cl, 9
 15906 000045FC 7613                <1> 	jna	short sysstty_0
 15907                              <1> 	; 17/11/2015
 15908 000045FE 80F9FF              <1> 	cmp	cl, 0FFh
 15909 00004601 7202                <1> 	jb	short sysstty_13
 15910 00004603 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
 15911                              <1> sysstty_13:
 15912 00004605 8A1D[A1740000]      <1> 	mov	bl, [u.uno] ; process number
 15913 0000460B 8A8B[A5710000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
 15914                              <1> sysstty_0:
 15915                              <1> 	; 29/06/2015
 15916 00004611 6652                <1> 	push	dx
 15917 00004613 6651                <1> 	push	cx
 15918 00004615 30D2                <1> 	xor 	dl, dl	; sysstty call sign
 15919 00004617 88C8                <1> 	mov	al, cl
 15920 00004619 A2[58740000]        <1> 	mov	[u.r0], al ; tyy number (0 to 9)
 15921 0000461E E8E2180000          <1> 	call	ottyp
 15922 00004623 6659                <1> 	pop	cx
 15923 00004625 665A                <1> 	pop	dx
 15924                              <1> 	;
 15925 00004627 7257                <1> 	jc	short sysstty_pd_err
 15926                              <1> 	;
 15927 00004629 80F908              <1> 	cmp	cl, 8
 15928 0000462C 7222                <1> 	jb	short sysstty_2
 15929                              <1> 	;
 15930 0000462E 80FEFF              <1> 	cmp	dh, 0FFh
 15931 00004631 741D                <1> 	je	short sysstty_2
 15932                              <1> 		; set communication parameters for serial ports
 15933                              <1> 	; 29/10/2015
 15934 00004633 88D4                <1> 	mov	ah, dl ; communication parameters
 15935                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
 15936                              <1> 		;			 THRE int + RDA int 
 15937                              <1> 		; ah = 23h = 00100011b = 9600 baud,
 15938                              <1> 		;			 THRE int + RDA int 
 15939 00004635 28C0                <1> 	sub	al, al ; 0
 15940                              <1> 	; 12/07/2014
 15941 00004637 80F909              <1> 	cmp	cl, 9
 15942 0000463A 7202                <1> 	jb	short sysstty_1
 15943 0000463C FEC0                <1> 	inc	al
 15944                              <1> sysstty_1:
 15945 0000463E 6651                <1> 	push	cx
 15946                              <1> 	; 29/06/2015	
 15947 00004640 E8B5F4FFFF          <1> 	call 	sp_setp ; Set serial port communication parameters
 15948 00004645 66890D[59740000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
 15949                              <1> 			     ; Modem status (EAX bits 16 to 23)
 15950 0000464C 6659                <1> 	pop	cx
 15951 0000464E 7265                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 15952                              <1> sysstty_2:
 15953                              <1> 	; 17/01/2014
 15954 00004650 20ED                <1> 	and	ch, ch 	; set cursor position 
 15955                              <1> 			; or comm. parameters ONLY
 15956 00004652 750D                <1> 	jnz	short sysstty_3
 15957 00004654 0FB61D[A1740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 15958 0000465B 888B[A5710000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
 15959                              <1> sysstty_3:
 15960                              <1> 	; 16/01/2014
 15961 00004661 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
 15962                              <1> 	; 17/11/2015
 15963 00004663 B507                <1> 	mov 	ch, 7  ; Default color (light gray)
 15964 00004665 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
 15965 00004667 0F86C5000000        <1>         jna     sysstty_9
 15966                              <1> sysstty_12:
 15967                              <1> 	;; BX = 0, CL = 8 or CL = 9
 15968                              <1> 	; (Set specified serial port as console tty port)
 15969                              <1> 	; CH = character to be written
 15970                              <1> 	; 15/04/2014
 15971                              <1> 	; CH = 0 --> initialization only
 15972                              <1> 	; AL = character
 15973                              <1> 	; 26/06/2014
 15974 0000466D 880D[A6740000]      <1> 	mov	[u.ttyn], cl
 15975                              <1> 	; 12/07/2014
 15976 00004673 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
 15977 00004675 20C0                <1> 	and	al, al
 15978 00004677 7416                <1> 	jz	short sysstty_4 ; al = ch = 0
 15979                              <1>  	; 04/07/2014
 15980 00004679 E8951E0000          <1> 	call 	sndc
 15981                              <1> 	; 12/07/2014
 15982 0000467E EB1B                <1> 	jmp	short sysstty_5
 15983                              <1> sysstty_pd_err: ; 29/06/2015
 15984                              <1> 	; 'permission denied !' error
 15985 00004680 C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
 15986 00004688 0000                <1>
 15987 0000468A E9BEF9FFFF          <1> 	jmp	error
 15988                              <1> sysstty_4:
 15989                              <1> 	; 12/07/2014
 15990                              <1> 	;xchg 	ah, al	; al = 0 -> al = ah, ah = 0
 15991 0000468F 88E0                <1> 	mov	al, ah ; 29/06/2015
 15992 00004691 2C08                <1> 	sub	al, 8
 15993                              <1> 	; 27/06/2015
 15994 00004693 E85AF4FFFF          <1> 	call	sp_status ; get serial port status
 15995                              <1> 	; AL = Line status, AH = Modem status
 15996                              <1> 	; 12/11/2015
 15997 00004698 3C80                <1> 	cmp	al, 80h
 15998 0000469A F5                  <1> 	cmc
 15999                              <1> sysstty_5:
 16000 0000469B 66A3[59740000]      <1> 	mov	[u.r0+1], ax ; ah = line status
 16001                              <1> 		     ; EAX bits 16-23 = modem status	
 16002 000046A1 9C                  <1> 	pushf
 16003 000046A2 30D2                <1> 	xor	dl, dl ; sysstty call sign
 16004 000046A4 A0[A6740000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
 16005 000046A9 E86A190000          <1> 	call	cttyp
 16006 000046AE 9D                  <1> 	popf
 16007 000046AF 0F83B8F9FFFF        <1> 	jnc	sysret	; time out error 
 16008                              <1> 
 16009                              <1> sysstty_tmout_err:
 16010 000046B5 C705[A7740000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
 16011 000046BD 0000                <1>
 16012 000046BF E989F9FFFF          <1> 	jmp	error
 16013                              <1> sysstty_6:
 16014 000046C4 6652                <1> 	push	dx
 16015 000046C6 6651                <1> 	push	cx
 16016 000046C8 891D[70740000]      <1> 	mov	[u.namep], ebx
 16017 000046CE E829080000          <1> 	call	namei
 16018 000046D3 6659                <1> 	pop	cx
 16019 000046D5 665A                <1> 	pop	dx
 16020 000046D7 720E                <1> 	jc	short sysstty_inv_dn
 16021                              <1> 	;
 16022 000046D9 6683F813            <1> 	cmp	ax, 19  ; inode number of /dev/COM2
 16023 000046DD 7708                <1> 	ja	short sysstty_inv_dn ; 27/06/2015
 16024                              <1> 	;
 16025 000046DF 3C0A                <1> 	cmp	al, 10 ; /dev/tty0 .. /dev/tty7
 16026                              <1> 		       ; /dev/COM1, /dev/COM2
 16027 000046E1 7213                <1> 	jb	short sysstty_7
 16028 000046E3 2C0A                <1> 	sub	al, 10
 16029 000046E5 EB20                <1> 	jmp	short sysstty_8
 16030                              <1> sysstty_inv_dn: 
 16031                              <1> 	; 27/06/2015
 16032                              <1> 	; Invalid device name (not a tty) ! error
 16033                              <1> 	; (Device is not a tty or device name not found)
 16034 000046E7 C705[A7740000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 16035 000046EF 0000                <1>
 16036 000046F1 E957F9FFFF          <1> 	jmp	error 
 16037                              <1> sysstty_7:
 16038 000046F6 3C01                <1> 	cmp	al, 1 ; /dev/tty
 16039 000046F8 75ED                <1> 	jne	short sysstty_inv_dn ; 27/06/2015
 16040 000046FA 0FB61D[A1740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 16041 00004701 8A83[A5710000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
 16042                              <1> sysstty_8:	
 16043 00004707 A2[58740000]        <1> 	mov	[u.r0], al
 16044 0000470C 6652                <1> 	push	dx
 16045 0000470E 6650                <1> 	push	ax
 16046 00004710 6651                <1> 	push	cx	
 16047 00004712 E8EE170000          <1> 	call	ottyp
 16048 00004717 6659                <1> 	pop	cx
 16049 00004719 6658                <1> 	pop	ax
 16050 0000471B 665A                <1> 	pop	dx
 16051 0000471D 0F825DFFFFFF        <1>         jc      sysstty_pd_err ; 'permission denied !'
 16052                              <1> 	; 29/10/2015
 16053 00004723 86E9                <1> 	xchg 	ch, cl
 16054                              <1> 		; cl = character, ch = color code
 16055 00004725 86C1                <1> 	xchg	al, cl
 16056                              <1> 		; al = character, cl = tty number
 16057 00004727 80F907              <1> 	cmp	cl, 7
 16058 0000472A 0F873DFFFFFF        <1>         ja      sysstty_12
 16059                              <1> 	;
 16060                              <1> 	; 16/01/2014
 16061 00004730 30FF                <1> 	xor	bh, bh
 16062                              <1> 	;
 16063                              <1> sysstty_9: 	; tty 0 to tty 7
 16064                              <1> 	; al = character
 16065 00004732 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
 16066 00004735 740F                <1> 	je	short sysstty_10
 16067 00004737 6651                <1> 	push	cx
 16068 00004739 6650                <1> 	push	ax	
 16069                              <1> 	; movzx, ebx, cl
 16070 0000473B 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
 16071 0000473D E8BCCEFFFF          <1> 	call	set_cpos
 16072 00004742 6658                <1> 	pop	ax
 16073 00004744 6659                <1> 	pop	cx
 16074                              <1> sysstty_10: 
 16075                              <1> 	; 29/10/2015
 16076 00004746 08C0                <1> 	or	al, al ; character
 16077 00004748 740F                <1> 	jz      short sysstty_11 ; al = 0
 16078                              <1> 	; 17/11/2015
 16079 0000474A 3CFF                <1> 	cmp	al, 0FFh
 16080 0000474C 730B                <1> 	jnb	short sysstty_11
 16081                              <1> 		; ch > 0 and ch < FFh
 16082                              <1> 	; write a character at current cursor position
 16083 0000474E 88EC                <1> 	mov	ah, ch ; color/attribute
 16084                              <1> 	; 12/07/2014
 16085 00004750 6651                <1> 	push	cx
 16086 00004752 E8F0CFFFFF          <1> 	call	write_c_current
 16087 00004757 6659                <1> 	pop	cx
 16088                              <1> sysstty_11:
 16089                              <1> 	; 14/01/2014
 16090 00004759 30D2                <1> 	xor	dl, dl ; sysstty call sign
 16091                              <1> 	; 18/01/2014
 16092                              <1> 	;movzx	eax, cl ; 27/06/2015
 16093 0000475B 88C8                <1> 	mov	al, cl
 16094 0000475D E8B6180000          <1> 	call	cttyp
 16095 00004762 E906F9FFFF          <1> 	jmp	sysret
 16096                              <1> 
 16097                              <1> ; Original UNIX v1 'sysstty' routine:
 16098                              <1> ; gtty:
 16099                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
 16100                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
 16101                              <1> 	; 		/ r2 has source
 16102                              <1>         ;mov    r2,-(sp)
 16103                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
 16104                              <1> ;1: / flush the clist wait till typewriter is quiescent
 16105                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
 16106                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
 16107                              <1>         ;mov    $240,*$ps / set processor priority to 5
 16108                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
 16109                              <1>         ;       br .+4 / list empty, skip branch
 16110                              <1>         ;br     1b / get another character until list is empty
 16111                              <1>         ;mov    0b,r1 / move cc offset to r1
 16112                              <1>         ;inc    r1 / bump it for output clist
 16113                              <1>         ;tstb   cc(r1) / is it 0
 16114                              <1>         ;beq    1f / yes, no characters to output
 16115                              <1>  	;mov    r1,0f / no, put offset in sleep arg
 16116                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
 16117                              <1>         ;br     1b / try to calm it down again
 16118                              <1> ;1:
 16119                              <1>         ;mov    (sp)+,r1
 16120                              <1>         ;mov    (sp)+,r2 / restore registers
 16121                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
 16122                              <1>         ;beq    1f / if 0, 1f
 16123                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
 16124                              <1>         ;                   / control status register
 16125                              <1> ;1:
 16126                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
 16127                              <1>         ;beq    1f / if 0 1f
 16128                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
 16129                              <1> 	;		    / control status reg
 16130                              <1> ;1:
 16131                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
 16132                              <1>         ;jmp     sysret2 / return to user
 16133                              <1> 
 16134                              <1> sysgtty: ; < get tty status >
 16135                              <1> 	; 23/11/2015
 16136                              <1> 	; 29/10/2015
 16137                              <1> 	; 17/10/2015
 16138                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
 16139                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 16140                              <1> 	;
 16141                              <1> 	; 'sysgtty' gets the status of tty in question. 
 16142                              <1> 	; It stores in the three words addressed by it's argument
 16143                              <1> 	; the status of the typewriter whose file descriptor
 16144                              <1> 	; in (u.r0).
 16145                              <1> 	;
 16146                              <1> 	; Calling sequence:
 16147                              <1> 	;	sysgtty; arg
 16148                              <1> 	; Arguments:
 16149                              <1> 	;	arg - address of 3 words destination of the status
 16150                              <1> 	; Inputs: ((*u.r0 - file descriptor))
 16151                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 16152                              <1> 	; ...............................................................
 16153                              <1> 	;	
 16154                              <1> 	; Retro UNIX 8086 v1 modification: 
 16155                              <1> 	;	'sysgtty' system call will return status of tty
 16156                              <1> 	;	(keyboard, serial port and video page status)
 16157                              <1> 	;	 in following manner:
 16158                              <1> 	;
 16159                              <1> 	; Inputs:
 16160                              <1> 	;	BX = 0 --> means 
 16161                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
 16162                              <1> 	;	                 for (current) process
 16163                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
 16164                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
 16165                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
 16166                              <1> 	;	     CH > 0 -->	tty number + 1
 16167                              <1> 	;
 16168                              <1> 	;	BX > 0 --> points to name of tty
 16169                              <1> 	;	     CL = 0 --> return keyboard status
 16170                              <1> 	;	     CL = 1 --> return video page status
 16171                              <1> 	;	     CH = undefined		 
 16172                              <1> 	;
 16173                              <1> 	; Outputs:
 16174                              <1> 	;	cf = 0 ->
 16175                              <1> 	;
 16176                              <1> 	;	     AL = tty number from 0 to 9
 16177                              <1> 	;		  (0 to 7 is also the video page of the tty)	
 16178                              <1> 	;	     AH = 0 if the tty is free/unused
 16179                              <1> 	;	     AH = the process number of the caller 
 16180                              <1>  	;	     AH = FFh if the tty is locked by another process
 16181                              <1> 	;
 16182                              <1> 	;	  (if calling is for serial port status)
 16183                              <1> 	;	     BX = serial port status if tty number is 8 or 9
 16184                              <1> 	;		  (BH = modem status, BL = Line status)
 16185                              <1> 	;	     CX = 0FFFFh (if data is ready)
 16186                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
 16187                              <1> 	;
 16188                              <1> 	;	  (if calling is for keyboard status)
 16189                              <1> 	;	     BX = current character in tty/keyboard buffer
 16190                              <1> 	;		  (BH = scan code, BL = ascii code)
 16191                              <1> 	;		  (BX=0 if there is not a waiting character)
 16192                              <1> 	;	     CX  is undefined
 16193                              <1> 	;
 16194                              <1> 	;	  (if calling is for video page status)	
 16195                              <1> 	;	     BX = cursor position on the video page
 16196                              <1> 	;		  if tty number < 8
 16197                              <1> 	;		  (BH = row, BL = column)
 16198                              <1> 	;	     CX = current character (in cursor position)
 16199                              <1> 	;		  on the video page of the tty 
 16200                              <1> 	;		  if tty number < 8
 16201                              <1> 	;		  (CH = color, CL = character)
 16202                              <1> 	;	
 16203                              <1> 	;	cf = 1 means error (requested tty is not ready)
 16204                              <1> 	;
 16205                              <1> 	;	     AH = FFh if the caller is not owner of
 16206                              <1> 	;		  specified tty or console tty
 16207                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 16208                              <1> 	;	     BX, CX are undefined if cf = 1
 16209                              <1> 	;
 16210                              <1> 	;	  (If tty number is 8 or 9)
 16211                              <1> 	;	     AL = tty number 
 16212                              <1> 	;	     AH = the process number of the caller 
 16213                              <1> 	;	     BX = serial port status
 16214                              <1> 	;  		 (BH = modem status, BL = Line status)
 16215                              <1> 	;	     CX = 0
 16216                              <1> 	;
 16217                              <1> 		
 16218                              <1> gtty:   ; get (requested) tty number
 16219                              <1> 	; 17/10/2015
 16220                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 16221                              <1> 	; 30/05/2013 - 12/07/2014
 16222                              <1> 	; Retro UNIX 8086 v1 modification ! 
 16223                              <1> 	;
 16224                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
 16225                              <1> 	;
 16226                              <1> 	; 28/06/2015 (32 bit modifications)
 16227                              <1> 	; 16/01/2014
 16228 00004767 31C0                <1> 	xor 	eax, eax
 16229 00004769 6648                <1> 	dec	ax ; 17/10/2015
 16230 0000476B A3[58740000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
 16231 00004770 80F901              <1> 	cmp	cl, 1
 16232 00004773 760F                <1> 	jna	short sysgtty_0
 16233                              <1> sysgtty_invp:
 16234                              <1> 	; 28/06/2015
 16235 00004775 C705[A7740000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 16236 0000477D 0000                <1>
 16237 0000477F E9C9F8FFFF          <1> 	jmp	error
 16238                              <1> sysgtty_0:	
 16239 00004784 21DB                <1> 	and	ebx, ebx
 16240 00004786 7430                <1> 	jz	short sysgtty_1
 16241                              <1> 	;
 16242 00004788 891D[70740000]      <1> 	mov	[u.namep], ebx
 16243 0000478E 6651                <1> 	push	cx ; 23/11/2015
 16244 00004790 E867070000          <1> 	call	namei
 16245 00004795 6659                <1> 	pop	cx ; 23/11/2015
 16246 00004797 7210                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
 16247                              <1> 	;
 16248 00004799 6683F801            <1> 	cmp	ax, 1
 16249 0000479D 7622                <1> 	jna	short sysgtty_2
 16250 0000479F 6683E80A            <1> 	sub	ax, 10
 16251 000047A3 6683F809            <1> 	cmp	ax, 9
 16252                              <1> 	;ja	short sysgtty_inv_dn
 16253                              <1> 	;mov	ch, al
 16254                              <1> 	;jmp	short sysgtty_4
 16255                              <1> 	; 23/11/2015
 16256 000047A7 7629                <1> 	jna	short sysgtty_4
 16257                              <1> sysgtty_inv_dn: 
 16258                              <1> 	; 28/06/2015
 16259                              <1> 	; Invalid device name (not a tty) ! error
 16260                              <1> 	; (Device is not a tty or device name not found)
 16261 000047A9 C705[A7740000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 16262 000047B1 0000                <1>
 16263 000047B3 E995F8FFFF          <1> 	jmp	error 
 16264                              <1> sysgtty_1:
 16265                              <1> 	; 16/01/2014
 16266 000047B8 80FD0A              <1> 	cmp	ch, 10
 16267 000047BB 77B8                <1> 	ja	short sysgtty_invp ; 28/06/2015
 16268 000047BD FECD                <1> 	dec	ch ; 0 -> FFh (negative)
 16269 000047BF 790F                <1> 	jns	short sysgtty_3 ; not negative
 16270                              <1> 	;
 16271                              <1> sysgtty_2:
 16272                              <1> 	; get tty number of console tty
 16273 000047C1 8A25[A1740000]      <1> 	mov	ah, [u.uno]
 16274                              <1>  	; 28/06/2015
 16275 000047C7 0FB6DC              <1> 	movzx 	ebx, ah
 16276 000047CA 8AAB[A5710000]      <1> 	mov	ch, [ebx+p.ttyc-1]
 16277                              <1> sysgtty_3:
 16278 000047D0 88E8                <1> 	mov	al, ch
 16279                              <1> sysgtty_4:
 16280 000047D2 A2[58740000]        <1> 	mov	[u.r0], al
 16281                              <1>  	; 28/06/2015
 16282                              <1> 	;cmp	al, 9
 16283                              <1> 	;ja	short sysgtty_invp
 16284 000047D7 8B2D[54740000]      <1> 	mov	ebp, [u.usp]
 16285                              <1> 	; 23/11/2015
 16286 000047DD 20C9                <1> 	and	cl, cl
 16287 000047DF 7436                <1> 	jz	short sysgtty_6 ; keyboard status
 16288 000047E1 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
 16289 000047E3 7232                <1> 	jb	short sysgtty_6 ; video page status
 16290                              <1> 	; serial port status
 16291                              <1> 	; 12/07/2014
 16292                              <1> 	;mov	dx, 0
 16293                              <1> 	;je	short sysgtty_5
 16294                              <1> 	;inc	dl
 16295                              <1> ;sysgtty_5:
 16296                              <1> 	; 28/06/2015
 16297 000047E5 2C08                <1> 	sub	al, 8
 16298 000047E7 E806F3FFFF          <1> 	call	sp_status ; serial (COM) port (line) status
 16299                              <1> 	; AL = Line status, AH = Modem status
 16300 000047EC 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
 16301 000047F0 8A25[A1740000]      <1> 	mov	ah, [u.uno]
 16302 000047F6 8825[59740000]      <1>         mov     [u.r0+1], ah
 16303 000047FC 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)	
 16304                              <1> 				; (in ECX)
 16305 00004802 A880                <1> 	test	al, 80h
 16306 00004804 7565                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
 16307 00004806 A801                <1> 	test	al, 1
 16308 00004808 0F845FF8FFFF        <1> 	jz	sysret
 16309 0000480E 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)	
 16310 00004812 E956F8FFFF          <1> 	jmp	sysret
 16311                              <1> sysgtty_6:
 16312 00004817 A2[A6740000]        <1> 	mov	[u.ttyn], al ; tty number
 16313                              <1> 	;movzx	ebx, al
 16314 0000481C 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
 16315 0000481E D0E3                <1> 	shl 	bl, 1  ; aligned to word
 16316                              <1> 	; 22/04/2014 - 29/06/2015
 16317 00004820 81C3[C4700000]      <1>         add     ebx, ttyl
 16318 00004826 8A23                <1>  	mov	ah, [ebx]
 16319 00004828 3A25[A1740000]      <1> 	cmp	ah, [u.uno]
 16320 0000482E 7404                <1> 	je	short sysgtty_7
 16321 00004830 20E4                <1> 	and	ah, ah
 16322                              <1> 	;jz	short sysgtty_7
 16323 00004832 7506                <1> 	jnz	short sysgtty_8
 16324                              <1> 	;mov	ah, 0FFh
 16325                              <1> sysgtty_7:
 16326 00004834 8825[59740000]      <1>         mov     [u.r0+1], ah
 16327                              <1> sysgtty_8:
 16328 0000483A 08C9                <1> 	or	cl, cl
 16329 0000483C 7510                <1> 	jnz	short sysgtty_9
 16330 0000483E B001                <1> 	mov	al, 1  ; test a key is available
 16331 00004840 E85F1C0000          <1> 	call	getc
 16332 00004845 66894510            <1> 	mov	[ebp+16], ax ; bx, character
 16333 00004849 E91FF8FFFF          <1> 	jmp	sysret
 16334                              <1> sysgtty_9:
 16335 0000484E 8A1D[A6740000]      <1> 	mov	bl, [u.ttyn]
 16336                              <1> 	; bl = video page number
 16337 00004854 E8D31D0000          <1> 	call 	get_cpos
 16338                              <1> 	; dx = cursor position
 16339 00004859 66895510            <1> 	mov	[ebp+16], dx ; bx
 16340                              <1> 	;mov	bl, [u.ttyn]
 16341                              <1> 	; bl = video page number
 16342 0000485D E8DB1D0000          <1> 	call	read_ac_current
 16343                              <1> 	; ax = character and attribute/color
 16344 00004862 66894518            <1> 	mov	[ebp+24], ax ; cx
 16345 00004866 E902F8FFFF          <1> 	jmp	sysret
 16346                              <1> sysgtty_dnr_err:
 16347                              <1> 	; 'device not responding !' error	
 16348                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
 16349 0000486B C705[A7740000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ;  25				
 16350 00004873 0000                <1>
 16351 00004875 E9D3F7FFFF          <1> 	jmp	error	
 16352                              <1> 
 16353                              <1> ; Original UNIX v1 'sysgtty' routine:
 16354                              <1> ; sysgtty:
 16355                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
 16356                              <1> 	;	       / r2 has destination
 16357                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
 16358                              <1> 	;                     / in 1st word of dest
 16359                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
 16360                              <1> 	;                     / in 2nd word of dest
 16361                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
 16362                              <1>         ;jmp    sysret2 / return to user
 16363                              <1> 	
 16364                              <1> ; Original UNIX v1 'gtty' routine:
 16365                              <1> ; gtty:
 16366                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
 16367                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
 16368                              <1>         ;jsr    r0,getf / get the i-number of the file
 16369                              <1>         ;tst    r1 / is it open for reading
 16370                              <1>         ;bgt    1f / yes
 16371                              <1>         ;neg    r1 / no, i-number is negative, 
 16372                              <1> 	;          / so make it positive
 16373                              <1> ;1:
 16374                              <1>         ;sub    $14.,r1 / get i-number of tty0
 16375                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
 16376                              <1>         ;bhis   error9 / no, error
 16377                              <1>         ;asl    r1 / 0%2
 16378                              <1>         ;asl    r1 / 0%4 / yes
 16379                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
 16380                              <1> 	;	       ; / tty block
 16381                              <1>         ;mov    u.off,r2 / put argument in r2
 16382                              <1>         ;rts    r0 / return
 16383                                  %include 'u2.s'        ; 11/05/2015
 16384                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS2.INC
 16385                              <1> ; Last Modification: 03/01/2016
 16386                              <1> ; ----------------------------------------------------------------------------
 16387                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 16388                              <1> ; (v0.1 - Beginning: 11/07/2012)
 16389                              <1> ;
 16390                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 16391                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 16392                              <1> ; <Bell Laboratories (17/3/1972)>
 16393                              <1> ; <Preliminary Release of UNIX Implementation Document>
 16394                              <1> ;
 16395                              <1> ; Retro UNIX 8086 v1 - U2.ASM (24/03/2014) //// UNIX v1 -> u2.s
 16396                              <1> ;
 16397                              <1> ; ****************************************************************************
 16398                              <1> 
 16399                              <1> syslink:
 16400                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 16401                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 16402                              <1> 	;
 16403                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
 16404                              <1> 	; name 1 is a file that already exists. name 2 is the name
 16405                              <1> 	; given to the entry that will go in the current directory.
 16406                              <1> 	; name2 will then be a link to the name 1 file. The i-number
 16407                              <1> 	; in the name 2 entry of current directory is the same
 16408                              <1> 	; i-number for the name 1 file.
 16409                              <1> 	;
 16410                              <1> 	; Calling sequence:
 16411                              <1> 	;	syslink; name 1; name 2
 16412                              <1> 	; Arguments:
 16413                              <1> 	;	name 1 - file name to which link will be created.
 16414                              <1> 	;	name 2 - name of entry in current directory that
 16415                              <1> 	;		 links to name 1.
 16416                              <1> 	; Inputs: -
 16417                              <1> 	; Outputs: -
 16418                              <1> 	; ...............................................................
 16419                              <1> 	;	
 16420                              <1> 	; Retro UNIX 8086 v1 modification: 
 16421                              <1> 	;       'syslink' system call has two arguments; so,
 16422                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
 16423                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
 16424                              <1> 	;
 16425                              <1> 		; / name1, name2
 16426                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
 16427 0000487A 891D[70740000]      <1> 	mov	[u.namep], ebx
 16428 00004880 51                  <1> 	push	ecx
 16429 00004881 E876060000          <1> 	call	namei
 16430                              <1> 		; jsr r0,namei / find the i-number associated with
 16431                              <1> 			     ; / the 1st path name
 16432                              <1>      	;;and	ax, ax
 16433                              <1> 	;;jz	error ; File not found
 16434                              <1> 	;jc	error 
 16435                              <1> 		; br error9 / cannot be found
 16436 00004886 730F                <1> 	jnc	short syslink0
 16437                              <1> 	;pop 	ecx
 16438                              <1> 	; 'file not found !' error
 16439 00004888 C705[A7740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 16440 00004890 0000                <1>
 16441 00004892 E9B6F7FFFF          <1> 	jmp	error
 16442                              <1> syslink0:
 16443 00004897 E8500E0000          <1> 	call	iget
 16444                              <1> 		; jsr r0,iget / get the i-node into core
 16445 0000489C 8F05[70740000]      <1> 	pop	dword [u.namep] ; ecx
 16446                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
 16447 000048A2 6650                <1> 	push	ax
 16448                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
 16449                              <1> 			    ; / (a link to this file is to be created)
 16450 000048A4 66FF35[3E740000]    <1> 	push	word [cdev]
 16451                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
 16452 000048AB E855000000          <1> 	call	isdir
 16453                              <1> 		; jsr r0,isdir / is it a directory
 16454 000048B0 E847060000          <1> 	call	namei
 16455                              <1> 		; jsr r0,namei / no, get i-number of name2
 16456                              <1> 	;jnc	error
 16457                              <1> 		; br .+4   / not found 
 16458                              <1> 			 ; / so r1 = i-number of current directory
 16459                              <1> 			 ; / ii = i-number of current directory
 16460                              <1> 		; br error9 / file already exists., error
 16461 000048B5 720F                <1> 	jc	short syslink1
 16462                              <1> 	; pop ax
 16463                              <1> 	; pop ax
 16464                              <1> 	; 'file exists !' error
 16465 000048B7 C705[A7740000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
 16466 000048BF 0000                <1>
 16467 000048C1 E987F7FFFF          <1> 	jmp	error
 16468                              <1> syslink1:
 16469 000048C6 6659                <1> 	pop	cx
 16470                              <1> 	;cmp	cx, [cdev]
 16471 000048C8 3A0D[3E740000]      <1> 	cmp	cl, [cdev]
 16472                              <1> 	;jne	error
 16473                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
 16474                              <1> 			       ; / end of current directory
 16475                              <1> 	        ; bne error9
 16476 000048CE 740F                <1> 	je	short syslink2
 16477                              <1> 	; 'not same drive !' error
 16478 000048D0 C705[A7740000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
 16479 000048D8 0000                <1>
 16480 000048DA E96EF7FFFF          <1> 	jmp	error
 16481                              <1> syslink2:
 16482 000048DF 6658                <1> 	pop	ax
 16483 000048E1 6650                <1> 	push	ax
 16484 000048E3 66A3[8A740000]      <1> 	mov	[u.dirbuf], ax
 16485                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
 16486 000048E9 E8A8000000          <1> 	call	mkdir
 16487                              <1> 		; jsr r0,mkdir / make directory entry for name2 
 16488                              <1> 		 	     ; / in current directory
 16489 000048EE 6658                <1> 	pop	ax
 16490                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
 16491 000048F0 E8F70D0000          <1> 	call	iget
 16492                              <1> 		; jsr r0,iget / get i-node into core
 16493 000048F5 FE05[28710000]      <1> 	inc	byte [i.nlks]
 16494                              <1> 		; incb i.nlks / add 1 to its number of links
 16495 000048FB E8FF0E0000          <1> 	call	setimod
 16496                              <1> 		; jsr r0,setimod / set the i-node modified flag
 16497 00004900 E968F7FFFF          <1> 	jmp	sysret
 16498                              <1> 
 16499                              <1> isdir:
 16500                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 16501                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16502                              <1> 	;
 16503                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
 16504                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
 16505                              <1> 	;  called by syslink and sysunlink to make sure directories
 16506                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
 16507                              <1> 	; 'isdir' does not bother checking. The current i-node
 16508                              <1> 	;  is not disturbed.			
 16509                              <1> 	;		
 16510                              <1> 	; INPUTS ->
 16511                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
 16512                              <1> 	;    u.uid - user id
 16513                              <1> 	; OUTPUTS ->
 16514                              <1> 	;    r1 - contains current i-number upon exit
 16515                              <1> 	;    	 (current i-node back in core) 
 16516                              <1> 	;	
 16517                              <1> 	; ((AX = R1))
 16518                              <1> 	;
 16519                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 16520                              <1> 	;
 16521                              <1> 
 16522                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
 16523                              <1> 	; / there is an error unless super user made the call
 16524                              <1> 	
 16525 00004905 803D[9E740000]00    <1> 	cmp	byte [u.uid], 0 
 16526                              <1> 		; tstb u.uid / super user
 16527 0000490C 762D                <1> 	jna	short isdir1
 16528                              <1> 		; beq 1f / yes, don't care
 16529 0000490E 66FF35[3A740000]    <1> 	push	word [ii]
 16530                              <1> 		; mov ii,-(sp) / put current i-number on stack
 16531 00004915 E8D20D0000          <1> 	call	iget
 16532                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
 16533 0000491A 66F705[26710000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
 16534 00004922 40                  <1>
 16535                              <1> 		; bit $40000,i.flgs / is it a directory
 16536                              <1> 	;jnz	error
 16537                              <1> 		; bne error9 / yes, error
 16538 00004923 740F                <1> 	jz	short isdir0
 16539 00004925 C705[A7740000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
 16540 0000492D 0000                <1>
 16541                              <1> 				; 'permission denied !' error
 16542                              <1> 	; pop	ax
 16543 0000492F E919F7FFFF          <1> 	jmp	error	
 16544                              <1> isdir0:	
 16545 00004934 6658                <1> 	pop	ax
 16546                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
 16547 00004936 E8B10D0000          <1> 	call	iget
 16548                              <1> 		; jsr r0,iget / get it back in
 16549                              <1> isdir1: ; 1:
 16550 0000493B C3                  <1> 	retn
 16551                              <1> 		; rts r0
 16552                              <1> 
 16553                              <1> sysunlink:
 16554                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 16555                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 16556                              <1> 	;
 16557                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
 16558                              <1> 	; name from its directory. If this entry was the last link
 16559                              <1> 	; to the file, the contents of the file are freed and the
 16560                              <1> 	; file is destroyed. If, however, the file was open in any
 16561                              <1> 	; process, the actual destruction is delayed until it is 
 16562                              <1> 	; closed, even though the directory entry has disappeared.
 16563                              <1> 	; 
 16564                              <1> 	; The error bit (e-bit) is set to indicate that the file	
 16565                              <1> 	; does not exist or that its directory can not be written.
 16566                              <1> 	; Write permission is not required on the file itself.
 16567                              <1> 	; It is also illegal to unlink a directory (except for
 16568                              <1> 	; the superuser).
 16569                              <1> 	;
 16570                              <1> 	; Calling sequence:
 16571                              <1> 	;	sysunlink; name
 16572                              <1> 	; Arguments:
 16573                              <1> 	;	name - name of directory entry to be removed 
 16574                              <1> 	; Inputs: -
 16575                              <1> 	; Outputs: -
 16576                              <1> 	; ...............................................................
 16577                              <1> 	;				
 16578                              <1> 	; Retro UNIX 8086 v1 modification:
 16579                              <1> 	;	 The user/application program puts address of the name
 16580                              <1> 	;        in BX register as 'sysunlink' system call argument.
 16581                              <1> 
 16582                              <1> 	; / name - remove link name
 16583 0000493C 891D[70740000]      <1> 	mov	[u.namep], ebx
 16584                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
 16585 00004942 E8B5050000          <1> 	call	namei
 16586                              <1> 		; jsr r0,namei / find the i-number associated 
 16587                              <1> 			     ; / with the path name
 16588                              <1> 	;jc	error
 16589                              <1> 		; br error9 / not found
 16590 00004947 730F                <1> 	jnc	short sysunlink1
 16591                              <1> 	; 'file not found !' error
 16592 00004949 C705[A7740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 16593 00004951 0000                <1>
 16594 00004953 E9F5F6FFFF          <1> 	jmp	error
 16595                              <1> sysunlink1:
 16596 00004958 6650                <1> 	push	ax
 16597                              <1> 		; mov r1,-(sp) / put its i-number on the stack
 16598 0000495A E8A6FFFFFF          <1> 	call	isdir
 16599                              <1> 		; jsr r0,isdir / is it a directory
 16600 0000495F 6631C0              <1> 	xor 	ax, ax
 16601 00004962 66A3[8A740000]      <1> 	mov	[u.dirbuf], ax ; 0
 16602                              <1> 		; clr u.dirbuf / no, clear the location that will
 16603                              <1> 			   ; / get written into the i-number portion
 16604                              <1> 			 ; / of the entry
 16605 00004968 832D[74740000]0A    <1> 	sub	dword [u.off], 10
 16606                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
 16607 0000496F E86B000000          <1> 	call	wdir
 16608                              <1> 		; jsr r0,wdir / free the directory entry
 16609 00004974 6658                <1> 	pop	ax
 16610                              <1> 		; mov (sp)+,r1 / get i-number back
 16611 00004976 E8710D0000          <1> 	call	iget
 16612                              <1> 		; jsr r0,iget / get i-node
 16613 0000497B E87F0E0000          <1> 	call	setimod
 16614                              <1> 		; jsr r0,setimod / set modified flag
 16615 00004980 FE0D[28710000]      <1> 	dec	byte [i.nlks]
 16616                              <1> 		; decb i.nlks / decrement the number of links
 16617 00004986 0F85E1F6FFFF        <1> 	jnz	sysret
 16618                              <1> 		; bgt sysret9 / if this was not the last link
 16619                              <1> 			    ; / to file return
 16620                              <1> 	; AX = r1 = i-number
 16621 0000498C E890090000          <1> 	call	anyi
 16622                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
 16623                              <1> 			 ; / Then free contents of file and destroy it.
 16624 00004991 E9D7F6FFFF          <1> 	jmp	sysret
 16625                              <1> 		; br sysret9
 16626                              <1> 
 16627                              <1> mkdir:
 16628                              <1> 	; 12/10/2015
 16629                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
 16630                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 16631                              <1> 	;
 16632                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
 16633                              <1> 	; by u.namep into the current directory.
 16634                              <1> 	;
 16635                              <1> 	; INPUTS ->
 16636                              <1> 	;    u.namep - points to a file name 
 16637                              <1> 	;	           that is about to be a directory entry.
 16638                              <1> 	;    ii - current directory's i-number.	
 16639                              <1> 	; OUTPUTS ->
 16640                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
 16641                              <1> 	;    u.off - points to entry to be filled 
 16642                              <1> 	;	     in the current directory		
 16643                              <1> 	;    u.base - points to start of u.dirbuf.
 16644                              <1> 	;    r1 - contains i-number of current directory 
 16645                              <1> 	;	
 16646                              <1> 	; ((AX = R1)) output
 16647                              <1> 	;
 16648                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
 16649                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 16650                              <1> 	;
 16651                              <1> 
 16652                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 16653 00004996 31C0                <1> 	xor 	eax, eax
 16654 00004998 BF[8C740000]        <1>         mov     edi, u.dirbuf+2
 16655 0000499D 89FE                <1> 	mov	esi, edi
 16656 0000499F AB                  <1> 	stosd
 16657 000049A0 AB                  <1> 	stosd
 16658                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
 16659 000049A1 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
 16660                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 16661                              <1> 	;mov 	ebp, [u.namep]
 16662 000049A3 E899060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 16663                              <1> 		; esi = physical address (page start + offset)
 16664                              <1> 		; ecx = byte count in the page (1 - 4096)
 16665                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 16666                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
 16667                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
 16668                              <1> mkdir_1: ; 1: 
 16669 000049A8 45                  <1> 	inc	ebp ; 12/10/2015
 16670                              <1> 	;
 16671                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
 16672                              <1> 	 ; 01/08/2013
 16673 000049A9 AC                  <1> 	lodsb
 16674                              <1> 		; movb (r2)+,r1 / move character in name to r1
 16675 000049AA 20C0                <1> 	and 	al, al
 16676 000049AC 7427                <1> 	jz 	short mkdir_3 	  
 16677                              <1> 		; beq 1f / if null, done
 16678 000049AE 3C2F                <1> 	cmp	al, '/'
 16679                              <1> 		; cmp r1,$'/ / is it a "/"?
 16680 000049B0 7414                <1> 	je	short mkdir_err
 16681                              <1> 	;je	error
 16682                              <1> 		; beq error9 / yes, error
 16683                              <1> 	; 12/10/2015
 16684 000049B2 6649                <1> 	dec	cx
 16685 000049B4 7505                <1> 	jnz	short mkdir_2
 16686                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 16687 000049B6 E88C060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 16688                              <1> 		; esi = physical address (page start + offset)
 16689                              <1> 		; ecx = byte count in the page
 16690                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 16691                              <1> mkdir_2:
 16692 000049BB 81FF[94740000]      <1> 	cmp     edi, u.dirbuf+10
 16693                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
 16694                              <1> 				     ; / a char?
 16695 000049C1 74E5                <1> 	je	short mkdir_1
 16696                              <1> 		; beq 1b / yes, go back
 16697 000049C3 AA                  <1> 	stosb
 16698                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
 16699 000049C4 EBE2                <1> 	jmp 	short mkdir_1
 16700                              <1> 		; br 1b / get next char
 16701                              <1> mkdir_err:
 16702                              <1> 	; 17/06/2015
 16703 000049C6 C705[A7740000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 16704 000049CE 0000                <1>
 16705 000049D0 E978F6FFFF          <1> 	jmp	error
 16706                              <1> 
 16707                              <1> mkdir_3: ; 1:
 16708 000049D5 A1[6C740000]        <1> 	mov	eax, [u.dirp]
 16709 000049DA A3[74740000]        <1> 	mov	[u.off], eax
 16710                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
 16711                              <1> 				 ; / slot to u.off
 16712                              <1> wdir: ; 29/04/2013
 16713 000049DF C705[78740000]-     <1>         mov     dword [u.base], u.dirbuf
 16714 000049E5 [8A740000]          <1>
 16715                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
 16716 000049E9 C705[7C740000]0A00- <1>         mov     dword [u.count], 10
 16717 000049F1 0000                <1>
 16718                              <1> 		; mov $10.,u.count / u.count = 10
 16719 000049F3 66A1[3A740000]      <1> 	mov	ax, [ii] 
 16720                              <1> 		; mov ii,r1 / r1 has i-number of current directory
 16721 000049F9 B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
 16722 000049FB E8C70D0000          <1> 	call 	access
 16723                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
 16724                              <1> 				 ; / for writing
 16725                              <1> 	; AX = i-number of current directory
 16726                              <1> 	; 01/08/2013
 16727 00004A00 FE05[B9740000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
 16728 00004A06 E8B7100000          <1> 	call	writei
 16729                              <1> 		; jsr r0,writei / write into directory
 16730 00004A0B C3                  <1> 	retn	
 16731                              <1> 		; rts r0
 16732                              <1> 
 16733                              <1> sysexec:
 16734                              <1> 	; 23/10/2015
 16735                              <1> 	; 19/10/2015
 16736                              <1> 	; 18/10/2015
 16737                              <1> 	; 10/10/2015
 16738                              <1> 	; 26/08/2015
 16739                              <1> 	; 05/08/2015
 16740                              <1> 	; 29/07/2015
 16741                              <1> 	; 25/07/2015
 16742                              <1> 	; 24/07/2015
 16743                              <1> 	; 21/07/2015
 16744                              <1> 	; 20/07/2015
 16745                              <1> 	; 02/07/2015
 16746                              <1> 	; 01/07/2015
 16747                              <1> 	; 25/06/2015
 16748                              <1> 	; 24/06/2015
 16749                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 16750                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 16751                              <1> 	;
 16752                              <1> 	; 'sysexec' initiates execution of a file whose path name if
 16753                              <1> 	; pointed to by 'name' in the sysexec call. 
 16754                              <1> 	; 'sysexec' performs the following operations:
 16755                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
 16756                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
 16757                              <1> 	;    3. sets trap vectors to system routines.
 16758                              <1> 	;    4. loads arguments to be passed to executing file into
 16759                              <1> 	;	highest locations of user's core
 16760                              <1> 	;    5. puts pointers to arguments in locations immediately
 16761                              <1> 	;	following arguments.
 16762                              <1> 	;    6.	saves number of arguments in next location.
 16763                              <1> 	;    7. intializes user's stack area so that all registers
 16764                              <1> 	;	will be zeroed and the PS is cleared and the PC set
 16765                              <1> 	;	to core when 'sysret' restores registers 
 16766                              <1> 	;	and does an rti.
 16767                              <1> 	;    8. inializes u.r0 and u.sp
 16768                              <1> 	;    9. zeros user's core down to u.r0
 16769                              <1> 	;   10.	reads executable file from storage device into core
 16770                              <1> 	;	starting at location 'core'.
 16771                              <1> 	;   11.	sets u.break to point to end of user's code with
 16772                              <1> 	;	data area appended.
 16773                              <1> 	;   12.	calls 'sysret' which returns control at location
 16774                              <1> 	;	'core' via 'rti' instruction. 		  		
 16775                              <1> 	;
 16776                              <1> 	; Calling sequence:
 16777                              <1> 	;	sysexec; namep; argp
 16778                              <1> 	; Arguments:
 16779                              <1> 	;	namep - points to pathname of file to be executed
 16780                              <1> 	;	argp  - address of table of argument pointers
 16781                              <1> 	;	argp1... argpn - table of argument pointers
 16782                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
 16783                              <1> 	; Inputs: (arguments)
 16784                              <1> 	; Outputs: -	
 16785                              <1> 	; ...............................................................
 16786                              <1> 	;
 16787                              <1> 	; Retro UNIX 386 v1 modification: 
 16788                              <1> 	;	User application runs in it's own virtual space 
 16789                              <1> 	;	which is izolated from kernel memory (and other
 16790                              <1> 	;	memory pages) via 80386	paging in ring 3 
 16791                              <1> 	;	privilige mode. Virtual start address is always 0.
 16792                              <1> 	;	User's core memory starts at linear address 400000h
 16793                              <1> 	;	(the end of the 1st 4MB).
 16794                              <1> 	;
 16795                              <1> 	; Retro UNIX 8086 v1 modification: 
 16796                              <1> 	;	user/application segment and system/kernel segment
 16797                              <1> 	;	are different and sysenter/sysret/sysrele routines
 16798                              <1> 	;	are different (user's registers are saved to 
 16799                              <1> 	;	and then restored from system's stack.)
 16800                              <1> 	;
 16801                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 16802                              <1> 	;	      arguments which were in these registers;
 16803                              <1> 	;	      but, it returns by putting the 1st argument
 16804                              <1> 	;	      in 'u.namep' and the 2nd argument
 16805                              <1> 	;	      on top of stack. (1st argument is offset of the
 16806                              <1> 	;	      file/path name in the user's program segment.)		 	
 16807                              <1> 	
 16808                              <1> 	;call	arg2
 16809                              <1> 	; * name - 'u.namep' points to address of file/path name
 16810                              <1> 	;          in the user's program segment ('u.segmnt')
 16811                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16812                              <1> 	; * argp - sysexec argument 2 is in CX register 
 16813                              <1> 	;          which is on top of stack.
 16814                              <1> 	;
 16815                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
 16816                              <1> 
 16817                              <1> 	; 23/06/2015 (32 bit modifications)
 16818                              <1> 
 16819 00004A0C 891D[70740000]      <1> 	mov	[u.namep], ebx ; argument 1
 16820                              <1>         ; 18/10/2015
 16821 00004A12 890D[D0740000]      <1> 	mov     [argv], ecx  ; * ; argument 2
 16822 00004A18 E8DF040000          <1> 	call	namei
 16823                              <1> 		; jsr r0,namei / namei returns i-number of file 
 16824                              <1> 			     ; / named in sysexec call in r1
 16825                              <1> 	;jc	error
 16826                              <1> 		; br error9
 16827 00004A1D 731E                <1> 	jnc	short sysexec_0
 16828                              <1> 	;
 16829                              <1> 	; 'file not found !' error
 16830 00004A1F C705[A7740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
 16831 00004A27 0000                <1>
 16832 00004A29 E91FF6FFFF          <1> 	jmp	error 
 16833                              <1> sysexec_not_exf:
 16834                              <1> 	; 'not executable file !' error
 16835 00004A2E C705[A7740000]1600- <1> 	mov	dword [u.error], ERR_NOT_EXECUTABLE
 16836 00004A36 0000                <1>
 16837 00004A38 E910F6FFFF          <1> 	jmp	error 
 16838                              <1> sysexec_0:
 16839 00004A3D E8AA0C0000          <1> 	call	iget
 16840                              <1> 		; jsr r0,iget / get i-node for file to be executed
 16841 00004A42 66F705[26710000]10- <1>         test    word [i.flgs], 10h
 16842 00004A4A 00                  <1>
 16843                              <1> 		; bit $20,i.flgs / is file executable
 16844 00004A4B 74E1                <1> 	jz	short sysexec_not_exf
 16845                              <1> 	;jz	error
 16846                              <1> 		; beq error9
 16847                              <1> 	;;
 16848 00004A4D E819140000          <1> 	call	iopen
 16849                              <1> 		; jsr r0,iopen / gets i-node for file with i-number
 16850                              <1> 			     ; / given in r1 (opens file)
 16851                              <1> 	; AX = i-number of the file
 16852 00004A52 66F705[26710000]20- <1> 	test	word [i.flgs], 20h
 16853 00004A5A 00                  <1>
 16854                              <1> 		; bit $40,i.flgs / test user id on execution bit
 16855 00004A5B 7415                <1> 	jz	short sysexec_1
 16856                              <1> 		; beq 1f
 16857 00004A5D 803D[9E740000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013
 16858                              <1> 		; tstb u.uid / test user id
 16859 00004A64 760C                <1> 	jna	short sysexec_1
 16860                              <1> 		; beq 1f / super user
 16861 00004A66 8A0D[29710000]      <1> 	mov	cl, [i.uid]
 16862 00004A6C 880D[9E740000]      <1> 	mov	[u.uid], cl ; 02/08/2013
 16863                              <1> 		; movb i.uid,u.uid / put user id of owner of file
 16864                              <1> 				 ; / as process user id
 16865                              <1> sysexec_1:
 16866                              <1> 	; 18/10/2215
 16867                              <1> 	; 10/10/2015
 16868                              <1> 	; 24/07/2015
 16869                              <1> 	; 21/07/2015
 16870                              <1> 	; 25/06/2015
 16871                              <1> 	; 24/06/2015
 16872                              <1>         ; Moving arguments to the end of [u.upage]
 16873                              <1> 	; (by regarding page borders in user's memory space)
 16874                              <1> 	;
 16875                              <1> 	; 10/10/2015
 16876                              <1> 	; 21/07/2015
 16877 00004A72 89E5                <1> 	mov	ebp, esp ; (**)
 16878                              <1> 	; 18/10/2015
 16879 00004A74 89EF                <1> 	mov 	edi, ebp
 16880 00004A76 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
 16881                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
 16882 00004A7B 29CF                <1> 	sub	edi, ecx
 16883 00004A7D 89FC                <1> 	mov	esp, edi
 16884 00004A7F 31C0                <1> 	xor	eax, eax
 16885 00004A81 A3[80740000]        <1> 	mov 	[u.nread], eax ; 0
 16886 00004A86 49                  <1> 	dec	ecx ; 256 - 1
 16887 00004A87 890D[7C740000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
 16888                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
 16889                              <1> sysexec_2:
 16890 00004A8D 8B35[D0740000]      <1> 	mov	esi, [argv] ; 18/10/2015 
 16891 00004A93 E873020000          <1> 	call	get_argp
 16892 00004A98 B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
 16893                              <1> sysexec_3:
 16894 00004A9D 21C0                <1> 	and	eax, eax
 16895 00004A9F 7456                <1> 	jz	short sysexec_6
 16896                              <1> 	; 18/10/2015
 16897 00004AA1 010D[D0740000]      <1> 	add	[argv], ecx ; 4
 16898 00004AA7 66FF05[CE740000]    <1> 	inc	word [argc]
 16899                              <1> 	;
 16900 00004AAE A3[78740000]        <1> 	mov	[u.base], eax
 16901                              <1>  	; 23/10/2015
 16902 00004AB3 66C705[B7740000]00- <1> 	mov	word [u.pcount], 0
 16903 00004ABB 00                  <1>
 16904                              <1> sysexec_4:
 16905 00004ABC E8BC110000          <1> 	call	cpass ; get a character from user's core memory
 16906 00004AC1 750B                <1>         jnz      short sysexec_5
 16907                              <1> 		; (max. 255 chars + null)
 16908                              <1> 	; 18/10/2015
 16909 00004AC3 28C0                <1> 	sub 	al, al
 16910 00004AC5 AA                  <1> 	stosb
 16911 00004AC6 FF05[80740000]      <1> 	inc	dword [u.nread]
 16912 00004ACC EB29                <1> 	jmp	short sysexec_6
 16913                              <1> sysexec_5:
 16914 00004ACE AA                  <1> 	stosb
 16915 00004ACF 20C0                <1> 	and 	al, al
 16916 00004AD1 75E9                <1> 	jnz	short sysexec_4
 16917 00004AD3 B904000000          <1> 	mov	ecx, 4
 16918 00004AD8 390D[CC740000]      <1> 	cmp	[ncount], ecx ; 4
 16919 00004ADE 72AD                <1> 	jb	short sysexec_2
 16920 00004AE0 8B35[C8740000]      <1> 	mov	esi, [nbase]
 16921 00004AE6 010D[C8740000]      <1> 	add	[nbase], ecx ; 4	
 16922 00004AEC 66290D[CC740000]    <1> 	sub	[ncount], cx 
 16923 00004AF3 8B06                <1> 	mov	eax, [esi]
 16924 00004AF5 EBA6                <1> 	jmp	short sysexec_3
 16925                              <1> sysexec_6:
 16926                              <1> 	; 18/10/2015
 16927                              <1> 	; argument list transfer from user's core memory to
 16928                              <1> 	; kernel stack frame is OK here.
 16929                              <1> 	; [u.nread] = ; argument list length
 16930                              <1> 	;mov	[argv], esp ; start address of argument list 	
 16931                              <1> 	;
 16932                              <1> 	; 18/10/2015
 16933                              <1> 	; 24/07/2015
 16934                              <1>         ; 21/07/2015
 16935                              <1> 	; 02/07/2015
 16936                              <1> 	; 25/06/2015
 16937                              <1> 	; 24/06/2015
 16938                              <1> 	; 23/06/2015
 16939                              <1> 	;
 16940 00004AF7 8B1D[AF740000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
 16941 00004AFD 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
 16942 00004AFF 740A                <1> 	jz	short sysexec_7
 16943 00004B01 A1[AB740000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
 16944 00004B06 E823E6FFFF          <1> 	call	deallocate_page_dir
 16945                              <1> sysexec_7:
 16946 00004B0B E853E5FFFF          <1> 	call	make_page_dir
 16947                              <1> 	;jc	short sysexec_14
 16948 00004B10 0F82BAEDFFFF        <1> 	jc	panic  ; allocation error 
 16949                              <1> 		       ; after a deallocation would be nonsence !?
 16950                              <1> 	; 24/07/2015
 16951                              <1> 	; map kernel pages (1st 4MB) to PDE 0
 16952                              <1> 	;     of the user's page directory
 16953                              <1> 	;     (It is needed for interrupts!)
 16954                              <1> 	; 18/10/2015
 16955 00004B16 8B15[78700000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
 16956 00004B1C 8B02                <1> 	mov	eax, [edx] ; physical address of
 16957                              <1> 			   ; kernel's first page table (1st 4 MB)
 16958                              <1> 			   ; (PDE 0 of kernel's page directory)
 16959 00004B1E 8B15[AB740000]      <1> 	mov 	edx, [u.pgdir]
 16960 00004B24 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
 16961                              <1> 	;
 16962                              <1> 	; 20/07/2015
 16963 00004B26 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
 16964                              <1> 	; 18/10/2015
 16965 00004B2B BE[C0740000]        <1> 	mov	esi, pcore ; physical start address
 16966                              <1> sysexec_8:	
 16967 00004B30 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
 16968 00004B35 E847E5FFFF          <1> 	call	make_page_table
 16969 00004B3A 0F8290EDFFFF        <1> 	jc	panic
 16970                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
 16971 00004B40 E84AE5FFFF          <1> 	call	make_page ; make new page, clear and set the pte 
 16972 00004B45 0F8285EDFFFF        <1> 	jc	panic
 16973                              <1> 	;
 16974 00004B4B 8906                <1> 	mov	[esi], eax ; 24/06/2015
 16975                              <1> 	; ebx = virtual address (24/07/2015)
 16976 00004B4D E860EAFFFF          <1> 	call 	add_to_swap_queue
 16977                              <1> 	; 18/10/2015
 16978 00004B52 81FE[C4740000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
 16979 00004B58 740C                <1> 	je	short sysexec_9 ; yes
 16980 00004B5A BE[C4740000]        <1> 	mov	esi, ecore  ; physical address of the last page 
 16981                              <1> 	; 20/07/2015
 16982 00004B5F BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
 16983                              <1> 	; ebx = virtual end address + segment base address - 4K
 16984 00004B64 EBCA                <1>         jmp     short sysexec_8
 16985                              <1> 
 16986                              <1> sysexec_9:
 16987                              <1> 	; 18/10/2015
 16988                              <1> 	; 26/08/2015
 16989                              <1> 	; 25/06/2015
 16990                              <1> 	; move arguments from kernel stack to [ecore]
 16991                              <1> 	; (argument list/line will be copied from kernel stack
 16992                              <1> 	; frame to the last (stack) page of user's core memory)
 16993                              <1> 	; 18/10/2015
 16994 00004B66 8B3D[C4740000]      <1> 	mov	edi, [ecore]
 16995 00004B6C 81C700100000        <1> 	add	edi, PAGE_SIZE
 16996 00004B72 0FB705[CE740000]    <1> 	movzx	eax, word [argc]
 16997 00004B79 09C0                <1> 	or	eax, eax
 16998 00004B7B 7509                <1> 	jnz	short sysexec_10
 16999 00004B7D 89FB                <1> 	mov 	ebx, edi
 17000 00004B7F 83EB04              <1> 	sub	ebx, 4 
 17001 00004B82 8903                <1> 	mov	[ebx], eax ; 0
 17002 00004B84 EB40                <1> 	jmp 	short sysexec_13
 17003                              <1> sysexec_10:
 17004 00004B86 8B0D[80740000]      <1> 	mov	ecx, [u.nread]
 17005                              <1> 	;mov 	esi, [argv}
 17006 00004B8C 89E6                <1> 	mov	esi, esp ; start address of argument list
 17007 00004B8E 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
 17008 00004B90 89C2                <1> 	mov	edx, eax
 17009 00004B92 FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
 17010 00004B94 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
 17011 00004B97 89FB                <1> 	mov	ebx, edi
 17012 00004B99 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
 17013 00004B9C 29D3                <1> 	sub 	ebx, edx
 17014 00004B9E 89FA                <1> 	mov	edx, edi
 17015 00004BA0 F3A4                <1> 	rep	movsb
 17016 00004BA2 89D6                <1> 	mov 	esi, edx
 17017 00004BA4 89DF                <1> 	mov 	edi, ebx
 17018 00004BA6 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
 17019 00004BAB 2B15[C4740000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
 17020 00004BB1 AB                  <1> 	stosd	; eax = argument count	
 17021                              <1> sysexec_11:
 17022 00004BB2 89F0                <1> 	mov	eax, esi
 17023 00004BB4 01D0                <1> 	add	eax, edx
 17024 00004BB6 AB                  <1> 	stosd  ; eax = virtual address
 17025 00004BB7 FE0D[CE740000]      <1> 	dec	byte [argc]
 17026 00004BBD 7407                <1> 	jz	short sysexec_13
 17027                              <1> sysexec_12:
 17028 00004BBF AC                  <1> 	lodsb
 17029 00004BC0 20C0                <1> 	and	al, al
 17030 00004BC2 75FB                <1> 	jnz	short sysexec_12
 17031 00004BC4 EBEC                <1> 	jmp	short sysexec_11
 17032                              <1> 	;
 17033                              <1> 	; 1:
 17034                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
 17035                              <1> 			     ; / pointers to arguments to be passed
 17036                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
 17037                              <1> 			      ; / u.quit = 1 take quit
 17038                              <1> 		; mov $1,u.intr / u.intr determines handling of 
 17039                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
 17040                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
 17041                              <1> 			       ; / system routine
 17042                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector 
 17043                              <1> 			       ; / set to take system routine
 17044                              <1> 		; mov $sstack,sp / stack space used during swapping
 17045                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
 17046                              <1> 		; mov $ecore,r5 / r5 has end of core
 17047                              <1> 		; mov $core,r4 / r4 has start of users core
 17048                              <1> 		; mov r4,u.base / u.base has start of users core
 17049                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
 17050                              <1> 	; 1:
 17051                              <1> 		; tst (r2)+ / argument char = "nul"
 17052                              <1> 		; bne 1b
 17053                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of 
 17054                              <1> 			  ; / end of argument pointer list
 17055                              <1> 	; 1:
 17056                              <1> 	     ; / move arguments to bottom of users core
 17057                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 17058                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
 17059                              <1> 			    ; / ptr list
 17060                              <1> 		; blo 1f / branch to 1f when all arguments
 17061                              <1> 		       ; / are moved
 17062                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 17063                              <1> 	; 2:
 17064                              <1> 		; tstb (r3)+
 17065                              <1> 		; bne 2b / scan argument for \0 (nul)
 17066                              <1> 
 17067                              <1> 	; 2:
 17068                              <1> 		; movb -(r3),-(r5) / move argument char 
 17069                              <1> 				 ; / by char starting at "ecore"
 17070                              <1> 		; cmp r3,(r2) / moved all characters in 
 17071                              <1> 			    ; / this argument
 17072                              <1> 		; bhi 2b / branch 2b if not
 17073                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
 17074                              <1> 			     ; / r5 has pointer to nth arg
 17075                              <1> 		; br 1b / string
 17076                              <1> 	; 1:
 17077                              <1> 		; clrb -(r5)
 17078                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
 17079                              <1> 			; / last word of argument strings
 17080                              <1> 		; mov $core,r2
 17081                              <1> 	
 17082                              <1> 	; 1: / move argument pointers into core following 
 17083                              <1> 	      ; / argument strings
 17084                              <1> 		; cmp r2,r4
 17085                              <1> 		; bhis 1f / branch to 1f when all pointers
 17086                              <1> 			; / are moved
 17087                              <1> 		; mov (r2)+,-(r5)
 17088                              <1> 		; br 1b
 17089                              <1> 	; 1:
 17090                              <1> 		; sub $core,r4 / gives number of arguments *2
 17091                              <1> 		; asr r4 / divide r4 by 2 to calculate 
 17092                              <1> 		       ; / the number of args stored
 17093                              <1> 		; mov r4,-(r5) / save number of arguments ahead
 17094                              <1> 			     ; / of the argument pointers
 17095                              <1> sysexec_13:
 17096                              <1> 	; 19/10/2015
 17097                              <1> 	; 18/10/2015
 17098                              <1> 	; 29/07/2015
 17099                              <1> 	; 25/07/2015
 17100                              <1> 	; 24/07/2015
 17101                              <1> 	; 20/07/2015
 17102                              <1> 	; 25/06/2015
 17103                              <1> 	; 24/06/2015
 17104                              <1> 	; 23/06/2015
 17105                              <1> 	;
 17106                              <1> 	; moving arguments to [ecore] is OK here..
 17107                              <1> 	; 18/10/2015
 17108 00004BC6 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
 17109                              <1> 	; ebx = beginning addres of argument list pointers
 17110                              <1> 	;	in user's stack
 17111                              <1> 	; 19/10/2015
 17112 00004BC8 2B1D[C4740000]      <1> 	sub 	ebx, [ecore]
 17113 00004BCE 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
 17114                              <1> 			; end of core - 4096 (last page)
 17115                              <1> 			; (virtual address)
 17116 00004BD4 891D[D0740000]      <1> 	mov	[argv], ebx
 17117 00004BDA 891D[84740000]      <1> 	mov	[u.break], ebx ; available user memory
 17118                              <1> 	;
 17119 00004BE0 29C0                <1> 	sub	eax, eax
 17120 00004BE2 C705[7C740000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
 17121 00004BEA 0000                <1>
 17122                              <1> 		; mov $14,u.count
 17123 00004BEC C705[68740000]-     <1> 	mov	dword [u.fofp], u.off
 17124 00004BF2 [74740000]          <1>
 17125                              <1> 		; mov $u.off,u.fofp
 17126 00004BF6 A3[74740000]        <1> 	mov	[u.off], eax ; 0
 17127                              <1> 		; clr u.off / set offset in file to be read to zero
 17128                              <1> 	; 25/07/2015
 17129 00004BFB A3[78740000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
 17130                              <1> 	; 25/06/2015 
 17131 00004C00 66A1[3A740000]      <1> 	mov	ax, [ii]
 17132                              <1> 	; AX = i-number of the executable file
 17133 00004C06 E8C10C0000          <1> 	call	readi
 17134                              <1> 		; jsr r0,readi / read in first six words of 
 17135                              <1> 			; / user's file, starting at $core
 17136                              <1> 		; mov sp,r5 / put users stack address in r5
 17137                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
 17138                              <1> 				; / from r5 (leaves number of words
 17139                              <1> 				; / less 26 available for
 17140                              <1> 			     	; / program in user core
 17141                              <1> 		; mov r5,u.count /
 17142                              <1> 	; 25/06/2015
 17143 00004C0B 8B0D[84740000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
 17144 00004C11 890D[7C740000]      <1> 	mov	[u.count], ecx ; save for overrun check
 17145                              <1> 	;
 17146 00004C17 8B0D[80740000]      <1> 	mov	ecx, [u.nread]
 17147 00004C1D 890D[84740000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
 17148 00004C23 80F920              <1> 	cmp	cl, 32
 17149 00004C26 7540                <1>         jne     short sysexec_15
 17150                              <1> 	;:
 17151                              <1> 	; 25/06/2015
 17152                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
 17153                              <1> 	; 18/10/2015
 17154 00004C28 8B35[C0740000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
 17155                              <1> 		             ; (phys. start addr. of the exec. file)
 17156 00004C2E AD                  <1> 	lodsd
 17157 00004C2F 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
 17158 00004C33 7533                <1> 	jne	short sysexec_15
 17159                              <1> 		; cmp core,$405 / br .+14 is first instruction 
 17160                              <1> 			      ; / if file is standard a.out format
 17161                              <1> 		; bne 1f / branch, if not standard format
 17162 00004C35 AD                  <1> 	lodsd
 17163 00004C36 89C1                <1> 	mov	ecx, eax ; text (code) section size
 17164 00004C38 AD                  <1> 	lodsd
 17165 00004C39 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
 17166                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
 17167                              <1> 		              ; / number of bytes in program text	
 17168                              <1> 		; sub $14,r5 / subtract 12
 17169 00004C3B 89CB                <1> 	mov	ebx, ecx
 17170                              <1> 	;
 17171                              <1> 	; 25/06/2015
 17172                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
 17173                              <1> 	;	and SINGLIX operating systems (as code template).
 17174                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
 17175                              <1> 	;	due to RUFS (floppy disk file system) restriction...
 17176                              <1> 	;	Overrun is not possible for current version. 	
 17177                              <1> 	;
 17178 00004C3D AD                  <1> 	lodsd	
 17179 00004C3E 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
 17180 00004C40 3B1D[7C740000]      <1> 	cmp	ebx, [u.count]
 17181 00004C46 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
 17182                              <1> 	;
 17183                              <1> 	; 24/07/2015
 17184                              <1> 	; add bss section size to [u.break]
 17185 00004C48 0105[84740000]      <1> 	add 	[u.break], eax
 17186                              <1> 	;
 17187 00004C4E 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
 17188                              <1> 	;cmp	ecx, [u.count]
 17189                              <1> 	;jnb	short sysexec_16
 17190                              <1> 		; cmp r5,u.count /
 17191                              <1> 		; bgt 1f / branch if r5 greater than u.count
 17192 00004C51 890D[7C740000]      <1> 	mov	[u.count], ecx ; required read count
 17193                              <1> 		; mov r5,u.count
 17194                              <1> 	;
 17195 00004C57 EB2A                <1> 	jmp	short sysexec_16
 17196                              <1> 	;
 17197                              <1> sysexec_14:
 17198                              <1> 	; 23/06/2015
 17199                              <1> 	; insufficient (out of) memory
 17200 00004C59 C705[A7740000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
 17201 00004C61 0000                <1>
 17202 00004C63 E9E5F3FFFF          <1> 	jmp	error
 17203                              <1> 	;
 17204                              <1> sysexec_15:
 17205                              <1> 	; 25/06/2015
 17206 00004C68 0FB715[2A710000]    <1>         movzx   edx, word [i.size] ; file size
 17207 00004C6F 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
 17208 00004C71 7627                <1> 	jna	short sysexec_17 ; no need to next read
 17209 00004C73 01D1                <1> 	add	ecx, edx ; [i.size]
 17210 00004C75 3B0D[7C740000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
 17211 00004C7B 77DC                <1> 	ja	short sysexec_14
 17212 00004C7D 8915[7C740000]      <1> 	mov	[u.count], edx
 17213                              <1> sysexec_16:
 17214 00004C83 66A1[3A740000]      <1> 	mov	ax, [ii] ; i-number
 17215 00004C89 E83E0C0000          <1> 	call	readi
 17216                              <1> 		; add core+10,u.nread / add size of user data area 
 17217                              <1> 		                    ; / to u.nread
 17218                              <1> 		; br 2f
 17219                              <1> 	; 1:
 17220                              <1> 		; jsr r0,readi / read in rest of file
 17221                              <1> 	; 2:
 17222 00004C8E 8B0D[80740000]      <1> 	mov	ecx, [u.nread]
 17223 00004C94 010D[84740000]      <1> 	add	[u.break], ecx
 17224                              <1> 		; mov u.nread,u.break / set users program break to end of 
 17225                              <1> 				    ; / user code
 17226                              <1> 		; add $core+14,u.break / plus data area
 17227                              <1> sysexec_17: ; 20/07/2015
 17228                              <1> 	;mov	ax, [ii] ;rgc i-number
 17229 00004C9A E8F9120000          <1> 	call	iclose
 17230                              <1> 		; jsr r0,iclose / does nothing
 17231 00004C9F 31C0                <1>         xor     eax, eax
 17232 00004CA1 FEC0                <1> 	inc	al
 17233 00004CA3 66A3[96740000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
 17234 00004CA9 66A3[98740000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
 17235                              <1> 	; 02/07/2015
 17236 00004CAF 833D[AF740000]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller sys_init (kernel) ?
 17237 00004CB6 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
 17238                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
 17239 00004CB8 8B15[78700000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
 17240 00004CBE 8915[AF740000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here 
 17241                              <1> sysexec_18:
 17242                              <1> 	; 18/10/2015
 17243                              <1> 	; 05/08/2015
 17244                              <1> 	; 29/07/2015
 17245 00004CC4 8B2D[D0740000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
 17246                              <1> 			    ; list pointers (argument count)
 17247 00004CCA FA                  <1> 	cli
 17248 00004CCB 8B25[14700000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
 17249                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
 17250                              <1> 			    ; for this process	 
 17251                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
 17252                              <1> 	;xor	eax, eax ; 0
 17253 00004CD1 FEC8                <1> 	dec	al ; eax = 0
 17254 00004CD3 66BA2300            <1> 	mov	dx, UDATA
 17255 00004CD7 6652                <1> 	push	dx  ; user's stack segment
 17256 00004CD9 55                  <1> 	push	ebp ; user's stack pointer
 17257                              <1> 		    ; (points to number of arguments)
 17258 00004CDA FB                  <1> 	sti
 17259 00004CDB 9C                  <1> 	pushfd	; EFLAGS
 17260                              <1> 		; Set IF for enabling interrupts in user mode	
 17261                              <1> 	;or	dword [esp], 200h 
 17262                              <1> 	;
 17263                              <1> 	;mov	bx, UCODE
 17264                              <1> 	;push	bx ; user's code segment
 17265 00004CDC 6A1B                <1> 	push	UCODE
 17266                              <1> 	;push	0
 17267 00004CDE 50                  <1> 	push	eax ; EIP (=0) - start address -	
 17268                              <1> 		; clr -(r5) / popped into ps when rti in 
 17269                              <1> 			  ; / sysrele is executed
 17270                              <1> 		; mov $core,-(r5) / popped into pc when rti 
 17271                              <1> 		                ; / in sysrele is executed
 17272                              <1> 		;mov r5,0f / load second copyz argument
 17273                              <1> 		;tst -(r5) / decrement r5
 17274 00004CDF 8925[50740000]      <1> 	mov	[u.sp], esp ; 29/07/2015
 17275                              <1> 	; 05/08/2015
 17276                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
 17277                              <1> 	; ('push dx' would cause to general protection fault, 
 17278                              <1> 	; after 'pop ds' etc.)
 17279                              <1> 	;
 17280                              <1> 	;; push dx ; ds (UDATA)
 17281                              <1> 	;; push dx ; es (UDATA)
 17282                              <1> 	;; push dx ; fs (UDATA)
 17283                              <1> 	;; push dx ; gs (UDATA)
 17284                              <1> 	;
 17285                              <1> 	; This is a trick to prevent general protection fault
 17286                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
 17287 00004CE5 8EC2                <1> 	mov 	es, dx ; UDATA
 17288 00004CE7 06                  <1> 	push 	es ; ds (UDATA)
 17289 00004CE8 06                  <1> 	push 	es ; es (UDATA)
 17290 00004CE9 06                  <1> 	push 	es ; fs (UDATA)
 17291 00004CEA 06                  <1> 	push	es ; gs (UDATA)
 17292 00004CEB 66BA1000            <1> 	mov	dx, KDATA
 17293 00004CEF 8EC2                <1> 	mov	es, dx
 17294                              <1> 	;
 17295                              <1> 	;; pushad simulation
 17296 00004CF1 89E5                <1> 	mov	ebp, esp ; esp before pushad
 17297 00004CF3 50                  <1> 	push	eax ; eax (0)
 17298 00004CF4 50                  <1> 	push	eax ; ecx (0)
 17299 00004CF5 50                  <1> 	push	eax ; edx (0)
 17300 00004CF6 50                  <1> 	push	eax ; ebx (0)
 17301 00004CF7 55                  <1> 	push	ebp ; esp before pushad
 17302 00004CF8 50                  <1> 	push	eax ; ebp (0)
 17303 00004CF9 50                  <1> 	push	eax ; esi (0)		
 17304 00004CFA 50                  <1> 	push	eax ; edi (0)	
 17305                              <1> 	;
 17306 00004CFB A3[58740000]        <1> 	mov	[u.r0], eax ; eax = 0
 17307 00004D00 8925[54740000]      <1> 	mov	[u.usp], esp
 17308                              <1> 		; mov r5,u.r0 /
 17309                              <1> 		; sub $16.,r5 / skip 8 words
 17310                              <1> 		; mov r5,u.sp / assign user stack pointer value, 
 17311                              <1> 		;             / effectively zeroes all regs
 17312                              <1> 			    ; / when sysrele is executed
 17313                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
 17314                              <1> 		; clr u.break
 17315                              <1> 		; mov r5,sp / point sp to user's stack
 17316                              <1> 	;
 17317 00004D06 E965F3FFFF          <1> 	jmp	sysret0
 17318                              <1> 	;jmp	sysret
 17319                              <1> 		; br sysret3 / return to core image at $core
 17320                              <1> 
 17321                              <1> get_argp:
 17322                              <1> 	; 18/10/2015 (nbase, ncount)
 17323                              <1> 	; 21/07/2015
 17324                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
 17325                              <1> 	; Get (virtual) address of argument from user's core memory
 17326                              <1> 	;
 17327                              <1> 	; INPUT:
 17328                              <1> 	;	esi = virtual address of argument pointer
 17329                              <1> 	; OUTPUT:
 17330                              <1> 	;	eax = virtual address of argument
 17331                              <1> 	;
 17332                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
 17333                              <1> 	;
 17334 00004D0B 833D[AF740000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
 17335                              <1> 				    ; (the caller is kernel)
 17336 00004D12 7667                <1>         jna     short get_argpk 
 17337                              <1> 	;
 17338 00004D14 89F3                <1>      	mov	ebx, esi
 17339 00004D16 E86DE9FFFF          <1> 	call	get_physical_addr ; get physical address
 17340 00004D1B 0F8289000000        <1>         jc      get_argp_err
 17341 00004D21 A3[C8740000]        <1> 	mov 	[nbase], eax ; physical address	
 17342 00004D26 66890D[CC740000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
 17343 00004D2D B804000000          <1> 	mov	eax, 4 ; 21/07/2015
 17344 00004D32 6639C1              <1> 	cmp	cx, ax ; 4
 17345 00004D35 735D                <1> 	jnb	short get_argp2
 17346 00004D37 89F3                <1> 	mov	ebx, esi
 17347 00004D39 01CB                <1> 	add	ebx, ecx
 17348 00004D3B E848E9FFFF          <1> 	call	get_physical_addr ; get physical address
 17349 00004D40 7268                <1> 	jc	short get_argp_err
 17350                              <1> 	;push	esi
 17351 00004D42 89C6                <1> 	mov	esi, eax
 17352 00004D44 66870D[CC740000]    <1> 	xchg	cx, [ncount]
 17353 00004D4B 8735[C8740000]      <1> 	xchg	esi, [nbase]
 17354 00004D51 B504                <1> 	mov	ch, 4
 17355 00004D53 28CD                <1> 	sub	ch, cl
 17356                              <1> get_argp0:
 17357 00004D55 AC                  <1> 	lodsb
 17358 00004D56 6650                <1> 	push	ax
 17359 00004D58 FEC9                <1> 	dec	cl
 17360 00004D5A 75F9                <1>         jnz     short get_argp0
 17361 00004D5C 8B35[C8740000]      <1> 	mov	esi, [nbase]
 17362                              <1> 	; 21/07/2015
 17363 00004D62 0FB6C5              <1> 	movzx	eax, ch
 17364 00004D65 0105[C8740000]      <1> 	add	[nbase], eax
 17365 00004D6B 662905[CC740000]    <1> 	sub	[ncount], ax
 17366                              <1> get_argp1:
 17367 00004D72 AC                  <1> 	lodsb
 17368 00004D73 FECD                <1> 	dec	ch
 17369 00004D75 743D                <1>         jz      short get_argp3
 17370 00004D77 6650                <1>         push	ax
 17371 00004D79 EBF7                <1> 	jmp     short get_argp1
 17372                              <1> get_argpk:
 17373                              <1> 	; Argument is in kernel's memory space
 17374 00004D7B 66C705[CC740000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
 17375 00004D83 10                  <1>
 17376 00004D84 8935[C8740000]      <1> 	mov	[nbase], esi
 17377 00004D8A 8305[C8740000]04    <1> 	add	dword [nbase], 4
 17378 00004D91 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
 17379 00004D93 C3                  <1> 	retn
 17380                              <1> get_argp2:
 17381                              <1> 	; 21/07/2015
 17382                              <1> 	;mov	eax, 4
 17383 00004D94 8B15[C8740000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
 17384 00004D9A 0105[C8740000]      <1> 	add	[nbase], eax
 17385 00004DA0 662905[CC740000]    <1> 	sub	[ncount], ax
 17386                              <1> 	;
 17387 00004DA7 8B02                <1> 	mov	eax, [edx]
 17388 00004DA9 C3                  <1> 	retn
 17389                              <1> get_argp_err:
 17390 00004DAA A3[A7740000]        <1> 	mov	[u.error], eax
 17391 00004DAF E999F2FFFF          <1> 	jmp	error
 17392                              <1> get_argp3:
 17393 00004DB4 B103                <1> 	mov	cl, 3
 17394                              <1> get_argp4:
 17395 00004DB6 C1E008              <1> 	shl	eax, 8
 17396 00004DB9 665A                <1> 	pop	dx
 17397 00004DBB 88D0                <1> 	mov 	al, dl
 17398 00004DBD E2F7                <1>         loop    get_argp4
 17399                              <1> 	;pop	esi
 17400 00004DBF C3                  <1> 	retn	
 17401                              <1> 
 17402                              <1> sysfstat: 
 17403                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17404                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17405                              <1> 	;
 17406                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
 17407                              <1> 	; on open files instead of files given by name. It puts the
 17408                              <1> 	; buffer address on the stack, gets the i-number and
 17409                              <1> 	; checks to see if the file is open for reading or writing.
 17410                              <1> 	; If the file is open for writing (i-number is negative)
 17411                              <1> 	; the i-number is set positive and a branch into 'sysstat'
 17412                              <1> 	; is made.	
 17413                              <1> 	;
 17414                              <1> 	; Calling sequence:
 17415                              <1> 	;	sysfstat; buf
 17416                              <1> 	; Arguments:
 17417                              <1> 	;	buf - buffer address
 17418                              <1> 	;
 17419                              <1> 	; Inputs: *u.r0 - file descriptor
 17420                              <1> 	; Outputs: buffer is loaded with file information
 17421                              <1> 	; ...............................................................
 17422                              <1> 	;				
 17423                              <1> 	; Retro UNIX 8086 v1 modification:
 17424                              <1> 	;       'sysfstat' system call has two arguments; so,
 17425                              <1> 	;	* 1st argument, file descriptor is in BX register
 17426                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 17427                              <1> 
 17428                              <1> 	; / set status of open file
 17429                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
 17430 00004DC0 51                  <1> 	push	ecx
 17431                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
 17432                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
 17433                              <1> 		; jsr r0,getf / get the files i-number
 17434                              <1> 	; BX = file descriptor (file number)
 17435 00004DC1 E8FF000000          <1> 	call	getf1
 17436 00004DC6 6621C0              <1> 	and	ax, ax ; i-number of the file
 17437                              <1> 		; tst	r1 / is it 0?
 17438                              <1> 	;jz	error
 17439                              <1> 		; beq error3 / yes, error
 17440 00004DC9 750F                <1> 	jnz	short sysfstat1
 17441 00004DCB C705[A7740000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 17442 00004DD3 0000                <1>
 17443 00004DD5 E973F2FFFF          <1> 	jmp	error
 17444                              <1> sysfstat1:
 17445 00004DDA 80FC80              <1> 	cmp	ah, 80h
 17446 00004DDD 7223                <1>         jb      short sysstat1
 17447                              <1> 		; bgt 1f / if i-number is negative (open for writing)
 17448 00004DDF 66F7D8              <1> 	neg	ax
 17449                              <1> 		; neg r1 / make it positive, then branch
 17450 00004DE2 EB1E                <1> 	jmp	short sysstat1
 17451                              <1> 		; br 1f / to 1f
 17452                              <1> sysstat:
 17453                              <1> 	; 18/10/2015
 17454                              <1> 	; 07/10/2015
 17455                              <1> 	; 02/09/2015
 17456                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17457                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17458                              <1> 	;
 17459                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
 17460                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
 17461                              <1> 	; long and information about the file placed in it.	
 17462                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
 17463                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
 17464                              <1> 	; is then loaded and the results are given in the UNIX
 17465                              <1> 	; Programmers Manual sysstat (II).	
 17466                              <1> 	;
 17467                              <1> 	; Calling sequence:
 17468                              <1> 	;	sysstat; name; buf
 17469                              <1> 	; Arguments:
 17470                              <1> 	;	name - points to the name of the file
 17471                              <1> 	;	buf - address of a 34 bytes buffer
 17472                              <1> 	; Inputs: -
 17473                              <1> 	; Outputs: buffer is loaded with file information
 17474                              <1> 	; ...............................................................
 17475                              <1> 	;				
 17476                              <1> 	; Retro UNIX 8086 v1 modification: 
 17477                              <1> 	;       'sysstat' system call has two arguments; so,
 17478                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 17479                              <1> 	;	to get sysstat system call arguments from the user;
 17480                              <1> 	;	* 1st argument, name is pointed to by BX register
 17481                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 17482                              <1> 	;
 17483                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 17484                              <1> 	;	      arguments which were in these registers;
 17485                              <1> 	;	      but, it returns by putting the 1st argument
 17486                              <1> 	;	      in 'u.namep' and the 2nd argument
 17487                              <1> 	;	      on top of stack. (1st argument is offset of the
 17488                              <1> 	;	      file/path name in the user's program segment.)		 	
 17489                              <1> 	
 17490                              <1> 	; / ; name of file; buffer - get files status
 17491                              <1> 		; jsr r0,arg2 / get the 2 arguments
 17492 00004DE4 891D[70740000]      <1> 	mov	[u.namep], ebx
 17493 00004DEA 51                  <1> 	push	ecx
 17494 00004DEB E80C010000          <1> 	call	namei
 17495                              <1> 		; jsr r0,namei / get the i-number for the file
 17496                              <1> 	;jc	error
 17497                              <1> 		; br error3 / no such file, error
 17498 00004DF0 7310                <1> 	jnc	short sysstat1
 17499                              <1> 	; pop 	ecx
 17500                              <1> sysstat_err0:
 17501                              <1> 	; 'file not found !' error
 17502 00004DF2 C705[A7740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17503 00004DFA 0000                <1>
 17504 00004DFC E94CF2FFFF          <1> 	jmp	error
 17505                              <1> 
 17506 00004E01 00                  <1> statx: db 0
 17507                              <1> 
 17508                              <1> sysstat1: ; 1:
 17509 00004E02 E8E5080000          <1> 	call	iget
 17510                              <1> 		; jsr r0,iget / get the i-node into core
 17511                              <1> 	; 07/10/2015 (ax = [ii], inode number)
 17512                              <1> 	; 02/09/2015
 17513 00004E07 8F05[78740000]      <1> 	pop	dword [u.base]
 17514                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
 17515 00004E0D E858000000          <1> 	call	sysstat_gpa ; get physical address
 17516 00004E12 730A                <1> 	jnc 	short sysstat2
 17517                              <1> sysstat_err1:
 17518 00004E14 A3[A7740000]        <1> 	mov	dword [u.error], eax ; error code
 17519 00004E19 E92FF2FFFF          <1> 	jmp	error
 17520                              <1> sysstat2:
 17521 00004E1E A0[3A740000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
 17522 00004E23 AA                  <1> 	stosb
 17523 00004E24 FF05[78740000]      <1> 	inc 	dword [u.base]
 17524 00004E2A 6649                <1> 	dec 	cx
 17525 00004E2C 7505                <1> 	jnz	short sysstat3
 17526 00004E2E E837000000          <1> 	call	sysstat_gpa
 17527                              <1> 	;jc	short sysstat_err1
 17528                              <1> sysstat3:
 17529 00004E33 A0[3B740000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
 17530 00004E38 AA                  <1> 	stosb
 17531                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
 17532 00004E39 FF05[78740000]      <1> 	inc 	dword [u.base]
 17533                              <1> 	;dec 	word [u.pcount]
 17534 00004E3F 6649                <1> 	dec	cx
 17535 00004E41 7505                <1> 	jnz	short sysstat4
 17536 00004E43 E822000000          <1> 	call	sysstat_gpa
 17537                              <1> 	;jc	short sysstat_err1	
 17538                              <1> sysstat4:
 17539 00004E48 BE[26710000]        <1> 	mov	esi, inode
 17540                              <1> 		; mov $inode,r2 / r2 points to i-node
 17541                              <1> sysstat5: ; 1:
 17542 00004E4D A4                  <1> 	movsb
 17543                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
 17544 00004E4E FF05[78740000]      <1> 	inc 	dword [u.base]
 17545                              <1> 	;dec 	word [u.pcount]
 17546 00004E54 6649                <1> 	dec	cx
 17547 00004E56 7505                <1> 	jnz	short sysstat6
 17548 00004E58 E80D000000          <1> 	call	sysstat_gpa
 17549                              <1> 	;jc	short sysstat_err1
 17550                              <1> sysstat6:		
 17551 00004E5D 81FE[46710000]      <1> 	cmp	esi, inode + 32
 17552                              <1> 		; cmp r2,$inode+32 / done?
 17553 00004E63 75E8                <1> 	jne	short sysstat5
 17554                              <1> 		; bne 1b / no, go back
 17555 00004E65 E903F2FFFF          <1> 	jmp	sysret
 17556                              <1> 		; br sysret3 / return through sysret
 17557                              <1> 	;
 17558                              <1> sysstat_gpa: ; get physical address of file status buffer
 17559                              <1> 	; 02/09/2015
 17560 00004E6A 8B1D[78740000]      <1> 	mov 	ebx, [u.base]
 17561                              <1> 	; 07/10/2015
 17562 00004E70 E813E8FFFF          <1> 	call	get_physical_addr ; get physical address
 17563                              <1> 	;jc	short sysstat_gpa1
 17564 00004E75 729D                <1> 	jc	short sysstat_err1
 17565                              <1> 	; 18/10/2015
 17566 00004E77 89C7                <1> 	mov	edi, eax ; physical address
 17567                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
 17568                              <1> ;sysstat_gpa1:
 17569 00004E79 C3                  <1> 	retn
 17570                              <1> 
 17571                              <1> fclose:
 17572                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
 17573                              <1> 	;            (32 bit offset pointer modification)
 17574                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
 17575                              <1> 	;
 17576                              <1> 	; Given the file descriptor (index to the u.fp list)
 17577                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
 17578                              <1> 	; If i-node is active (i-number > 0) the entry in 
 17579                              <1> 	; u.fp list is cleared. If all the processes that opened
 17580                              <1> 	; that file close it, then fsp etry is freed and the file
 17581                              <1> 	; is closed. If not a return is taken. 
 17582                              <1> 	; If the file has been deleted while open, 'anyi' is called
 17583                              <1> 	; to see anyone else has it open, i.e., see if it is appears
 17584                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
 17585                              <1> 	; a check is made to see if the file is special.	
 17586                              <1> 	;
 17587                              <1> 	; INPUTS ->
 17588                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
 17589                              <1> 	;    u.fp - list of entries in the fsp table
 17590                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
 17591                              <1> 	; OUTPUTS ->
 17592                              <1> 	;    r1 - contains the same file descriptor
 17593                              <1> 	;    r2 - contains i-number
 17594                              <1> 	;
 17595                              <1> 	; ((AX = R1))
 17596                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
 17597                              <1> 	;
 17598                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
 17599                              <1> 	;              if i-number of the file is 0. (error)  	
 17600                              <1> 	;
 17601 00004E7A 0FB7D0              <1> 	movzx	edx, ax ; **
 17602 00004E7D 6650                <1> 	push	ax ; ***
 17603                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
 17604                              <1> 			     ; / the index to u.fp list)
 17605 00004E7F E83F000000          <1> 	call	getf
 17606                              <1> 		; jsr r0,getf / r1 contains i-number, 
 17607                              <1> 			    ; / cdev has device =, u.fofp 
 17608                              <1> 			    ; / points to 3rd word of fsp entry
 17609 00004E84 6683F801            <1> 	cmp	ax, 1 ; r1
 17610                              <1> 		; tst r1 / is i-number 0?
 17611 00004E88 7236                <1> 	jb	short fclose_2
 17612                              <1> 		; beq 1f / yes, i-node not active so return
 17613                              <1> 		; tst (r0)+ / no, jump over error return
 17614 00004E8A 89D3                <1> 	mov	ebx, edx ; **
 17615 00004E8C 6689C2              <1> 	mov 	dx, ax ; *
 17616                              <1> 		; mov r1,r2 / move i-number to r2 ;*
 17617                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
 17618                              <1> 			    ; / which is index to u.fp ; **
 17619 00004E8F C683[5E740000]00    <1> 	mov	byte [ebx+u.fp], 0
 17620                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
 17621 00004E96 8B1D[68740000]      <1> 	mov	ebx, [u.fofp]
 17622                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
 17623                              <1> fclose_0:
 17624 00004E9C FE4B04              <1> 	dec	byte [ebx+4] ; 18/06/2015
 17625                              <1> 		; decb 2(r1) / decrement the number of processes 
 17626                              <1> 			   ; / that have opened the file
 17627 00004E9F 791F                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
 17628                              <1> 		; bge 1f / if all processes haven't closed the file, return
 17629                              <1> 	;
 17630 00004EA1 6652                <1> 	push	dx ;*
 17631                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
 17632 00004EA3 6631C0              <1> 	xor	ax, ax ; 0
 17633 00004EA6 668943FC            <1> 	mov	[ebx-4], ax ; 0
 17634                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
 17635 00004EAA 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
 17636                              <1> 		; tstb	3(r1) / has this file been deleted
 17637 00004EAD 20C0                <1> 	and	al, al
 17638 00004EAF 7408                <1> 	jz	short fclose_1
 17639                              <1> 		; beq 2f / no, branch
 17640 00004EB1 6689D0              <1> 	mov	ax, dx ; *
 17641                              <1> 		; mov r2,r1 / yes, put i-number back into r1
 17642                              <1> 	; AX = inode number
 17643 00004EB4 E868040000          <1> 	call	anyi
 17644                              <1> 		; jsr r0,anyi / free all blocks related to i-number
 17645                              <1> 			    ; / check if file appears in fsp again
 17646                              <1> fclose_1: ; 2:
 17647 00004EB9 6658                <1> 	pop	ax ; *
 17648                              <1> 		; mov (sp)+,r1 / put i-number back into r1
 17649 00004EBB E8D8100000          <1> 	call	iclose ; close if it is special file 
 17650                              <1> 		; jsr r0,iclose / check to see if its a special file
 17651                              <1> fclose_2: ; 1:
 17652 00004EC0 6658                <1> 	pop	ax ; ***
 17653                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
 17654 00004EC2 C3                  <1> 	retn
 17655                              <1> 		; rts r0
 17656                              <1> 
 17657                              <1> getf:	; / get the device number and the i-number of an open file
 17658                              <1> 	; 13/05/2015
 17659                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 17660                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 17661                              <1> 	;
 17662 00004EC3 89C3                <1> 	mov	ebx, eax
 17663                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
 17664 00004EC5 83FB0A              <1> 	cmp	ebx, 10
 17665                              <1> 		; cmp r1,$10. / user limited to 10 open files
 17666 00004EC8 730A                <1>         jnb	short getf2 ; 13/05/2015
 17667                              <1> 	;jnb     error
 17668                              <1> 		; bhis error3 / u.fp is table of users open files, 
 17669                              <1> 			    ; / index in fsp table
 17670 00004ECA 8A9B[5E740000]      <1> 	mov	bl, [ebx+u.fp]
 17671                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
 17672                              <1> 		                  ; / in fsp table
 17673 00004ED0 08DB                <1> 	or	bl, bl
 17674 00004ED2 7503                <1> 	jnz	short getf3
 17675                              <1> 	;jz	short getf4
 17676                              <1> 		; beq 1f / if its zero return
 17677                              <1> getf2:
 17678                              <1> 	; 'File not open !' error (ax=0)
 17679 00004ED4 29C0                <1> 	sub	eax, eax
 17680 00004ED6 C3                  <1> 	retn
 17681                              <1> getf3:	
 17682                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
 17683                              <1> 	;
 17684                              <1> 	; 'fsp' table (10 bytes/entry)
 17685                              <1> 	; bit 15				   bit 0
 17686                              <1> 	; ---|-------------------------------------------
 17687                              <1> 	; r/w|		i-number of open file
 17688                              <1> 	; ---|-------------------------------------------
 17689                              <1> 	;		   device number
 17690                              <1> 	; -----------------------------------------------
 17691                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 17692                              <1> 	; -----------------------------------------------
 17693                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 17694                              <1> 	; ----------------------|------------------------
 17695                              <1> 	;  flag that says file 	| number of processes
 17696                              <1> 	;   has been deleted	| that have file open 
 17697                              <1> 	; ----------------------|------------------------
 17698                              <1> 	;
 17699 00004ED7 B80A000000          <1> 	mov	eax, 10
 17700 00004EDC F6E3                <1> 	mul	bl
 17701 00004EDE BB[20720000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
 17702 00004EE3 01C3                <1> 	add	ebx, eax
 17703                              <1> 		; asl r1
 17704                              <1> 		; asl r1 / multiply by 8 to get index into 
 17705                              <1> 		       ; / fsp table entry
 17706                              <1> 		; asl r1
 17707                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
 17708                              <1> 			      ; / in the fsp entry
 17709 00004EE5 891D[68740000]      <1> 	mov	[u.fofp], ebx
 17710                              <1> 		; mov r1,u.fofp / save address of 3rd word 
 17711                              <1> 			      ; / in fsp entry in u.fofp
 17712 00004EEB 4B                  <1> 	dec	ebx
 17713 00004EEC 4B                  <1> 	dec	ebx
 17714 00004EED 668B03              <1> 	mov	ax, [ebx]
 17715                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
 17716 00004EF0 66A3[3E740000]      <1> 	mov	[cdev], ax ; ;;in fact (!) 
 17717                              <1> 			     ;;dev number is in 1 byte
 17718                              <1> 		; mov -(r1),cdev / remove the device number  cdev
 17719 00004EF6 4B                  <1> 	dec	ebx
 17720 00004EF7 4B                  <1> 	dec	ebx
 17721 00004EF8 668B03              <1> 	mov	ax, [ebx]
 17722                              <1> 		; mov -(r1),r1 / and the i-number  r1
 17723                              <1> getf4:	; 1:
 17724 00004EFB C3                  <1> 	retn
 17725                              <1> 		; rts r0
 17726                              <1> 
 17727                              <1> namei:
 17728                              <1> 	; 18/10/2015 (nbase, ncount)
 17729                              <1> 	; 12/10/2015
 17730                              <1> 	; 21/08/2015
 17731                              <1> 	; 18/07/2015
 17732                              <1> 	; 02/07/2015
 17733                              <1> 	; 17/06/2015
 17734                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
 17735                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 17736                              <1> 	;
 17737                              <1> 	; 'namei' takes a file path name and returns i-number of
 17738                              <1> 	; the file in the current directory or the root directory
 17739                              <1> 	; (if the first character of the pathname is '/').	
 17740                              <1> 	;
 17741                              <1> 	; INPUTS ->
 17742                              <1> 	;    u.namep - points to a file path name
 17743                              <1> 	;    u.cdir - i-number of users directory
 17744                              <1> 	;    u.cdev - device number on which user directory resides	
 17745                              <1> 	; OUTPUTS ->
 17746                              <1> 	;    r1 - i-number of file
 17747                              <1> 	;    cdev
 17748                              <1> 	;    u.dirbuf - points to directory entry where a match 
 17749                              <1> 	;               occurs in the search for file path name.
 17750                              <1> 	;	        If no match u.dirb points to the end of 
 17751                              <1> 	;               the directory and r1 = i-number of the current
 17752                              <1> 	;	        directory.	
 17753                              <1> 	; ((AX = R1))
 17754                              <1> 	;
 17755                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
 17756                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 17757                              <1> 	;
 17758                              <1> 
 17759 00004EFC 66A1[5C740000]      <1> 	mov	ax, [u.cdir]
 17760                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
 17761                              <1> 			      ; / in r1
 17762 00004F02 668B15[9C740000]    <1> 	mov	dx, [u.cdrv]
 17763 00004F09 668915[3E740000]    <1> 	mov	[cdev], dx 	    ; NOTE: Retro UNIX 8086 v1 
 17764                              <1> 				    ; device/drive number is in 1 byte, 
 17765                              <1> 				    ; not in 1 word!
 17766                              <1> 		; mov u.cdev,cdev / device number for users directory 
 17767                              <1> 				; / into cdev
 17768                              <1> 	; 12/10/2015
 17769                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 17770                              <1>       	 ; convert virtual (pathname) addr to physical address
 17771 00004F10 E82C010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
 17772                              <1> 		; esi = physical address of [u.namep]
 17773                              <1> 		; ecx = byte count in the page
 17774 00004F15 803E2F              <1> 	cmp	byte [esi], '/'
 17775                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
 17776 00004F18 751E                <1> 	jne	short namei_1
 17777                              <1> 		; bne 1f
 17778 00004F1A FF05[70740000]      <1> 	inc	dword [u.namep]
 17779                              <1> 		; inc u.namep / go to next char
 17780 00004F20 6649                <1> 	dec	cx ; remain byte count in the page
 17781 00004F22 7506                <1> 	jnz	short namei_0
 17782                              <1> 	; 12/10/2015
 17783 00004F24 E818010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 17784                              <1> 		; esi = physical address (page start + offset)
 17785                              <1> 		; ecx = byte count in the page
 17786 00004F29 4E                  <1> 	dec	esi
 17787                              <1> namei_0:
 17788 00004F2A 46                  <1> 	inc 	esi  ; go to next char
 17789 00004F2B 66A1[48740000]      <1> 	mov	ax, [rootdir] ; 09/07/2013
 17790                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
 17791 00004F31 C605[3E740000]00    <1> 	mov	byte [cdev], 0
 17792                              <1> 		; clr cdev / clear device number
 17793                              <1> namei_1: ; 1:
 17794 00004F38 F606FF              <1> 	test	byte [esi], 0FFh
 17795 00004F3B 74BE                <1> 	jz	short getf4
 17796                              <1> 	;jz      nig
 17797                              <1> 		; tstb *u.namep / is the character in file name a nul
 17798                              <1> 		; beq nig / yes, end of file name reached; 
 17799                              <1> 			; / branch to "nig"
 17800                              <1> namei_2: ; 1:
 17801                              <1> 	; 18/10/2015
 17802 00004F3D 8935[C8740000]      <1> 	mov 	[nbase], esi
 17803 00004F43 66890D[CC740000]    <1> 	mov 	[ncount], cx
 17804                              <1> 	;
 17805                              <1> 	;mov	dx, 2
 17806 00004F4A B202                <1> 	mov	dl, 2 ; user flag (read, non-owner)
 17807 00004F4C E876080000          <1> 	call	access
 17808                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
 17809                              <1> 	; 'access' will not return here if user has not "r" permission !
 17810 00004F51 66F705[26710000]00- <1> 	test 	word [i.flgs], 4000h
 17811 00004F59 40                  <1>
 17812                              <1> 		; bit $40000,i.flgs / directory i-node?
 17813 00004F5A 746A                <1>         jz      short namei_err
 17814                              <1> 		; beq error3 / no, got an error
 17815                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 17816 00004F5C 31C0                <1> 	xor	eax, eax
 17817 00004F5E A3[74740000]        <1> 	mov	[u.off], eax ; 0
 17818 00004F63 66A1[2A710000]      <1> 	mov	ax, [i.size]
 17819 00004F69 A3[6C740000]        <1> 	mov	[u.dirp], eax
 17820                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
 17821                              <1> 		; clr u.off / u.off is file offset used by user
 17822 00004F6E C705[68740000]-     <1> 	mov	dword [u.fofp], u.off
 17823 00004F74 [74740000]          <1>
 17824                              <1> 		; mov $u.off,u.fofp / u.fofp is a pointer to 
 17825                              <1> 				  ; / the offset portion of fsp entry
 17826                              <1> namei_3: ; 2:
 17827 00004F78 C705[78740000]-     <1> 	mov	dword [u.base], u.dirbuf
 17828 00004F7E [8A740000]          <1>
 17829                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
 17830                              <1> 				    ; / copied from a directory
 17831 00004F82 C705[7C740000]0A00- <1> 	mov 	dword [u.count], 10 	
 17832 00004F8A 0000                <1>
 17833                              <1>  		; mov $10.,u.count / u.count is byte count 
 17834                              <1> 				 ; / for reads and writes
 17835 00004F8C 66A1[3A740000]      <1> 	mov 	ax, [ii]
 17836                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
 17837 00004F92 FE05[B9740000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
 17838 00004F98 E82F090000          <1>     	call	readi
 17839                              <1> 		; jsr r0,readi / read 10. bytes of file 
 17840                              <1> 		      ; with i-number (r1); i.e. read a directory entry
 17841 00004F9D 8B0D[80740000]      <1> 	mov 	ecx, [u.nread]
 17842 00004FA3 09C9                <1> 	or 	ecx, ecx
 17843                              <1> 		; tst u.nread
 17844 00004FA5 741B                <1> 	jz	short nib
 17845                              <1> 		; ble nib / gives error return
 17846                              <1> 	;
 17847 00004FA7 668B1D[8A740000]    <1> 	mov 	bx, [u.dirbuf]
 17848 00004FAE 6621DB              <1> 	and 	bx, bx       
 17849                              <1> 		; tst u.dirbuf /
 17850 00004FB1 7522                <1> 	jnz	short namei_4
 17851                              <1> 		; bne 3f / branch when active directory entry 
 17852                              <1> 		       ; / (i-node word in entry non zero)
 17853 00004FB3 A1[74740000]        <1> 	mov	eax, [u.off]
 17854 00004FB8 83E80A              <1> 	sub	eax, 10
 17855 00004FBB A3[6C740000]        <1> 	mov	[u.dirp], eax
 17856                              <1> 		; mov u.off,u.dirp
 17857                              <1> 		; sub $10.,u.dirp
 17858 00004FC0 EBB6                <1> 	jmp	short namei_3
 17859                              <1> 		; br 2b
 17860                              <1> 
 17861                              <1> 	; 18/07/2013
 17862                              <1> nib: 
 17863 00004FC2 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
 17864 00004FC4 F9                  <1> 	stc
 17865                              <1> nig:
 17866 00004FC5 C3                  <1> 	retn
 17867                              <1> 
 17868                              <1> namei_err:
 17869                              <1> 	; 16/06/2015
 17870 00004FC6 C705[A7740000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
 17871 00004FCE 0000                <1>
 17872 00004FD0 E978F0FFFF          <1> 	jmp	error
 17873                              <1> 
 17874                              <1> namei_4: ; 3:
 17875                              <1> 	; 18/10/2015
 17876                              <1> 	; 12/10/2015
 17877                              <1> 	; 21/08/2015
 17878                              <1> 	; 18/07/2015
 17879 00004FD5 8B2D[70740000]      <1> 	mov	ebp, [u.namep]
 17880                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
 17881 00004FDB BF[8C740000]        <1> 	mov 	edi, u.dirbuf + 2
 17882                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
 17883                              <1> 	; 18/10/2015
 17884 00004FE0 8B35[C8740000]      <1> 	mov	esi, [nbase]	
 17885 00004FE6 668B0D[CC740000]    <1> 	mov	cx, [ncount]
 17886                              <1> 	;
 17887 00004FED 6621C9              <1> 	and	cx, cx
 17888 00004FF0 7505                <1> 	jnz	short namei_5	
 17889                              <1> 	;
 17890 00004FF2 E850000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 17891                              <1> 		; esi = physical address (page start + offset)
 17892                              <1> 		; ecx = byte count in the page
 17893                              <1> namei_5: ; 3:
 17894 00004FF7 45                  <1> 	inc	ebp ; 18/07/2015
 17895 00004FF8 AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
 17896                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
 17897 00004FF9 08C0                <1> 	or 	al, al
 17898 00004FFB 741D                <1> 	jz 	short namei_7
 17899                              <1> 		; beq 3f / if char is nul, then the last char in string
 17900                              <1> 			; / has been moved
 17901 00004FFD 3C2F                <1> 	cmp	al, '/'
 17902                              <1> 		; cmp r4,$'/ / is char a </>
 17903 00004FFF 7419                <1> 	je 	short namei_7
 17904                              <1> 		; beq 3f	
 17905                              <1> 	; 12/10/2015
 17906 00005001 6649                <1> 	dec	cx ; remain byte count in the page
 17907 00005003 7505                <1> 	jnz	short namei_6
 17908 00005005 E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 17909                              <1> 		; esi = physical address (page start + offset)
 17910                              <1> 		; ecx = byte count in the page
 17911                              <1> namei_6:
 17912 0000500A 81FF[94740000]      <1>         cmp     edi, u.dirbuf + 10
 17913                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
 17914                              <1> 				     ; / all 8 bytes of file name
 17915 00005010 74E5                <1> 	je	short namei_5
 17916                              <1> 		; beq 3b
 17917 00005012 AE                  <1> 	scasb	
 17918                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
 17919                              <1> 			      ; / char read from directory
 17920 00005013 74E2                <1> 	je 	short namei_5
 17921                              <1> 		; beq 3b / branch if chars match
 17922                              <1> 
 17923 00005015 E95EFFFFFF          <1>         jmp    namei_3 ; 2b
 17924                              <1> 		; br 2b / file names do not match go to next directory entry
 17925                              <1> namei_7: ; 3:
 17926 0000501A 81FF[94740000]      <1> 	cmp	edi, u.dirbuf + 10
 17927                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
 17928 00005020 740A                <1> 	je	short namei_8
 17929                              <1> 		; beq 3f
 17930 00005022 8A27                <1> 	mov 	ah, [edi]
 17931                              <1> 	;inc 	edi 
 17932 00005024 20E4                <1> 	and 	ah, ah
 17933                              <1> 		; tstb (r3)+ /
 17934 00005026 0F854CFFFFFF        <1>         jnz     namei_3
 17935                              <1> 		; bne 2b
 17936                              <1> namei_8: ; 3
 17937 0000502C 892D[70740000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
 17938                              <1> 		; mov r2,u.namep / u.namep points to char 
 17939                              <1> 			       ; / following a / or nul
 17940                              <1> 	;mov	bx, [u.dirbuf]
 17941                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
 17942                              <1> 				; / entry to r1
 17943 00005032 20C0                <1> 	and 	al, al
 17944                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
 17945                              <1> 		      ;  / if r4 = </> then go to next directory
 17946                              <1> 	; mov	ax, bx
 17947 00005034 66A1[8A740000]      <1> 	mov 	ax, [u.dirbuf] ; 17/06/2015
 17948 0000503A 0F85FDFEFFFF        <1>         jnz     namei_2 
 17949                              <1> 		; bne 1b
 17950                              <1> 	; AX = i-number of the file
 17951                              <1> ;;nig:
 17952 00005040 C3                  <1> 	retn
 17953                              <1> 		; tst (r0)+ / gives non-error return
 17954                              <1> ;;nib:
 17955                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
 17956                              <1> 		       ; ax = 0 -> file not found 
 17957                              <1> ;;	stc	; 27/05/2013
 17958                              <1> ;;	retn
 17959                              <1> 		; rts r0
 17960                              <1> 
 17961                              <1> trans_addr_nmbp:
 17962                              <1> 	; 18/10/2015
 17963                              <1> 	; 12/10/2015
 17964 00005041 8B2D[70740000]      <1> 	mov 	ebp, [u.namep]
 17965                              <1> trans_addr_nm: 
 17966                              <1> 	; Convert virtual (pathname) address to physical address
 17967                              <1> 	; (Retro UNIX 386 v1 feature only !)
 17968                              <1> 	; 18/10/2015
 17969                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
 17970                              <1> 	; 02/07/2015
 17971                              <1> 	; 17/06/2015
 17972                              <1> 	; 16/06/2015
 17973                              <1> 	;
 17974                              <1> 	; INPUTS: 
 17975                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
 17976                              <1> 	;	[u.pgdir] = user's page directory
 17977                              <1> 	; OUTPUT:
 17978                              <1> 	;       esi = physical address of the pathname
 17979                              <1> 	;	ecx = remain byte count in the page
 17980                              <1> 	;
 17981                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI)
 17982                              <1> 	;
 17983 00005047 833D[AF740000]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
 17984 0000504E 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
 17985                              <1> 				     ; it is already physical address
 17986 00005050 50                  <1>    	push	eax	
 17987 00005051 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
 17988 00005053 E830E6FFFF          <1>        	call	get_physical_addr ; get physical address
 17989 00005058 7204                <1> 	jc	short tr_addr_nm_err
 17990                              <1> 	; 18/10/2015
 17991                              <1> 	; eax = physical address 
 17992                              <1> 	; cx = remain byte count in page (1-4096) 
 17993                              <1> 		; 12/10/2015 (cx = [u.pncount])
 17994 0000505A 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
 17995 0000505C 58                  <1> 	pop	eax 
 17996 0000505D C3                  <1> 	retn
 17997                              <1> 
 17998                              <1> tr_addr_nm_err:
 17999 0000505E A3[A7740000]        <1> 	mov	[u.error], eax
 18000                              <1> 	;pop 	eax
 18001 00005063 E9E5EFFFFF          <1> 	jmp	error
 18002                              <1> 
 18003                              <1> trans_addr_nmk:
 18004                              <1> 	; 12/10/2015
 18005                              <1> 	; 02/07/2015
 18006 00005068 8B35[70740000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
 18007 0000506E 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
 18008 00005072 C3                  <1> 	retn
 18009                              <1> 
 18010                              <1> syschdir:
 18011                              <1> 	; / makes the directory specified in the argument
 18012                              <1> 	; / the current directory
 18013                              <1> 	;
 18014                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18015                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18016                              <1> 	;
 18017                              <1> 	; 'syschdir' makes the directory specified in its argument
 18018                              <1> 	; the current working directory.
 18019                              <1> 	;
 18020                              <1> 	; Calling sequence:
 18021                              <1> 	;	syschdir; name
 18022                              <1> 	; Arguments:
 18023                              <1> 	;	name - address of the path name of a directory
 18024                              <1> 	;	       terminated by nul byte.	
 18025                              <1> 	; Inputs: -
 18026                              <1> 	; Outputs: -
 18027                              <1> 	; ...............................................................
 18028                              <1> 	;				
 18029                              <1> 	; Retro UNIX 8086 v1 modification:
 18030                              <1> 	;	 The user/application program puts address of 
 18031                              <1> 	;	 the path name in BX register as 'syschdir' 
 18032                              <1> 	; 	 system call argument.
 18033                              <1> 
 18034 00005073 891D[70740000]      <1> 	mov	[u.namep], ebx
 18035                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
 18036 00005079 E87EFEFFFF          <1> 	call	namei
 18037                              <1> 		; jsr r0,namei / find its i-number
 18038                              <1> 	;jc	error
 18039                              <1> 		; br error3
 18040 0000507E 730F                <1> 	jnc	short syschdir0
 18041                              <1> 	; 'directory not found !' error
 18042 00005080 C705[A7740000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
 18043 00005088 0000                <1>
 18044 0000508A E9BEEFFFFF          <1> 	jmp	error
 18045                              <1> syschdir0:
 18046 0000508F E833070000          <1> 	call	access
 18047                              <1> 		; jsr r0,access; 2 / get i-node into core
 18048 00005094 66F705[26710000]00- <1> 	test	word [i.flgs], 4000h
 18049 0000509C 40                  <1>
 18050                              <1> 		; bit $40000,i.flgs / is it a directory?
 18051                              <1> 	;jz	error 
 18052                              <1> 		; beq error3 / no error
 18053 0000509D 750F                <1> 	jnz	short syschdir1
 18054 0000509F C705[A7740000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 18055 000050A7 0000                <1>
 18056 000050A9 E99FEFFFFF          <1> 	jmp	error
 18057                              <1> syschdir1:
 18058 000050AE 66A3[5C740000]      <1> 	mov	[u.cdir], ax
 18059                              <1> 		; mov r1,u.cdir / move i-number to users 
 18060                              <1> 			      ; / current directory
 18061 000050B4 66A1[3E740000]      <1> 	mov	ax, [cdev]
 18062 000050BA 66A3[9C740000]      <1> 	mov	[u.cdrv], ax
 18063                              <1> 		; mov cdev,u.cdev / move its device to users 
 18064                              <1> 			        ; / current device
 18065 000050C0 E9A8EFFFFF          <1> 	jmp	sysret
 18066                              <1> 		; br sysret3
 18067                              <1> 	
 18068                              <1> syschmod: ; < change mode of file >
 18069                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18070                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 18071                              <1> 	;
 18072                              <1> 	; 'syschmod' changes mode of the file whose name is given as
 18073                              <1> 	; null terminated string pointed to by 'name' has it's mode 
 18074                              <1> 	; changed to 'mode'.
 18075                              <1> 	;
 18076                              <1> 	; Calling sequence:
 18077                              <1> 	;	syschmod; name; mode
 18078                              <1> 	; Arguments:
 18079                              <1> 	;	name - address of the file name
 18080                              <1> 	;	       terminated by null byte.
 18081                              <1> 	;	mode - (new) mode/flags < attributes >
 18082                              <1> 	;	
 18083                              <1> 	; Inputs: -
 18084                              <1> 	; Outputs: -
 18085                              <1> 	; ...............................................................
 18086                              <1> 	;				
 18087                              <1> 	; Retro UNIX 8086 v1 modification: 
 18088                              <1> 	;       'syschmod' system call has two arguments; so,
 18089                              <1> 	;	* 1st argument, name is pointed to by BX register
 18090                              <1> 	;	* 2nd argument, mode is in CX register
 18091                              <1> 	;
 18092                              <1> 	; Mode bits (Flags):
 18093                              <1> 	;	bit 0 - write permission for non-owner (1)
 18094                              <1> 	;	bit 1 - read permission for non-owner (2)
 18095                              <1> 	;	bit 2 - write permission for owner (4)
 18096                              <1> 	;	bit 3 - read permission for owner (8)
 18097                              <1> 	;	bit 4 - executable flag (16) 	
 18098                              <1> 	;	bit 5 - set user ID on execution flag (32) 
 18099                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
 18100                              <1> 	;	bit 12 - large file flag (4096)
 18101                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
 18102                              <1> 	;	bit 14 - directory flag (16384)
 18103                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
 18104                              <1> 
 18105                              <1> 	; / name; mode
 18106 000050C5 E814000000          <1> 	call	isown
 18107                              <1> 		;jsr r0,isown / get the i-node and check user status
 18108 000050CA 66F705[26710000]00- <1> 	test	word [i.flgs], 4000h
 18109 000050D2 40                  <1>
 18110                              <1> 		; bit	$40000,i.flgs / directory?
 18111 000050D3 7402                <1> 	jz	short syschmod1
 18112                              <1> 		; beq 2f / no
 18113                              <1> 	; AL = (new) mode
 18114 000050D5 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
 18115                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
 18116                              <1> 			   ; / executable modes
 18117                              <1> syschmod1: ; 2:
 18118 000050D7 A2[26710000]        <1> 	mov	[i.flgs], al	
 18119                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
 18120 000050DC EB42                <1> 	jmp	short isown1
 18121                              <1> 		; br 1f
 18122                              <1> 
 18123                              <1> isown:
 18124                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18125                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 18126                              <1> 	;
 18127                              <1> 	; 'isown' is given a file name (the 1st argument).
 18128                              <1> 	;  It find the i-number of that file via 'namei' 
 18129                              <1> 	;  then gets the i-node into core via 'iget'.
 18130                              <1> 	;  It then tests to see if the user is super user. 
 18131                              <1> 	;  If not, it cheks to see if the user is owner of 
 18132                              <1> 	;  the file. If he is not an error occurs.
 18133                              <1> 	;  If user is the owner 'setimod' is called to indicate
 18134                              <1> 	;  the inode has been modificed and the 2nd argument of
 18135                              <1> 	;  the call is put in r2.
 18136                              <1> 	;
 18137                              <1> 	; INPUTS ->
 18138                              <1> 	;    arguments of syschmod and syschown calls
 18139                              <1> 	; OUTPUTS ->
 18140                              <1> 	;    u.uid - id of user
 18141                              <1> 	;    imod - set to a 1
 18142                              <1> 	;    r2 - contains second argument of the system call				 	
 18143                              <1> 	;
 18144                              <1> 	;   ((AX=R2) output as 2nd argument)
 18145                              <1> 	;
 18146                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 18147                              <1> 	;
 18148                              <1> 		; jsr r0,arg2 / u.namep points to file name
 18149                              <1> 	;; ! 2nd argument on top of stack !
 18150                              <1> 	;; 22/06/2015 - 32 bit modifications
 18151                              <1> 	;; 07/07/2013
 18152 000050DE 891D[70740000]      <1> 	mov	[u.namep], ebx ;; 1st argument
 18153 000050E4 51                  <1> 	push 	ecx ;; 2nd argument
 18154                              <1> 	;;
 18155 000050E5 E812FEFFFF          <1> 	call	namei
 18156                              <1> 		; jsr r0,namei / get its i-number
 18157                              <1>        ; Retro UNIX 8086 v1 modification !
 18158                              <1>        ; ax = 0 -> file not found 
 18159                              <1> 	;and	ax, ax
 18160                              <1> 	;jz	error
 18161                              <1> 	;jc	error ; 27/05/2013
 18162                              <1> 		; br error3
 18163 000050EA 730F                <1> 	jnc	short isown0
 18164                              <1> 	; 'file not found !' error
 18165 000050EC C705[A7740000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 18166 000050F4 0000                <1>
 18167 000050F6 E952EFFFFF          <1> 	jmp	error
 18168                              <1> isown0:
 18169 000050FB E8EC050000          <1> 	call	iget
 18170                              <1> 		; jsr r0,iget / get i-node into core
 18171 00005100 A0[9E740000]        <1> 	mov	al, [u.uid] ; 02/08/2013
 18172 00005105 08C0                <1> 	or	al, al
 18173                              <1> 		; tstb u.uid / super user?
 18174 00005107 7417                <1> 	jz	short isown1
 18175                              <1> 		; beq 1f / yes, branch
 18176 00005109 3A05[29710000]      <1> 	cmp	al, [i.uid]
 18177                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
 18178                              <1> 				 ; / the file
 18179                              <1> 	;jne	error
 18180                              <1> 		; beq 1f / yes
 18181                              <1> 		; jmp error3 / no, error
 18182 0000510F 740F                <1> 	je	short isown1
 18183                              <1> 
 18184 00005111 C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
 18185 00005119 0000                <1>
 18186                              <1> 			;  'permission denied !' error
 18187 0000511B E92DEFFFFF          <1> 	jmp	error
 18188                              <1> isown1: ; 1:
 18189 00005120 E8DA060000          <1> 	call	setimod
 18190                              <1> 		; jsr r0,setimod / indicates 
 18191                              <1> 		;	       ; / i-node has been modified
 18192 00005125 58                  <1> 	pop	eax ; 2nd argument
 18193                              <1> 		; mov (sp)+,r2 / mode is put in r2 
 18194                              <1> 		       ; / (u.off put on stack with 2nd arg)
 18195 00005126 C3                  <1> 	retn
 18196                              <1> 		; rts r0
 18197                              <1> 
 18198                              <1> ;;arg:  ; < get system call arguments >
 18199                              <1> 	; 'arg' extracts an argument for a routine whose call is 
 18200                              <1> 	; of form:
 18201                              <1> 	;	sys 'routine' ; arg1
 18202                              <1> 	;		or
 18203                              <1> 	;	sys 'routine' ; arg1 ; arg2
 18204                              <1> 	;		or
 18205                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
 18206                              <1> 	;	
 18207                              <1> 	; INPUTS ->
 18208                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
 18209                              <1> 	;	This pointers's value is actually the value of
 18210                              <1> 	;	update pc at the the trap to sysent (unkni) is
 18211                              <1> 	;	made to process the sys instruction
 18212                              <1> 	;    r0 - contains the return address for the routine
 18213                              <1> 	;	that called arg. The data in the word pointer 
 18214                              <1> 	;	to by the return address is used as address
 18215                              <1> 	;	in which the extracted argument is stored   		
 18216                              <1> 	;    	
 18217                              <1> 	; OUTPUTS ->
 18218                              <1> 	;    'address' - contains the extracted argument 
 18219                              <1> 	;    u.sp+18 - is incremented by 2 
 18220                              <1> 	;    r1 - contains the extracted argument
 18221                              <1> 	;    r0 - points to the next instruction to be
 18222                              <1> 	;	 executed in the calling routine.
 18223                              <1> 	;
 18224                              <1>   
 18225                              <1> 	; mov u.sp,r1
 18226                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
 18227                              <1> 			; / into argument of arg2
 18228                              <1> 	; add $2,18.(r1) / point pc on stack 
 18229                              <1> 			      ; / to next system argument
 18230                              <1> 	; rts r0
 18231                              <1> 
 18232                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
 18233                              <1> 	; 'arg2' takes first argument in system call
 18234                              <1> 	;  (pointer to name of the file) and puts it in location
 18235                              <1> 	;  u.namep; takes second argument and puts it in u.off
 18236                              <1> 	;  and on top of the stack
 18237                              <1> 	;	
 18238                              <1> 	; INPUTS ->
 18239                              <1> 	;    u.sp, r0
 18240                              <1> 	;    	
 18241                              <1> 	; OUTPUTS ->
 18242                              <1> 	;    u.namep
 18243                              <1> 	;    u.off 
 18244                              <1> 	;    u.off pushed on stack
 18245                              <1> 	;    r1
 18246                              <1> 	;
 18247                              <1> 
 18248                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
 18249                              <1> 				; / first arg in sys call
 18250                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
 18251                              <1> 				; / second arg in sys call
 18252                              <1> 	; mov r0,r1 / r0 points to calling routine
 18253                              <1> 	; mov (sp),r0 / put operation code back in r0
 18254                              <1> 	; mov u.off,(sp) / put pointer to second argument 
 18255                              <1> 			; / on stack
 18256                              <1> 	; jmp (r1) / return to calling routine
 18257                              <1> 
 18258                              <1> syschown: ; < change owner of file >
 18259                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18260                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18261                              <1> 	;
 18262                              <1> 	; 'syschown' changes the owner of the file whose name is given
 18263                              <1> 	; as null terminated string pointed to by 'name' has it's owner
 18264                              <1> 	; changed to 'owner'
 18265                              <1> 	;
 18266                              <1> 	; Calling sequence:
 18267                              <1> 	;	syschown; name; owner
 18268                              <1> 	; Arguments:
 18269                              <1> 	;	name - address of the file name
 18270                              <1> 	;	       terminated by null byte.
 18271                              <1> 	;	owner - (new) owner (number/ID)
 18272                              <1> 	;	
 18273                              <1> 	; Inputs: -
 18274                              <1> 	; Outputs: -
 18275                              <1> 	; ...............................................................
 18276                              <1> 	;				
 18277                              <1> 	; Retro UNIX 8086 v1 modification: 
 18278                              <1> 	;       'syschown' system call has two arguments; so,
 18279                              <1> 	;	* 1st argument, name is pointed to by BX register
 18280                              <1> 	;	* 2nd argument, owner number is in CX register
 18281                              <1> 	;
 18282                              <1> 	; / name; owner
 18283 00005127 E8B2FFFFFF          <1> 	call	isown
 18284                              <1> 		; jsr r0,isown / get the i-node and check user status
 18285 0000512C 803D[9E740000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
 18286                              <1> 		; tstb u.uid / super user
 18287 00005133 7418                <1> 	jz	short syschown1
 18288                              <1> 		; beq 2f / yes, 2f
 18289 00005135 F605[26710000]20    <1>         test    byte [i.flgs], 20h ; 32
 18290                              <1> 		; bit $40,i.flgs / no, set userid on execution?
 18291                              <1> 	;jnz	error
 18292                              <1> 		; bne 3f / yes error, could create Trojan Horses
 18293 0000513C 740F                <1> 	jz	short syschown1
 18294                              <1> 	; 'permission denied !'
 18295 0000513E C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
 18296 00005146 0000                <1>
 18297 00005148 E900EFFFFF          <1> 	jmp	error
 18298                              <1> syschown1: ; 2:
 18299                              <1> 	; AL = owner (number/ID)
 18300 0000514D A2[29710000]        <1> 	mov	[i.uid], al ; 23/06/2015
 18301                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
 18302                              <1> 			       ; / in the i-node
 18303 00005152 E916EFFFFF          <1> 	jmp	sysret
 18304                              <1> 	; 1: 
 18305                              <1> 		; jmp sysret4
 18306                              <1> 	; 3:
 18307                              <1> 		; jmp	error
 18308                              <1> 
 18309                              <1> systime: ; / get time of year
 18310                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18311                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 18312                              <1> 	;
 18313                              <1> 	; 20/06/2013
 18314                              <1> 	; 'systime' gets the time of the year.
 18315                              <1> 	; The present time is put on the stack.
 18316                              <1> 	;
 18317                              <1> 	; Calling sequence:
 18318                              <1> 	;	systime
 18319                              <1> 	; Arguments: -
 18320                              <1> 	;	
 18321                              <1> 	; Inputs: -
 18322                              <1> 	; Outputs: sp+2, sp+4 - present time
 18323                              <1> 	; ...............................................................
 18324                              <1> 	;	
 18325                              <1> 	; Retro UNIX 8086 v1 modification: 
 18326                              <1> 	;       'systime' system call will return to the user
 18327                              <1> 	;	with unix time (epoch) in DX:AX register pair
 18328                              <1> 	;
 18329                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
 18330                              <1> 	;	system call for PC compatibility !!		 	
 18331                              <1> 
 18332 00005157 E82CEAFFFF          <1> 	call 	epoch
 18333 0000515C A3[58740000]        <1> 	mov 	[u.r0], eax
 18334                              <1> 		; mov s.time,4(sp)
 18335                              <1> 		; mov s.time+2,2(sp) / put the present time 
 18336                              <1> 				   ; / on the stack
 18337                              <1> 		; br sysret4
 18338 00005161 E907EFFFFF          <1> 	jmp	sysret 
 18339                              <1> 
 18340                              <1> sysstime: ; / set time
 18341                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18342                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18343                              <1> 	;
 18344                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
 18345                              <1> 	;
 18346                              <1> 	; Calling sequence:
 18347                              <1> 	;	sysstime
 18348                              <1> 	; Arguments: -
 18349                              <1> 	;	
 18350                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
 18351                              <1> 	; Outputs: -
 18352                              <1> 	; ...............................................................
 18353                              <1> 	;	
 18354                              <1> 	; Retro UNIX 8086 v1 modification: 
 18355                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
 18356                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
 18357                              <1> 	; 
 18358                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 18359                              <1> 	;	to get sysstime system call arguments from the user;
 18360                              <1> 	;	* 1st argument, lowword of unix time is in BX register
 18361                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
 18362                              <1> 	;
 18363                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
 18364                              <1> 	;	system call for PC compatibility !!	
 18365                              <1> 
 18366 00005166 803D[9E740000]00    <1> 	cmp	byte [u.uid], 0
 18367                              <1> 		; tstb u.uid / is user the super user
 18368                              <1> 	;ja	error
 18369                              <1> 		; bne error4 / no, error
 18370 0000516D 760F                <1> 	jna	short systime1
 18371                              <1> 	; 'permission denied !'
 18372 0000516F C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
 18373 00005177 0000                <1>
 18374 00005179 E9CFEEFFFF          <1> 	jmp	error
 18375                              <1> systime1:
 18376                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
 18377                              <1> 	; EBX = unix (epoch) time (from user)
 18378 0000517E 89D8                <1> 	mov	eax, ebx
 18379 00005180 E885EBFFFF          <1> 	call 	set_date_time
 18380                              <1> 		; mov 4(sp),s.time
 18381                              <1> 		; mov 2(sp),s.time+2 / set the system time
 18382 00005185 E9E3EEFFFF          <1> 	jmp	sysret
 18383                              <1> 		; br sysret4
 18384                              <1> 
 18385                              <1> sysbreak:
 18386                              <1> 	; 18/10/2015
 18387                              <1> 	; 07/10/2015
 18388                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18389                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
 18390                              <1> 	;
 18391                              <1> 	; 'sysbreak' sets the programs break points. 
 18392                              <1> 	; It checks the current break point (u.break) to see if it is
 18393                              <1> 	; between "core" and the stack (sp). If it is, it is made an
 18394                              <1> 	; even address (if it was odd) and the area between u.break
 18395                              <1> 	; and the stack is cleared. The new breakpoint is then put
 18396                              <1> 	; in u.break and control is passed to 'sysret'.
 18397                              <1> 	;
 18398                              <1> 	; Calling sequence:
 18399                              <1> 	;	sysbreak; addr
 18400                              <1> 	; Arguments: -
 18401                              <1> 	;	
 18402                              <1> 	; Inputs: u.break - current breakpoint
 18403                              <1> 	; Outputs: u.break - new breakpoint 
 18404                              <1> 	;	area between old u.break and the stack (sp) is cleared.
 18405                              <1> 	; ...............................................................
 18406                              <1> 	;	
 18407                              <1> 	; Retro UNIX 8086 v1 modification:
 18408                              <1> 	;	The user/application program puts breakpoint address
 18409                              <1> 	;       in BX register as 'sysbreak' system call argument.
 18410                              <1> 	; 	(argument transfer method 1)
 18411                              <1> 	;
 18412                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
 18413                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
 18414                              <1> 	;  NOTE:
 18415                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
 18416                              <1> 	;	'u.break' address) of user's memory for original unix's
 18417                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
 18418                              <1> 
 18419                              <1> 		; mov u.break,r1 / move users break point to r1
 18420                              <1> 		; cmp r1,$core / is it the same or lower than core?
 18421                              <1> 		; blos 1f / yes, 1f
 18422                              <1> 	; 23/06/2015
 18423 0000518A 8B2D[84740000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
 18424                              <1> 	;and	ebp, ebp
 18425                              <1> 	;jz	short sysbreak_3 
 18426                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
 18427                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
 18428 00005190 8B15[50740000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
 18429 00005196 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
 18430                              <1> 	; 07/10/2015
 18431 00005199 891D[84740000]      <1> 	mov	[u.break], ebx ; virtual address !!!
 18432                              <1> 	;
 18433 0000519F 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
 18434                              <1> 			   ; with top of user's stack (virtual!)
 18435 000051A1 7327                <1> 	jnb	short sysbreak_3
 18436                              <1> 		; cmp r1,sp / is it the same or higher 
 18437                              <1> 			  ; / than the stack?
 18438                              <1> 		; bhis 1f / yes, 1f
 18439 000051A3 89DE                <1> 	mov	esi, ebx
 18440 000051A5 29EE                <1> 	sub	esi, ebp ; new break point - old break point
 18441 000051A7 7621                <1> 	jna	short sysbreak_3 
 18442                              <1> 	;push	ebx
 18443                              <1> sysbreak_1:
 18444 000051A9 89EB                <1> 	mov	ebx, ebp  
 18445 000051AB E8D8E4FFFF          <1> 	call	get_physical_addr ; get physical address
 18446 000051B0 0F82A8FEFFFF        <1> 	jc	tr_addr_nm_err
 18447                              <1> 	; 18/10/2015
 18448 000051B6 89C7                <1> 	mov	edi, eax 
 18449 000051B8 29C0                <1> 	sub	eax, eax ; 0
 18450                              <1> 		 ; ECX = remain byte count in page (1-4096)
 18451 000051BA 39CE                <1> 	cmp	esi, ecx
 18452 000051BC 7302                <1> 	jnb	short sysbreak_2
 18453 000051BE 89F1                <1> 	mov	ecx, esi
 18454                              <1> sysbreak_2:
 18455 000051C0 29CE                <1> 	sub	esi, ecx
 18456 000051C2 01CD                <1> 	add	ebp, ecx
 18457 000051C4 F3AA                <1> 	rep 	stosb
 18458 000051C6 09F6                <1> 	or	esi, esi
 18459 000051C8 75DF                <1> 	jnz	short sysbreak_1
 18460                              <1> 	;
 18461                              <1> 		; bit $1,r1 / is it an odd address
 18462                              <1> 		; beq 2f / no, its even
 18463                              <1> 		; clrb (r1)+ / yes, make it even
 18464                              <1> 	; 2: / clear area between the break point and the stack
 18465                              <1> 		; cmp r1,sp / is it higher or same than the stack
 18466                              <1> 		; bhis 1f / yes, quit
 18467                              <1> 		; clr (r1)+ / clear word
 18468                              <1> 		; br 2b / go back
 18469                              <1> 	;pop	ebx
 18470                              <1> sysbreak_3: ; 1:
 18471                              <1> 	;mov	[u.break], ebx ; virtual address !!!
 18472                              <1> 		; jsr r0,arg; u.break / put the "address" 
 18473                              <1> 			; / in u.break (set new break point)
 18474                              <1> 		; br sysret4 / br sysret
 18475 000051CA E99EEEFFFF          <1> 	jmp	sysret
 18476                              <1> 
 18477                              <1> 
 18478                              <1> maknod: 
 18479                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18480                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18481                              <1> 	;
 18482                              <1> 	; 'maknod' creates an i-node and makes a directory entry
 18483                              <1> 	; for this i-node in the current directory.
 18484                              <1> 	;
 18485                              <1> 	; INPUTS ->
 18486                              <1> 	;    r1 - contains mode
 18487                              <1> 	;    ii - current directory's i-number	
 18488                              <1> 	;    	
 18489                              <1> 	; OUTPUTS ->
 18490                              <1> 	;    u.dirbuf - contains i-number of free i-node 
 18491                              <1> 	;    i.flgs - flags in new i-node 
 18492                              <1> 	;    i.uid - filled with u.uid
 18493                              <1> 	;    i.nlks - 1 is put in the number of links
 18494                              <1> 	;    i.ctim - creation time				
 18495                              <1> 	;    i.ctim+2 - modification time
 18496                              <1> 	;    imod - set via call to setimod
 18497                              <1> 	;	
 18498                              <1> 	; ((AX = R1)) input
 18499                              <1> 	;
 18500                              <1> 	; (Retro UNIX Prototype : 
 18501                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
 18502                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 18503                              <1> 
 18504                              <1> 	; / r1 contains the mode
 18505 000051CF 80CC80              <1> 	or 	ah, 80h  ; 10000000b
 18506                              <1> 		; bis	$100000,r1 / allocate flag set
 18507 000051D2 6650                <1> 	push	ax
 18508                              <1> 		; mov r1,-(sp) / put mode on stack
 18509                              <1> 	; 31/07/2013
 18510 000051D4 66A1[3A740000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
 18511                              <1> 		; mov ii,r1 / move current i-number to r1
 18512 000051DA B201                <1> 	mov	dl, 1 ; owner flag mask
 18513 000051DC E8E6050000          <1> 	call	access	
 18514                              <1> 		; jsr r0,access; 1 / get its i-node into core
 18515 000051E1 6650                <1> 	push	ax
 18516                              <1> 		; mov r1,-(sp) / put i-number on stack
 18517 000051E3 66B82800            <1> 	mov	ax, 40
 18518                              <1> 		; mov $40.,r1 / r1 = 40
 18519                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
 18520 000051E7 6640                <1> 	inc	ax
 18521                              <1> 		; inc r1 / r1 = r1 + 1
 18522 000051E9 E8AA060000          <1> 	call	imap
 18523                              <1> 		; jsr r0,imap / get byte address and bit position in 
 18524                              <1> 			    ; /	inode map in r2 & m
 18525                              <1>           ; DX (MQ) has a 1 in the calculated bit position
 18526                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
 18527                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
 18528                              <1> 	;	       Inode count must be checked here
 18529                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
 18530 000051EE 8413                <1> 	test	[ebx], dl
 18531                              <1> 		; bitb mq,(r2) / is the i-node active
 18532 000051F0 75F5                <1> 	jnz	short maknod1
 18533                              <1> 		; bne 1b / yes, try the next one
 18534 000051F2 0813                <1> 	or	[ebx], dl
 18535                              <1> 		; bisb mq,(r2) / no, make it active 
 18536                              <1> 			     ; / (put a 1 in the bit map)
 18537 000051F4 E8F3040000          <1> 	call	iget
 18538                              <1> 		; jsr r0,iget / get i-node into core
 18539 000051F9 66F705[26710000]00- <1> 	test	word [i.flgs], 8000h 
 18540 00005201 80                  <1>
 18541                              <1> 		; tst i.flgs / is i-node already allocated
 18542 00005202 75E3                <1> 	jnz	short maknod1	
 18543                              <1> 		; blt 1b / yes, look for another one
 18544 00005204 66A3[8A740000]      <1> 	mov	[u.dirbuf], ax
 18545                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
 18546 0000520A 6658                <1> 	pop	ax
 18547                              <1> 		; mov (sp)+,r1 / get current i-number back
 18548 0000520C E8DB040000          <1> 	call	iget
 18549                              <1> 		; jsr r0,iget / get i-node in core
 18550 00005211 E880F7FFFF          <1> 	call	mkdir
 18551                              <1> 		; jsr r0,mkdir / make a directory entry 
 18552                              <1> 			     ; / in current directory
 18553 00005216 66A1[8A740000]      <1> 	mov	ax, [u.dirbuf]
 18554                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
 18555 0000521C E8CB040000          <1> 	call	iget
 18556                              <1> 		; jsr r0,iget / get it into core
 18557                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
 18558 00005221 B908000000          <1> 	mov	ecx, 8 
 18559 00005226 31C0                <1> 	xor	eax, eax ; 0
 18560 00005228 BF[26710000]        <1> 	mov	edi, inode 
 18561 0000522D F3AB                <1> 	rep	stosd
 18562                              <1> 	;
 18563 0000522F 668F05[26710000]    <1> 	pop	word [i.flgs]
 18564                              <1> 		; mov (sp)+,i.flgs / fill flags
 18565 00005236 8A0D[9E740000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
 18566 0000523C 880D[29710000]      <1> 	mov 	[i.uid], cl
 18567                              <1> 		; movb u.uid,i.uid / user id	
 18568 00005242 C605[28710000]01    <1> 	mov     byte [i.nlks], 1
 18569                              <1> 		; movb $1,i.nlks / 1 link
 18570                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
 18571                              <1> 	;mov	eax, [s.time]
 18572                              <1> 	;mov 	[i.ctim], eax
 18573                              <1> 	 	; mov s.time,i.ctim / time created
 18574                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
 18575                              <1> 	; Retro UNIX 8086 v1 modification !
 18576                              <1> 	; i.ctime=0, i.ctime+2=0 and
 18577                              <1>         ; 'setimod' will set ctime of file via 'epoch'
 18578 00005249 E8B1050000          <1> 	call setimod
 18579                              <1> 		; jsr r0,setimod / set modified flag
 18580 0000524E C3                  <1> 	retn
 18581                              <1> 		; rts r0 / return
 18582                              <1> 
 18583                              <1> sysseek: ; / moves read write pointer in an fsp entry
 18584                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18585                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 18586                              <1> 	;
 18587                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
 18588                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
 18589                              <1> 	; The file descriptor refers to a file open for reading or
 18590                              <1> 	; writing. The read (or write) pointer is set as follows:
 18591                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
 18592                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
 18593                              <1> 	;	  current location plus offset.
 18594                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
 18595                              <1> 	;	  size of file plus offset.
 18596                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
 18597                              <1> 	;
 18598                              <1> 	; Calling sequence:
 18599                              <1> 	;	sysseek; offset; ptrname
 18600                              <1> 	; Arguments:
 18601                              <1> 	;	offset - number of bytes desired to move 
 18602                              <1> 	;		 the r/w pointer
 18603                              <1> 	;	ptrname - a switch indicated above
 18604                              <1> 	;
 18605                              <1> 	; Inputs: r0 - file descriptor 
 18606                              <1> 	; Outputs: -
 18607                              <1> 	; ...............................................................
 18608                              <1> 	;	
 18609                              <1> 	; Retro UNIX 8086 v1 modification: 
 18610                              <1> 	;       'sysseek' system call has three arguments; so,
 18611                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
 18612                              <1> 	;	* 2nd argument, offset is in CX register
 18613                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
 18614                              <1> 	;	
 18615                              <1> 
 18616 0000524F E823000000          <1> 	call	seektell
 18617                              <1> 	; AX = u.count
 18618                              <1> 	; BX = *u.fofp
 18619                              <1> 		; jsr r0,seektell / get proper value in u.count
 18620                              <1> 		; add u.base,u.count / add u.base to it
 18621 00005254 0305[78740000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
 18622 0000525A 8903                <1> 	mov	[ebx], eax
 18623                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
 18624 0000525C E90CEEFFFF          <1> 	jmp	sysret
 18625                              <1> 		; br sysret4
 18626                              <1> 
 18627                              <1> systell: ; / get the r/w pointer
 18628                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18629                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 18630                              <1> 	;
 18631                              <1> 	; Retro UNIX 8086 v1 modification:
 18632                              <1> 	; ! 'systell' does not work in original UNIX v1,
 18633                              <1> 	; 	    it returns with error !
 18634                              <1> 	; Inputs: r0 - file descriptor 
 18635                              <1> 	; Outputs: r0 - file r/w pointer
 18636                              <1> 
 18637                              <1> 	;xor	ecx, ecx ; 0
 18638 00005261 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
 18639                              <1> 	;call 	seektell
 18640 00005266 E812000000          <1> 	call 	seektell0 ; 05/08/2013
 18641                              <1> 	;mov	ebx, [u.fofp]
 18642 0000526B 8B03                <1> 	mov	eax, [ebx]
 18643 0000526D A3[58740000]        <1> 	mov	[u.r0], eax
 18644 00005272 E9F6EDFFFF          <1> 	jmp	sysret
 18645                              <1> 
 18646                              <1> ; Original unix v1 'systell' system call:
 18647                              <1> 		; jsr r0,seektell
 18648                              <1> 		; br error4
 18649                              <1> 
 18650                              <1> seektell:
 18651                              <1> 	; 03/01/2016
 18652                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18653                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 18654                              <1> 	;
 18655                              <1> 	; 'seektell' puts the arguments from sysseek and systell
 18656                              <1> 	; call in u.base and u.count. It then gets the i-number of
 18657                              <1> 	; the file from the file descriptor in u.r0 and by calling
 18658                              <1> 	; getf. The i-node is brought into core and then u.count
 18659                              <1> 	; is checked to see it is a 0, 1, or 2.
 18660                              <1> 	; If it is 0 - u.count stays the same
 18661                              <1> 	;          1 - u.count = offset (u.fofp)
 18662                              <1> 	;	   2 - u.count = i.size (size of file)
 18663                              <1> 	; 	 		
 18664                              <1> 	; !! Retro UNIX 8086 v1 modification:
 18665                              <1> 	;	Argument 1, file descriptor is in BX;
 18666                              <1> 	;	Argument 2, offset is in CX;
 18667                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
 18668                              <1> 	;
 18669                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
 18670                              <1> 	; call 	arg
 18671                              <1> 	;
 18672                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
 18673                              <1> 	;
 18674 00005277 890D[78740000]      <1> 	mov 	[u.base], ecx ; offset
 18675                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
 18676                              <1> seektell0:
 18677 0000527D 8915[7C740000]      <1> 	mov 	[u.count], edx
 18678                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
 18679                              <1> 	; mov	ax, bx
 18680                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
 18681                              <1> 			     ; / (index in u.fp list)
 18682                              <1> 	; call	getf
 18683                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
 18684                              <1> 	; BX = file descriptor (file number)
 18685 00005283 E83DFCFFFF          <1> 	call	getf1
 18686 00005288 6609C0              <1> 	or	ax, ax ; i-number of the file
 18687                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
 18688                              <1> 		             ; / put it on the stack
 18689                              <1> 	;jz	error
 18690                              <1> 		; beq error4 / if i-number is 0, not active so error
 18691 0000528B 750F                <1> 	jnz	short seektell1
 18692 0000528D C705[A7740000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 18693 00005295 0000                <1>
 18694 00005297 E9B1EDFFFF          <1> 	jmp	error
 18695                              <1> seektell1:
 18696                              <1> 	;push	eax
 18697 0000529C 80FC80              <1> 	cmp	ah, 80h
 18698 0000529F 7203                <1> 	jb	short seektell2
 18699                              <1> 		; bgt .+4 / if its positive jump
 18700 000052A1 66F7D8              <1> 	neg	ax
 18701                              <1> 		; neg r1 / if not make it positive
 18702                              <1> seektell2:
 18703 000052A4 E843040000          <1> 	call	iget
 18704                              <1> 		; jsr r0,iget / get its i-node into core
 18705 000052A9 8B1D[68740000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
 18706 000052AF 803D[7C740000]01    <1> 	cmp	byte [u.count], 1
 18707                              <1> 		; cmp u.count,$1 / is ptr name =1
 18708 000052B6 7705                <1> 	ja	short seektell3
 18709                              <1> 		; blt 2f / no its zero
 18710 000052B8 740A                <1> 	je	short seektell_4
 18711                              <1> 		; beq 1f / yes its 1
 18712 000052BA 31C0                <1> 	xor	eax, eax
 18713                              <1> 	;jmp	short seektell_5
 18714 000052BC C3                  <1> 	retn
 18715                              <1> seektell3:
 18716                              <1> 	; 03/01/2016
 18717                              <1> 	;movzx  eax, word [i.size]
 18718 000052BD 66A1[2A710000]      <1> 	mov	ax, [i.size]
 18719                              <1>                 ; mov i.size,u.count /  put number of bytes 
 18720                              <1>                                    ; / in file in u.count
 18721                              <1> 	;jmp	short seektell_5
 18722                              <1> 		; br 2f
 18723 000052C3 C3                  <1> 	retn
 18724                              <1> seektell_4: ; 1: / ptrname =1
 18725                              <1> 	;mov	ebx, [u.fofp]
 18726 000052C4 8B03                <1> 	mov	eax, [ebx]
 18727                              <1> 		; mov *u.fofp,u.count / put offset in u.count
 18728                              <1> ;seektell_5: ; 2: / ptrname =0
 18729                              <1> 	;mov	[u.count], eax
 18730                              <1> 	;pop	eax 
 18731                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
 18732 000052C6 C3                  <1> 	retn
 18733                              <1> 		; rts r0
 18734                              <1> 
 18735                              <1> sysintr: ; / set interrupt handling
 18736                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18737                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 18738                              <1> 	;
 18739                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
 18740                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
 18741                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
 18742                              <1> 	; If one does the interrupt character in the tty buffer is
 18743                              <1> 	; cleared and 'sysret'is called. If one does not exits
 18744                              <1> 	; 'sysret' is just called.	
 18745                              <1> 	;
 18746                              <1> 	; Calling sequence:
 18747                              <1> 	;	sysintr; arg
 18748                              <1> 	; Argument:
 18749                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
 18750                              <1> 	;	    - if 1, intterupts cause their normal result
 18751                              <1> 	;		 i.e force an exit.
 18752                              <1> 	;	    - if arg is a location within the program,
 18753                              <1> 	;		control is passed to that location when
 18754                              <1> 	;		an interrupt occurs.	
 18755                              <1> 	; Inputs: -
 18756                              <1> 	; Outputs: -
 18757                              <1> 	; ...............................................................
 18758                              <1> 	;	
 18759                              <1> 	; Retro UNIX 8086 v1 modification: 
 18760                              <1> 	;       'sysintr' system call sets u.intr to value of BX
 18761                              <1> 	;	then branches into sysquit.
 18762                              <1> 	;
 18763 000052C7 66891D[96740000]    <1> 	mov	[u.intr], bx
 18764                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
 18765                              <1> 		; br 1f / go into quit routine
 18766 000052CE E99AEDFFFF          <1> 	jmp	sysret
 18767                              <1> 
 18768                              <1> sysquit:
 18769                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18770                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 18771                              <1> 	;
 18772                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
 18773                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
 18774                              <1> 	; tty exists. If one does the interrupt character in the tty
 18775                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
 18776                              <1> 	; 'sysret' is just called.	
 18777                              <1> 	;
 18778                              <1> 	; Calling sequence:
 18779                              <1> 	;	sysquit; arg
 18780                              <1> 	; Argument:
 18781                              <1> 	;	arg - if 0, this call diables quit signals from the
 18782                              <1> 	;		typewriter (ASCII FS)
 18783                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
 18784                              <1> 	;		cease and a core image to be produced.
 18785                              <1> 	;		 i.e force an exit.
 18786                              <1> 	;	    - if arg is an addres in the program,
 18787                              <1> 	;		a quit causes control to sent to that
 18788                              <1> 	;		location.	
 18789                              <1> 	; Inputs: -
 18790                              <1> 	; Outputs: -
 18791                              <1> 	; ...............................................................
 18792                              <1> 	;	
 18793                              <1> 	; Retro UNIX 8086 v1 modification: 
 18794                              <1> 	;       'sysquit' system call sets u.quit to value of BX
 18795                              <1> 	;	then branches into 'sysret'.
 18796                              <1> 	;
 18797 000052D3 66891D[98740000]    <1> 	mov	[u.quit], bx
 18798 000052DA E98EEDFFFF          <1> 	jmp	sysret
 18799                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
 18800                              <1> 	;1:
 18801                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
 18802                              <1> 			      ; / to r1
 18803                              <1> 		; beq sysret4 / return to user
 18804                              <1> 		; clrb 6(r1) / clear the interrupt character 
 18805                              <1> 			   ; / in the tty buffer
 18806                              <1> 		; br sysret4 / return to user
 18807                              <1> 
 18808                              <1> syssetuid: ; / set process id
 18809                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18810                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18811                              <1> 	;
 18812                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
 18813                              <1> 	; to the process id in (u.r0). Both the effective user and 
 18814                              <1> 	; u.uid and the real user u.ruid are set to this. 
 18815                              <1> 	; Only the super user can make this call.	
 18816                              <1> 	;
 18817                              <1> 	; Calling sequence:
 18818                              <1> 	;	syssetuid
 18819                              <1> 	; Arguments: -
 18820                              <1> 	;
 18821                              <1> 	; Inputs: (u.r0) - contains the process id.
 18822                              <1> 	; Outputs: -
 18823                              <1> 	; ...............................................................
 18824                              <1> 	;	
 18825                              <1> 	; Retro UNIX 8086 v1 modification: 
 18826                              <1> 	;       BL contains the (new) user ID of the current process
 18827                              <1> 
 18828                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
 18829 000052DF 3A1D[9F740000]      <1> 	cmp	bl, [u.ruid] 
 18830                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
 18831                              <1> 			       ; / id number
 18832 000052E5 741E                <1> 	je	short setuid1
 18833                              <1> 		; beq 1f / yes
 18834 000052E7 803D[9E740000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 18835                              <1> 		; tstb u.uid / no, is current user the super user?
 18836                              <1> 	;ja	error
 18837                              <1> 		; bne error4 / no, error
 18838 000052EE 760F                <1> 	jna	short setuid0
 18839 000052F0 C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
 18840 000052F8 0000                <1>
 18841                              <1> 				;  'permission denied !' error
 18842 000052FA E94EEDFFFF          <1> 	jmp	error
 18843                              <1> setuid0:
 18844 000052FF 881D[9F740000]      <1> 	mov	[u.ruid], bl
 18845                              <1> setuid1: ; 1:
 18846 00005305 881D[9E740000]      <1> 	mov	[u.uid], bl ; 02/08/2013
 18847                              <1> 		; movb r1,u.uid / put process id in u.uid
 18848                              <1> 		; movb r1,u.ruid / put process id in u.ruid
 18849 0000530B E95DEDFFFF          <1> 	jmp	sysret
 18850                              <1> 		; br sysret4 / system return
 18851                              <1> 
 18852                              <1> sysgetuid: ; < get user id >
 18853                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18854                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 18855                              <1> 	;
 18856                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
 18857                              <1> 	; The real user ID identifies the person who is logged in,
 18858                              <1> 	; in contradistinction to the effective user ID, which
 18859                              <1> 	; determines his access permission at each moment. It is thus
 18860                              <1> 	; useful to programs which operate using the 'set user ID'
 18861                              <1> 	; mode, to find out who invoked them.	
 18862                              <1> 	;
 18863                              <1> 	; Calling sequence:
 18864                              <1> 	;	syssetuid
 18865                              <1> 	; Arguments: -
 18866                              <1> 	;
 18867                              <1> 	; Inputs: -
 18868                              <1> 	; Outputs: (u.r0) - contains the real user's id.
 18869                              <1> 	; ...............................................................
 18870                              <1> 	;	
 18871                              <1> 	; Retro UNIX 8086 v1 modification: 
 18872                              <1> 	;       AL contains the real user ID at return.
 18873                              <1> 	;
 18874 00005310 0FB605[9F740000]    <1> 	movzx 	eax, byte [u.ruid]
 18875 00005317 A3[58740000]        <1> 	mov	[u.r0], eax
 18876                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
 18877 0000531C E94CEDFFFF          <1> 	jmp	sysret
 18878                              <1> 		; br sysret4 / systerm return, sysret
 18879                              <1> 
 18880                              <1> anyi: 
 18881                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 18882                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
 18883                              <1> 	;
 18884                              <1> 	; 'anyi' is called if a file deleted while open.
 18885                              <1> 	; "anyi" checks to see if someone else has opened this file.
 18886                              <1> 	;
 18887                              <1> 	; INPUTS ->
 18888                              <1> 	;    r1 - contains an i-number
 18889                              <1> 	;    fsp - start of table containing open files
 18890                              <1> 	;
 18891                              <1> 	; OUTPUTS ->
 18892                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
 18893                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
 18894                              <1> 	;    if file not found - bit in i-node map is cleared
 18895                              <1> 	;    			 (i-node is freed)
 18896                              <1> 	;               all blocks related to i-node are freed
 18897                              <1> 	;	        all flags in i-node are cleared
 18898                              <1> 	; ((AX = R1)) input
 18899                              <1> 	;
 18900                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 18901                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 18902                              <1> 	;
 18903                              <1> 		; / r1 contains an i-number
 18904 00005321 BB[26720000]        <1> 	mov	ebx, fsp
 18905                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
 18906                              <1> anyi_1: ; 1:
 18907 00005326 663B03              <1> 	cmp	ax, [ebx]
 18908                              <1> 		; cmp r1,(r2) / do i-numbers match?
 18909 00005329 7433                <1> 	je	short anyi_3
 18910                              <1> 		; beq 1f / yes, 1f
 18911 0000532B 66F7D8              <1> 	neg	ax
 18912                              <1> 		; neg r1 / no complement r1
 18913 0000532E 663B03              <1> 	cmp	ax, [ebx]
 18914                              <1> 		; cmp r1,(r2) / do they match now?
 18915 00005331 742B                <1> 	je	short anyi_3
 18916                              <1> 		; beq 1f / yes, transfer
 18917                              <1> 		; / i-numbers do not match
 18918 00005333 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
 18919                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
 18920                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
 18921 00005336 81FB[1A740000]      <1> 	cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
 18922                              <1> 		; cmp r2,$fsp+[nfiles*8] 
 18923                              <1> 				; / are we at last entry in the table
 18924 0000533C 72E8                <1> 	jb	short anyi_1
 18925                              <1> 		; blt 1b / no, check next entries i-number
 18926                              <1> 	;cmp	ax, 32768
 18927 0000533E 80FC80              <1> 	cmp	ah, 80h ; negative number check
 18928                              <1> 		; tst r1 / yes, no match
 18929                              <1> 		; bge .+4
 18930 00005341 7203                <1> 	jb	short anyi_2
 18931 00005343 66F7D8              <1> 	neg	ax
 18932                              <1> 		; neg r1 / make i-number positive
 18933                              <1> anyi_2:	
 18934 00005346 E84D050000          <1> 	call	imap
 18935                              <1> 		; jsr r0,imap / get address of allocation bit 
 18936                              <1> 			    ; / in the i-map in r2
 18937                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
 18938                              <1>         ;; eBX (R2) has address of the byte with allocation bit
 18939                              <1>  	; not	dx
 18940 0000534B F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
 18941                              <1>         ;and	[ebx], dx
 18942 0000534D 2013                <1> 	and 	[ebx], dl 
 18943                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
 18944 0000534F E8CD040000          <1> 	call	itrunc
 18945                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
 18946 00005354 66C705[26710000]00- <1>  	mov 	word [i.flgs], 0
 18947 0000535C 00                  <1>
 18948                              <1> 		; clr i.flgs / clear all flags in the i-node
 18949 0000535D C3                  <1> 	retn
 18950                              <1> 		;rts	r0 / return
 18951                              <1> anyi_3: ; 1: / i-numbers match
 18952 0000535E FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
 18953                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
 18954                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
 18955 00005361 C3                  <1> 	retn
 18956                              <1> 		; rts r0
 18957                                  %include 'u3.s'        ; 10/05/2015
 18958                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS3.INC
 18959                              <1> ; Last Modification: 15/09/2015
 18960                              <1> ; ----------------------------------------------------------------------------
 18961                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 18962                              <1> ; (v0.1 - Beginning: 11/07/2012)
 18963                              <1> ;
 18964                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 18965                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 18966                              <1> ; <Bell Laboratories (17/3/1972)>
 18967                              <1> ; <Preliminary Release of UNIX Implementation Document>
 18968                              <1> ;
 18969                              <1> ; Retro UNIX 8086 v1 - U3.ASM (08/03/2014) //// UNIX v1 -> u3.s
 18970                              <1> ;
 18971                              <1> ; ****************************************************************************
 18972                              <1> 
 18973                              <1> tswitch: ; Retro UNIX 386 v1
 18974                              <1> tswap:
 18975                              <1> 	; 01/09/2015
 18976                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 18977                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 18978                              <1> 	; time out swap, called when a user times out.
 18979                              <1> 	; the user is put on the low priority queue.
 18980                              <1> 	; This is done by making a link from the last user
 18981                              <1> 	; on the low priority queue to him via a call to 'putlu'.
 18982                              <1> 	; then he is swapped out.
 18983                              <1> 	;
 18984                              <1> 	; Retro UNIX 386 v1 modification ->
 18985                              <1> 	;       swap (software task switch) is performed by changing
 18986                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 18987                              <1> 	;	as in Retro UNIX 8086 v1.
 18988                              <1> 	;
 18989                              <1> 	; RETRO UNIX 8086 v1 modification ->
 18990                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 18991                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 18992                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 18993                              <1> 	;	compatibles was using 1MB segmented memory 
 18994                              <1> 	;	in 8086/8088 times.
 18995                              <1> 	;
 18996                              <1> 	; INPUTS ->
 18997                              <1> 	;    u.uno - users process number
 18998                              <1> 	;    runq+4 - lowest priority queue
 18999                              <1> 	; OUTPUTS ->
 19000                              <1> 	;    r0 - users process number
 19001                              <1> 	;    r2 - lowest priority queue address
 19002                              <1> 	;
 19003                              <1> 	; ((AX = R0, BX = R2)) output
 19004                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
 19005                              <1> 	;
 19006 00005362 A0[A1740000]        <1> 	mov 	al, [u.uno]
 19007                              <1> 	       	; movb u.uno,r1 / move users process number to r1
 19008                              <1> 		; mov  $runq+4,r2 
 19009                              <1> 			; / move lowest priority queue address to r2
 19010 00005367 E8CE000000          <1>         call 	putlu
 19011                              <1> 		; jsr r0,putlu / create link from last user on Q to 
 19012                              <1> 		             ; / u.uno's user
 19013                              <1> 
 19014                              <1> switch: ; Retro UNIX 386 v1
 19015                              <1> swap:
 19016                              <1> 	; 02/09/2015
 19017                              <1> 	; 01/09/2015
 19018                              <1> 	; 31/08/2015
 19019                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19020                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19021                              <1> 	; 'swap' is routine that controls the swapping of processes
 19022                              <1> 	; in and out of core.
 19023                              <1> 	;
 19024                              <1> 	; Retro UNIX 386 v1 modification ->
 19025                              <1> 	;       swap (software task switch) is performed by changing
 19026                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 19027                              <1> 	;	as in Retro UNIX 8086 v1.
 19028                              <1> 	;
 19029                              <1> 	; RETRO UNIX 8086 v1 modification ->
 19030                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19031                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19032                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19033                              <1> 	;	compatibles was using 1MB segmented memory 
 19034                              <1> 	;	in 8086/8088 times.
 19035                              <1> 	;
 19036                              <1> 	; INPUTS ->
 19037                              <1> 	;    runq table - contains processes to run.
 19038                              <1> 	;    p.link - contains next process in line to be run.
 19039                              <1> 	;    u.uno - process number of process in core	
 19040                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
 19041                              <1> 	; OUTPUTS ->
 19042                              <1> 	;    (original unix v1 -> present process to its disk block)
 19043                              <1> 	;    (original unix v1 -> new process into core -> 
 19044                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
 19045                              <1> 	;	   for new process)
 19046                              <1> 	;    u.quant = 3 (Time quantum for a process)
 19047                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
 19048                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
 19049                              <1> 	;	 for now, it will swap the process if there is not
 19050                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
 19051                              <1> 	;	 or will count down from 3 to 0 even if there is a
 19052                              <1> 	;        keyboard event locking due to repetitive key strokes.
 19053                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
 19054                              <1> 	;
 19055                              <1> 	;    u.pri -points to highest priority run Q.
 19056                              <1> 	;    r2 - points to the run queue.
 19057                              <1> 	;    r1 - contains new process number
 19058                              <1> 	;    r0 - points to place in routine or process that called
 19059                              <1> 	;	  swap all user parameters
 19060                              <1> 	;				
 19061                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
 19062                              <1> 	;
 19063                              <1> swap_0:
 19064                              <1> 		;mov $300,*$ps / processor priority = 6
 19065 0000536C BE[4A740000]        <1> 	mov	esi, runq
 19066                              <1> 		; mov $runq,r2 / r2 points to runq table
 19067                              <1> swap_1: ; 1: / search runq table for highest priority process
 19068 00005371 668B06              <1> 	mov	ax, [esi]
 19069 00005374 6621C0              <1> 	and 	ax, ax
 19070                              <1>        		; tst (r2)+ / are there any processes to run 
 19071                              <1> 			  ; / in this Q entry
 19072 00005377 7507                <1> 	jnz	short swap_2
 19073                              <1>        		; bne 1f / yes, process 1f
 19074                              <1> 		; cmp r2,$runq+6 / if zero compare address 
 19075                              <1> 			       ; / to end of table
 19076                              <1> 		; bne 1b / if not at end, go back
 19077 00005379 E8E1000000          <1> 	call	idle
 19078                              <1> 		; jsr r0,idle; s.idlet+2 / wait for interrupt; 
 19079                              <1> 				       ; / all queues are empty
 19080 0000537E EBF1                <1> 	jmp	short swap_1
 19081                              <1> 		; br swap
 19082                              <1> swap_2: ; 1:
 19083 00005380 0FB6D8              <1> 	movzx	ebx, al ; 02/09/2015
 19084                              <1> 		; tst -(r2) / restore pointer to right Q entry
 19085                              <1>  		; mov r2,u.pri / set present user to this run queue
 19086                              <1> 	        ; movb (r2)+,r1 / move 1st process in queue to r1
 19087 00005383 38E0                <1> 	cmp	al, ah
 19088                              <1> 		; cmpb r1,(r2)+ / is there only 1 process 
 19089                              <1> 			      ; / in this Q to be run
 19090 00005385 740A                <1> 	je	short swap_3
 19091                              <1>        		; beq 1f / yes
 19092                              <1> 		; tst -(r2) / no, pt r2 back to this Q entry
 19093                              <1> 	;movzx	ebx, al
 19094 00005387 8AA3[C5710000]      <1> 	mov	ah, [ebx+p.link-1] 
 19095 0000538D 8826                <1>        	mov	[esi], ah
 19096                              <1> 		; movb p.link-1(r1),(r2) / move next process 
 19097                              <1> 				       ; / in line into run queue
 19098 0000538F EB06                <1> 	jmp	short swap_4
 19099                              <1>        		; br 2f
 19100                              <1> swap_3: ; 1:
 19101 00005391 6631D2              <1> 	xor	dx, dx
 19102 00005394 668916              <1> 	mov	[esi], dx
 19103                              <1> 		; clr -(r2) / zero the entry; no processes on the Q
 19104                              <1> swap_4: ; / write out core to appropriate disk area and read 
 19105                              <1>       ; / in new process if required
 19106                              <1>        		; clr *$ps / clear processor status
 19107 00005397 8A25[A1740000]      <1> 	mov 	ah, [u.uno]
 19108 0000539D 38C4                <1> 	cmp	ah, al
 19109                              <1> 		; cmpb r1,u.uno / is this process the same as 
 19110                              <1> 			      ; / the process in core?
 19111 0000539F 743B                <1>        	je	short swap_8
 19112                              <1>        		; beq 2f / yes, don't have to swap
 19113                              <1>        		; mov r0,-(sp) / no, write out core; save r0 
 19114                              <1> 			   ; / (address in routine that called swap)
 19115                              <1> 		; mov r1,-(sp) / put r1 (new process #) on the stack
 19116                              <1> 	; 01/09/2015
 19117                              <1> 	;mov	[u.usp], esp
 19118                              <1>        		; mov sp,u.usp / save stack pointer
 19119                              <1> 		; mov $sstack,sp / move swap stack pointer 
 19120                              <1> 			       ; / to the stack pointer
 19121 000053A1 08E4                <1> 	or	ah, ah
 19122                              <1>        		; tstb u.uno / is the process # = 0
 19123 000053A3 740D                <1>        	jz	short swap_6 ; 'sysexit'
 19124                              <1> 		; beq  1f / yes, kill process by overwriting
 19125                              <1> 	; 02/09/2015
 19126 000053A5 8925[54740000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
 19127                              <1> 	;
 19128 000053AB E834000000          <1> 	call	wswap
 19129                              <1> 		;jsr r0,wswap / write out core to disk
 19130                              <1> 	 ; 31/08/2015
 19131                              <1> 	;movzx	ebx, al ; New (running) process number
 19132 000053B0 EB1C                <1> 	jmp 	short swap_7
 19133                              <1> swap_6:
 19134                              <1> 	; 31/08/2015
 19135                              <1> 	; Deallocate memory pages belong to the process
 19136                              <1> 	; which is being terminated
 19137                              <1> 	; 14/05/2015 ('sysexit')
 19138                              <1>  	; Deallocate memory pages of the process
 19139                              <1> 	; (Retro UNIX 386 v1 modification !)
 19140                              <1> 	;
 19141                              <1> 	; movzx ebx, al
 19142 000053B2 53                  <1> 	push	ebx
 19143 000053B3 A1[AB740000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
 19144 000053B8 8B1D[AF740000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
 19145 000053BE E86BDDFFFF          <1> 	call	deallocate_page_dir
 19146 000053C3 A1[A2740000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
 19147 000053C8 E800DEFFFF          <1> 	call	deallocate_page
 19148 000053CD 5B                  <1> 	pop	ebx
 19149                              <1> swap_7: ;1: 
 19150                              <1> 	; 02/09/2015
 19151                              <1> 	; 31/08/2015
 19152                              <1> 	; 14/05/2015
 19153 000053CE C0E302              <1> 	shl	bl, 2 ; * 4 
 19154 000053D1 8B83[E2710000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
 19155                              <1> 	;cli
 19156 000053D7 E831000000          <1> 	call	rswap
 19157                              <1>  		; mov (sp)+,r1 / restore r1 to new process number
 19158                              <1> 		; jsr r0,rswap / read new process into core
 19159                              <1>        		; jsr r0,unpack / unpack the users stack from next
 19160                              <1> 			      ; / to his program to its normal
 19161                              <1> 	; 01/09/2015
 19162                              <1> 	;mov	esp, [u.usp]	
 19163                              <1> 		; mov u.usp,sp / location; restore stack pointer to
 19164                              <1> 			     ; / new process stack
 19165                              <1> 		; mov (sp)+,r0 / put address of where the process 
 19166                              <1> 			     ; / that just got swapped in, left off.,
 19167                              <1> 			     ; / i.e., transfer control to new process
 19168                              <1> 	;sti
 19169                              <1> swap_8: ;2:
 19170                              <1> 	; RETRO UNIX 8086 v1 modification !
 19171 000053DC C605[94740000]04    <1> 	mov	byte [u.quant], time_count 
 19172                              <1> 		; movb    $30.,uquant / initialize process time quantum
 19173 000053E3 C3                  <1> 	retn
 19174                              <1> 		; rts r0 / return
 19175                              <1> 
 19176                              <1> wswap:  ; < swap out, swap to disk >
 19177                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 19178                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19179                              <1> 	; 'wswap' writes out the process that is in core onto its 
 19180                              <1> 	; appropriate disk area.
 19181                              <1> 	;
 19182                              <1> 	; Retro UNIX 386 v1 modification ->
 19183                              <1> 	;       User (u) structure content and the user's register content
 19184                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
 19185                              <1> 	;	saving 'u' structure and user registers for task switching).
 19186                              <1> 	;	u.usp - points to kernel stack address which contains
 19187                              <1> 	;		user's registers while entering system call.  
 19188                              <1> 	;	u.sp  - points to kernel stack address 
 19189                              <1> 	;		to return from system call -for IRET-.
 19190                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 19191                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 19192                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 19193                              <1> 	;
 19194                              <1> 	; Retro UNIX 8086 v1 modification ->
 19195                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19196                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19197                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19198                              <1> 	;	compatibles was using 1MB segmented memory 
 19199                              <1> 	;	in 8086/8088 times.
 19200                              <1> 	;
 19201                              <1> 	; INPUTS ->
 19202                              <1> 	;    u.break - points to end of program
 19203                              <1> 	;    u.usp - stack pointer at the moment of swap
 19204                              <1> 	;    core - beginning of process program		
 19205                              <1> 	;    ecore - end of core 	
 19206                              <1> 	;    user - start of user parameter area		
 19207                              <1> 	;    u.uno - user process number	
 19208                              <1> 	;    p.dska - holds block number of process	
 19209                              <1> 	; OUTPUTS ->
 19210                              <1> 	;    swp I/O queue
 19211                              <1> 	;    p.break - negative word count of process 
 19212                              <1> 	;    r1 - process disk address	
 19213                              <1> 	;    r2 - negative word count
 19214                              <1> 	;
 19215                              <1> 	; RETRO UNIX 8086 v1 input/output:
 19216                              <1> 	;
 19217                              <1> 	; INPUTS ->
 19218                              <1> 	;    u.uno - process number (to be swapped out)
 19219                              <1> 	; OUTPUTS ->
 19220                              <1> 	;    none
 19221                              <1> 	;
 19222                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
 19223                              <1> 	;
 19224 000053E4 8B3D[A2740000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
 19225 000053EA B91C000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 19226 000053EF BE[50740000]        <1> 	mov	esi, user ; active user (u) structure	
 19227 000053F4 F3A5                <1> 	rep	movsd
 19228                              <1> 	;
 19229 000053F6 8B35[54740000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
 19230                              <1> 			     ;      points to user registers)
 19231 000053FC 8B0D[50740000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 19232                              <1> 			     ; (for IRET)
 19233                              <1> 			     ; [u.sp] -> EIP (user)
 19234                              <1> 			     ; [u.sp+4]-> CS (user)
 19235                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 19236                              <1> 			     ; [u.sp+12] -> ESP (user)
 19237                              <1> 			     ; [u.sp+16] -> SS (user)	
 19238 00005402 29F1                <1> 	sub	ecx, esi     ; required space for user registers
 19239 00005404 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 19240                              <1> 			     ; (for IRET) 	
 19241 00005407 C1E902              <1> 	shr	ecx, 2	     		
 19242 0000540A F3A5                <1> 	rep	movsd
 19243 0000540C C3                  <1> 	retn
 19244                              <1> 
 19245                              <1> 	; Original UNIX v1 'wswap' routine:
 19246                              <1> 	; wswap:
 19247                              <1> 		; mov *$30,u.emt / determines handling of emts
 19248                              <1>         	; mov *$10,u.ilgins / determines handling of 
 19249                              <1> 				; / illegal instructions
 19250                              <1> 		; mov u.break,r2 / put process program break address in r2
 19251                              <1> 		; inc r2 / add 1 to it 
 19252                              <1> 		; bic $1,r2 / make it even
 19253                              <1> 		; mov r2,u.break / set break to an even location
 19254                              <1> 		; mov u.usp,r3 / put users stack pointer 
 19255                              <1> 			     ; / at moment of swap in r3
 19256                              <1> 		; cmp r2,$core / is u.break less than $core
 19257                              <1> 		; blos 2f / yes
 19258                              <1> 		; cmp r2,r3 / no, is (u.break) greater than stack ptr.
 19259                              <1>        		; bhis 2f / yes
 19260                              <1> 	; 1:
 19261                              <1>        		; mov (r3)+,(r2)+ / no, pack stack next to users program
 19262                              <1> 		; cmp r3,$ecore / has stack reached end of core
 19263                              <1> 		; bne 1b / no, keep packing
 19264                              <1> 	 	; br 1f / yes
 19265                              <1> 	; 2:
 19266                              <1>        		; mov $ecore,r2 / put end of core in r2 
 19267                              <1> 	; 1:
 19268                              <1>        		; sub  $user,r2 / get number of bytes to write out 
 19269                              <1> 			   ; / (user up to end of stack gets written out)
 19270                              <1> 		; neg r2 / make it negative
 19271                              <1> 		; asr r2 / change bytes to words (divide by 2)
 19272                              <1> 		; mov r2,swp+4 / word count
 19273                              <1> 		; movb u.uno,r1 / move user process number to r1
 19274                              <1> 		; asl r1 / x2 for index
 19275                              <1>       		; mov r2,p.break-2(r1) / put negative of word count 
 19276                              <1> 				     ; / into the p.break table
 19277                              <1>        		; mov p.dska-2(r1),r1 / move disk address of swap area 
 19278                              <1> 				    ; /	for process to r1
 19279                              <1>        		; mov r1,swp+2 / put processes dska address in swp+2 
 19280                              <1> 			     ; / (block number)
 19281                              <1> 		; bis $1000,swp / set it up to write (set bit 9)
 19282                              <1>        		; jsr r0,ppoke / write process out on swap area of disk
 19283                              <1> 	; 1:
 19284                              <1>        		; tstb swp+1 / is lt done writing?
 19285                              <1>        		; bne 1b / no, wait
 19286                              <1> 		; rts r0 / yes, return to swap
 19287                              <1> 
 19288                              <1> rswap:  ; < swap in, swap from disk >
 19289                              <1> 	; 15/09/2015
 19290                              <1> 	; 28/08/2015
 19291                              <1> 	; 14/05/2015
 19292                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 19293                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 19294                              <1> 	; 'rswap' reads a process whose number is in r1, 
 19295                              <1> 	; from disk into core.
 19296                              <1> 	;
 19297                              <1> 	; Retro UNIX 386 v1 modification ->
 19298                              <1> 	;       User (u) structure content and the user's register content
 19299                              <1> 	;	will be restored from process's/user's UPAGE (a page for
 19300                              <1> 	;	saving 'u' structure and user registers for task switching).
 19301                              <1> 	;	u.usp - points to kernel stack address which contains
 19302                              <1> 	;		user's registers while entering system call.  
 19303                              <1> 	;	u.sp  - points to kernel stack address 
 19304                              <1> 	;		to return from system call -for IRET-.
 19305                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 19306                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 19307                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 19308                              <1> 	;
 19309                              <1> 	; RETRO UNIX 8086 v1 modification ->
 19310                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 19311                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 19312                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 19313                              <1> 	;	compatibles was using 1MB segmented memory 
 19314                              <1> 	;	in 8086/8088 times.
 19315                              <1> 	;
 19316                              <1> 	; INPUTS ->
 19317                              <1> 	;    r1 - process number of process to be read in
 19318                              <1> 	;    p.break - negative of word count of process 
 19319                              <1> 	;    p.dska - disk address of the process		
 19320                              <1> 	;    u.emt - determines handling of emt's 	
 19321                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 19322                              <1> 	; OUTPUTS ->
 19323                              <1> 	;    8 = (u.ilgins)
 19324                              <1> 	;    24 = (u.emt)
 19325                              <1> 	;    swp - bit 10 is set to indicate read 
 19326                              <1> 	;		(bit 15=0 when reading is done)	
 19327                              <1> 	;    swp+2 - disk block address
 19328                              <1> 	;    swp+4 - negative word count 	
 19329                              <1> 	;      ((swp+6 - address of user structure)) 
 19330                              <1> 	;
 19331                              <1> 	; RETRO UNIX 8086 v1 input/output:
 19332                              <1> 	;
 19333                              <1> 	; INPUTS ->
 19334                              <1> 	;    AL	- new process number (to be swapped in)	 
 19335                              <1> 	; OUTPUTS ->
 19336                              <1> 	;    none
 19337                              <1> 	;
 19338                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
 19339                              <1> 	;
 19340                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
 19341 0000540D 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
 19342 0000540F B91C000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 19343 00005414 BF[50740000]        <1> 	mov	edi, user ; active user (u) structure	
 19344 00005419 F3A5                <1> 	rep	movsd
 19345 0000541B 58                  <1> 	pop	eax ; 15/09/2015, 'rswap' return address 
 19346 0000541C 8B3D[54740000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
 19347                              <1> 			     ;      points to user registers)
 19348 00005422 8B0D[50740000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 19349                              <1> 			     ; (for IRET)
 19350                              <1> 			     ; [u.sp] -> EIP (user)
 19351                              <1> 			     ; [u.sp+4]-> CS (user)
 19352                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 19353                              <1> 			     ; [u.sp+12] -> ESP (user)
 19354                              <1> 			     ; [u.sp+16] -> SS (user)		
 19355                              <1> 	; 28/08/2015
 19356 00005428 29F9                <1> 	sub	ecx, edi     ; required space for user registers
 19357 0000542A 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 19358                              <1> 			     ; (for IRET) 	
 19359 0000542D C1E902              <1> 	shr	ecx, 2	       		
 19360 00005430 F3A5                <1> 	rep	movsd
 19361 00005432 8B25[54740000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
 19362 00005438 50                  <1> 	push	eax ; 15/09/2015 'rswap' return address
 19363 00005439 C3                  <1> 	retn
 19364                              <1> 
 19365                              <1> 	; Original UNIX v1 'rswap'  and 'unpack' routines:
 19366                              <1> 	;rswap:
 19367                              <1>        		; asl r1 / process number x2 for index
 19368                              <1>        		; mov p.break-2(r1), swp+4 / word count
 19369                              <1>        		; mov p.dska-2(r1),swp+2 / disk address
 19370                              <1>        		; bis $2000,swp / read
 19371                              <1>        		; jsr r0,ppoke / read it in 
 19372                              <1> 	; 1:
 19373                              <1>        		; tstb swp+1 / done
 19374                              <1>        		; bne 1b / no, wait for bit 15 to clear (inhibit bit)
 19375                              <1>        		; mov u.emt,*$30 / yes move these
 19376                              <1>        		; mov u.ilgins,*$10 / back
 19377                              <1>        		; rts r0 / return
 19378                              <1> 
 19379                              <1> 	;unpack: ; / move stack back to its normal place
 19380                              <1> 		; mov u.break,r2 / r2 points to end of user program
 19381                              <1>        		; cmp r2,$core / at beginning of user program yet?
 19382                              <1> 		; blos 2f / yes, return
 19383                              <1> 		; cmp r2,u.usp / is break_above the stack pointer 
 19384                              <1> 			     ; / before swapping
 19385                              <1> 		; bhis 2f / yes, return
 19386                              <1> 		; mov $ecore,r3 / r3 points to end of core
 19387                              <1> 		; add r3,r2
 19388                              <1> 		; sub u.usp,r2 / end of users stack is in r2
 19389                              <1> 	; 1:
 19390                              <1> 		; mov -(r2),-(r3) / move stack back to its normal place
 19391                              <1> 		; cmp r2,u.break / in core
 19392                              <1> 		; bne 1b
 19393                              <1> 	; 2:
 19394                              <1>        		; rts r0
 19395                              <1> 
 19396                              <1> putlu: 
 19397                              <1> 	; 12/09/2015
 19398                              <1> 	; 02/09/2015
 19399                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19400                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 19401                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
 19402                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
 19403                              <1> 	; the last process on the queue to process in r1 by putting
 19404                              <1> 	; the process number in r1 into the last process's link.
 19405                              <1> 	;
 19406                              <1> 	; INPUTS ->
 19407                              <1> 	;    r1 - user process number
 19408                              <1> 	;    r2 - points to lowest priority queue 
 19409                              <1> 	;    p.dska - disk address of the process		
 19410                              <1> 	;    u.emt - determines handling of emt's 	
 19411                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 19412                              <1> 	; OUTPUTS ->
 19413                              <1> 	;    r3 - process number of last process on the queue upon
 19414                              <1> 	;	  entering putlu
 19415                              <1> 	;    p.link-1 + r3 - process number in r1
 19416                              <1> 	;    r2 - points to lowest priority queue
 19417                              <1> 	;
 19418                              <1> 	; ((Modified registers: EDX, EBX)) 
 19419                              <1> 	;
 19420                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
 19421                              <1> 
 19422                              <1> 	; eBX = r2
 19423                              <1> 	; eAX = r1 (AL=r1b)
 19424                              <1> 
 19425 0000543A BB[4A740000]        <1> 	mov	ebx, runq
 19426 0000543F 0FB613              <1> 	movzx  	edx, byte [ebx]
 19427 00005442 43                  <1> 	inc	ebx
 19428 00005443 20D2                <1> 	and	dl, dl
 19429                              <1> 		; tstb (r2)+ / is queue empty?
 19430 00005445 740A                <1>        	jz	short putlu_1
 19431                              <1> 		; beq 1f / yes, branch
 19432 00005447 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
 19433                              <1> 		; movb (r2),r3 / no, save the "last user" process number
 19434                              <1> 			     ; / in r3
 19435 00005449 8882[C5710000]      <1>        	mov	[edx+p.link-1], al
 19436                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
 19437                              <1> 			     ; / "last users" link
 19438 0000544F EB03                <1> 	jmp	short putlu_2
 19439                              <1> 		; br 2f /
 19440                              <1> putlu_1: ; 1:
 19441 00005451 8843FF              <1> 	mov	[ebx-1], al
 19442                              <1>        		; movb r1,-1(r2) / user is only user; 
 19443                              <1> 			    ; / put process no. at beginning and at end
 19444                              <1> putlu_2: ; 2: 
 19445 00005454 8803                <1> 	mov	[ebx], al
 19446                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
 19447                              <1> 			     ; / on the queue
 19448 00005456 88C2                <1> 	mov	dl, al
 19449 00005458 88B2[C5710000]      <1>         mov     [edx+p.link-1], dh ; 0
 19450                              <1> 		; dec r2 / restore r2
 19451 0000545E C3                  <1>         retn
 19452                              <1> 		; rts r0
 19453                              <1> 
 19454                              <1> ;copyz:
 19455                              <1> ;       mov     r1,-(sp) / put r1 on stack
 19456                              <1> ;       mov     r2,-(sp) / put r2 on stack
 19457                              <1> ;       mov     (r0)+,r1
 19458                              <1> ;       mov     (r0)+,r2
 19459                              <1> ;1:
 19460                              <1> ;       clr     (r1)+ / clear all locations between r1 and r2
 19461                              <1> ;       cmp     r1,r2 
 19462                              <1> ;       blo     1b
 19463                              <1> ;       mov     (sp)+,r2 / restore r2
 19464                              <1> ;       mov     (sp)+,r1 / restore r1
 19465                              <1> ;       rts     r0 
 19466                              <1> 
 19467                              <1> idle:
 19468                              <1> 	; 01/09/2015
 19469                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19470                              <1> 	; 10/04/2013 - 23/10/2013 (Retro UNIX 8086 v1)
 19471                              <1> 	; (idle & wait loop)
 19472                              <1> 	; Retro Unix 8086 v1 modification on original UNIX v1
 19473                              <1> 	; idle procedure!
 19474                              <1>       	;
 19475                              <1>   	; 01/09/2015
 19476 0000545F FB                  <1> 	sti
 19477                              <1>       	; 29/07/2013
 19478 00005460 F4                  <1>       	hlt
 19479 00005461 90                  <1>       	nop ; 10/10/2013
 19480 00005462 90                  <1>       	nop
 19481 00005463 90                  <1>       	nop
 19482                              <1>       	; 23/10/2013
 19483 00005464 90                  <1>       	nop
 19484 00005465 90                  <1>       	nop
 19485 00005466 90                  <1>       	nop
 19486 00005467 90                  <1>       	nop
 19487 00005468 C3                  <1>       	retn      
 19488                              <1> 
 19489                              <1> 	;mov *$ps,-(sp) / save ps on stack
 19490                              <1> 	;clr *$ps / clear ps
 19491                              <1> 	;mov clockp,-(sp) / save clockp on stack
 19492                              <1> 	;mov (r0)+,clockp / arg to idle in clockp
 19493                              <1> 	;1 / wait for interrupt
 19494                              <1> 	;mov (sp)+,clockp / restore clockp, ps
 19495                              <1> 	;mov (sp)+,*$ps
 19496                              <1> 	;rts r0
 19497                              <1> 
 19498                              <1> clear:
 19499                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 19500                              <1> 	; 09/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 19501                              <1> 	; 'clear' zero's out of a block (whose block number is in r1)
 19502                              <1> 	; on the current device (cdev)
 19503                              <1> 	;	
 19504                              <1> 	; INPUTS ->
 19505                              <1> 	;    r1 - block number of block to be zeroed
 19506                              <1> 	;    cdev - current device number 
 19507                              <1> 	; OUTPUTS ->
 19508                              <1> 	;    a zeroed I/O buffer onto the current device
 19509                              <1> 	;    r1 - points to last entry in the I/O buffer
 19510                              <1> 	;
 19511                              <1> 	; ((AX = R1)) input/output
 19512                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 14/11/2012, UNIXCOPY.ASM)
 19513                              <1>         ;    ((Modified registers: EDX, ECX, EBX, ESI, EDI, EBP))  
 19514                              <1> 
 19515 00005469 E8AB0D0000          <1> 	call 	wslot
 19516                              <1> 		; jsr r0,wslot / get an I/O buffer set bits 9 and 15 in first
 19517                              <1>                    ; / word of I/O queue r5 points to first data word in buffer
 19518 0000546E 89DF                <1> 	mov	edi, ebx ; r5
 19519 00005470 89C2                <1> 	mov	edx, eax
 19520 00005472 B980000000          <1> 	mov	ecx, 128
 19521                              <1> 		; mov $256.,r3
 19522 00005477 31C0                <1> 	xor	eax, eax
 19523 00005479 F3AB                <1> 	rep	stosd
 19524 0000547B 89D0                <1> 	mov	eax, edx
 19525                              <1> ; 1: 
 19526                              <1>        		; clr (r5)+ / zero data word in buffer
 19527                              <1>        		; dec r3
 19528                              <1>        		; bgt 1b / branch until all data words in buffer are zero
 19529 0000547D E8B30D0000          <1> 	call	dskwr
 19530                              <1> 		; jsr r0,dskwr / write zeroed buffer area out onto physical
 19531                              <1>                              ; / block specified in r1
 19532                              <1> 	; eAX (r1) = block number
 19533 00005482 C3                  <1> 	retn
 19534                              <1> 		; rts r0
 19535                                  %include 'u4.s'        ; 15/04/2015
 19536                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS4.INC
 19537                              <1> ; Last Modification: 14/10/2015
 19538                              <1> ; ----------------------------------------------------------------------------
 19539                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 19540                              <1> ; (v0.1 - Beginning: 11/07/2012)
 19541                              <1> ;
 19542                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 19543                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 19544                              <1> ; <Bell Laboratories (17/3/1972)>
 19545                              <1> ; <Preliminary Release of UNIX Implementation Document>
 19546                              <1> ;
 19547                              <1> ; Retro UNIX 8086 v1 - U4.ASM (04/07/2014) //// UNIX v1 -> u4.s
 19548                              <1> ;
 19549                              <1> ; ****************************************************************************
 19550                              <1> 
 19551                              <1> ;setisp:
 19552                              <1>        ;mov     r1,-(sp)
 19553                              <1>        ;mov     r2,-(sp)
 19554                              <1>        ;mov     r3,-(sp)
 19555                              <1>        ;mov     clockp,-(sp)
 19556                              <1>        ;mov     $s.syst+2,clockp
 19557                              <1>        ;jmp     (r0)
 19558                              <1> 
 19559                              <1> clock: ; / interrupt from 60 cycle clock
 19560                              <1> 	
 19561                              <1> 	; 14/10/2015
 19562                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 19563                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
 19564                              <1> 
 19565                              <1>        ;mov     r0,-(sp) / save r0
 19566                              <1>        ;tst     *$lks / restart clock?
 19567                              <1>        ;mov     $s.time+2,r0 / increment the time of day
 19568                              <1>        ;inc     (r0)
 19569                              <1>        ;bne     1f
 19570                              <1>        ;inc     -(r0)
 19571                              <1> ;1:
 19572                              <1>        ;mov     clockp,r0 / increment appropriate time category
 19573                              <1>        ;inc     (r0)
 19574                              <1>        ;bne     1f
 19575                              <1>        ;inc     -(r0)
 19576                              <1> ;1:
 19577                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 19578                              <1> 
 19579 00005483 803D[94740000]00    <1> 	cmp	byte [u.quant], 0
 19580 0000548A 772C                <1> 	ja	short clk_1
 19581                              <1> 	;
 19582 0000548C 803D[4F740000]FF    <1>         cmp     byte [sysflg], 0FFh ; user or system space ?
 19583 00005493 7529                <1> 	jne	short clk_2 ; system space (sysflg <> 0FFh)
 19584 00005495 803D[A1740000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ?
 19585 0000549C 761A                <1> 	jna	short clk_1 ; yes, do not swap out
 19586 0000549E 66833D[96740000]00  <1> 	cmp	word [u.intr], 0
 19587 000054A6 7616                <1> 	jna	short clk_2
 19588                              <1> clk_0:
 19589                              <1> 	; 14/10/2015
 19590 000054A8 FE05[4F740000]      <1> 	inc	byte [sysflg] 	; Now, we are in system space
 19591 000054AE 58                  <1> 	pop	eax ; return address to the timer interrupt
 19592                              <1> 	;
 19593 000054AF B020                <1> 	MOV	AL,EOI			; GET END OF INTERRUPT MASK
 19594                              <1> 	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
 19595 000054B1 E620                <1> 	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
 19596                              <1> 	;
 19597 000054B3 E911ECFFFF          <1> 	jmp     sysrelease ; 'sys release' by clock/timer
 19598                              <1> clk_1:
 19599 000054B8 FE0D[94740000]      <1> 	dec	byte [u.quant]
 19600                              <1> clk_2:
 19601 000054BE C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
 19602                              <1> 
 19603                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
 19604                              <1> 
 19605                              <1>        ;mov     $uquant,r0 / decrement user time quantum
 19606                              <1>        ;decb    (r0)
 19607                              <1>        ;bge     1f / if less than 0
 19608                              <1>        ;clrb    (r0) / make it 0
 19609                              <1> ;1: / decrement time out counts return now if priority was not 0
 19610                              <1>        ;cmp     4(sp),$200 / ps greater than or equal to 200
 19611                              <1>        ;bge     2f / yes, check time outs
 19612                              <1>        ;tstb    (r0) / no, user timed out?
 19613                              <1>        ;bne     1f / no
 19614                              <1>        ;cmpb    sysflg,$-1 / yes, are we outside the system?
 19615                              <1>        ;bne     1f / no, 1f
 19616                              <1>        ;mov     (sp)+,r0 / yes, put users r0 in r0
 19617                              <1>        ;sys     0 / sysrele
 19618                              <1>        ;rti
 19619                              <1> ;2: / priority is high so just decrement time out counts
 19620                              <1>        ;mov     $toutt,r0 / r0 points to beginning of time out table
 19621                              <1> ;2:
 19622                              <1>        ;tstb    (r0) / is the time out?
 19623                              <1>        ;beq     3f / yes, 3f (get next entry)
 19624                              <1>        ;decb    (r0) / no, decrement the time
 19625                              <1>        ;bne     3f / isit zero now?
 19626                              <1>        ;incb    (r0) / yes, increment the time
 19627                              <1> ;3:
 19628                              <1>        ;inc     r0 / next entry
 19629                              <1>        ;cmp     r0,$touts / end of toutt table?
 19630                              <1>        ;blo     2b / no, check this entry
 19631                              <1>        ;mov     (sp)+,r0 / yes, restore r0
 19632                              <1>        ;rti / return from interrupt
 19633                              <1> ;1: / decrement time out counts; if 0 call subroutine
 19634                              <1>        ;mov     (sp)+,r0 / restore r0
 19635                              <1>        ;mov     $240,*$ps / set processor priority to 5
 19636                              <1>        ;jsr     r0,setisp / save registers
 19637                              <1>        ;mov     $touts-toutt-1,r0 / set up r0 as index to decrement thru
 19638                              <1>                                ;  / the table
 19639                              <1> ;1:
 19640                              <1>        ;tstb    toutt(r0) / is the time out for this entry
 19641                              <1>        ;beq     2f / yes
 19642                              <1>        ;decb    toutt(r0) / no, decrement the time
 19643                              <1>        ;bne     2f / is the time 0, now
 19644                              <1>        ;asl     r0 / yes, 2 x r0 to get word index for tout entry
 19645                              <1>        ;jsr     r0,*touts(r0) / go to appropriate routine specified in this
 19646                              <1>        ;asr     r0 / touts entry; set r0 back to toutt index
 19647                              <1> ;2:
 19648                              <1>        ;dec     r0 / set up r0 for next entry
 19649                              <1>        ;bge     1b / finished? , no, go back
 19650                              <1>        ;br      retisp / yes, restore registers and do a rti
 19651                              <1> 
 19652                              <1> ;retisp:
 19653                              <1>        ;mov     (sp)+,clockp / pop values before interrupt off the stack
 19654                              <1>        ;mov     (sp)+,r3
 19655                              <1>        ;mov     (sp)+,r2
 19656                              <1>        ;mov     (sp)+,r1
 19657                              <1>        ;mov     (sp)+,r0
 19658                              <1>        ;rti     / return from interrupt
 19659                              <1> 
 19660                              <1> 
 19661                              <1> wakeup: ; / wakeup processes waiting for an event 
 19662                              <1> 	; / by linking them to the queue
 19663                              <1> 	;
 19664                              <1> 	; 15/09/2015
 19665                              <1> 	; 29/06/2015
 19666                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 19667                              <1> 	;
 19668                              <1> 	; 15/05/2013 - 02/06/2014
 19669                              <1> 	; Retro UNIX 8086 v1 modification !
 19670                              <1> 	; (Process/task switching routine by using
 19671                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.)
 19672                              <1> 	;
 19673                              <1> 	; In original UNIX v1, 'wakeup' is called to wake the process
 19674                              <1> 	; sleeping in the specified wait channel by creating a link 
 19675                              <1> 	; to it from the last user process on the run queue.
 19676                              <1> 	; If there is no process to wake up, nothing happens.
 19677                              <1> 	;
 19678                              <1> 	; In Retro UNIX 8086 v1, Int 09h keyboard interrupt will set
 19679                              <1> 	; 'switching' status of the current process (owns current tty)
 19680                              <1> 	; (via alt + function keys) to a process which has highest
 19681                              <1> 	; priority (on run queue) on the requested tty (0 to 7, except
 19682                              <1> 	; 8 and 9 which are tty identifiers of COM1, COM2 serial ports)
 19683                              <1> 	; as it's console tty. (NOTE: 'p.ttyc' is used to set console
 19684                              <1> 	; tty for tty switching by keyboard.)	 
 19685                              <1> 	; 
 19686                              <1> 	; INPUT -> 
 19687                              <1> 	;	   AL = wait channel (r3) ('tty number' for now)
 19688                              <1> 	;	   ;;EBX = Run queue (r2) offset
 19689                              <1> 	;
 19690                              <1> 	; ((modified registers: EAX, EBX))
 19691                              <1> 	;
 19692 000054BF 0FB6D8              <1> 	movzx	ebx, al ; 29/06/2015
 19693 000054C2 81C3[D8700000]      <1> 	add	ebx, wlist
 19694 000054C8 8A03                <1> 	mov	al, [ebx] ; waiting list (waiting process number)
 19695 000054CA 20C0                <1> 	and	al, al
 19696 000054CC 7424                <1> 	jz	short wa0 ; nothing to wakeup
 19697                              <1> 	;
 19698 000054CE 30E4                <1> 	xor	ah, ah
 19699 000054D0 8825[94740000]      <1> 	mov 	[u.quant], ah ; 0 ; time quantum = 0	
 19700 000054D6 8823                <1> 	mov	[ebx], ah ; 0 ; zero wait channel entry
 19701                              <1> 	; 15/09/2015
 19702 000054D8 0FB6D8              <1> 	movzx	ebx, al
 19703 000054DB 88A3[B5710000]      <1> 	mov	[ebx+p.waitc-1], ah ; 0
 19704 000054E1 FEC4                <1> 	inc	ah
 19705 000054E3 88A3[D5710000]      <1> 	mov	byte [ebx+p.stat-1], ah ; 1 ; SRUN
 19706                              <1> 	;
 19707 000054E9 57                  <1> 	push	edi
 19708 000054EA 52                  <1> 	push	edx
 19709 000054EB E84AFFFFFF          <1> 	call	putlu
 19710 000054F0 5A                  <1> 	pop	edx
 19711 000054F1 5F                  <1> 	pop	edi
 19712                              <1> wa0:
 19713 000054F2 C3                  <1> 	retn
 19714                              <1> 
 19715                              <1> sleep: 
 19716                              <1> 	; 15/09/2015
 19717                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 19718                              <1> 	;
 19719                              <1> 	; 09/05/2013 - 20/03/2014
 19720                              <1> 	;
 19721                              <1> 	; Retro UNIX 8086 v1 modification !
 19722                              <1> 	; (Process/task switching and quit routine by using
 19723                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 19724                              <1> 	;
 19725                              <1> 	; In original UNIX v1, 'sleep' is called to wait for
 19726                              <1> 	; tty and tape output or input becomes available
 19727                              <1> 	; and process is put on waiting channel and swapped out,
 19728                              <1> 	; then -when the tty or tape is ready to write or read-
 19729                              <1> 	; 'wakeup' gets process back to active swapped-in status.)
 19730                              <1> 	;
 19731                              <1> 	; In Retro UNIX 8086 v1, Int 1Bh ctrl+brk interrupt and
 19732                              <1> 	; Int 09h keyboard interrupt will set 'quit' or 'switching'		
 19733                              <1> 	; status of the current process also INT 1Ch will count down
 19734                              <1> 	; 'uquant' value and INT 09h will redirect scancode of keystroke
 19735                              <1> 	; to tty buffer of the current process and kernel will get
 19736                              <1> 	; user input by using tty buffer of the current process
 19737                              <1> 	; (instead of standard INT 16h interrupt).
 19738                              <1> 	; TTY output will be redirected to related video page of text mode
 19739                              <1> 	; (INT 10h will be called with different video page depending
 19740                              <1> 	; on tty assignment of the active process: 0 to 7 for
 19741                              <1> 	; pseudo screens.)
 19742                              <1> 	;
 19743                              <1> 	; In Retro UNIX 8086 v1, 'sleep' will be called to wait for
 19744                              <1> 	; a keystroke from keyboard or wait for reading or writing
 19745                              <1> 	; characters/data on serial port(s).
 19746                              <1> 	;
 19747                              <1> 	; Character/Terminal input/output through COM1 and COM2 will be
 19748                              <1> 	; performed by related routines in addition to pseudo TTY routines.
 19749                              <1> 	; 
 19750                              <1> 	; R1 = AH = wait channel (0-9 for TTYs) ; 05/10/2013 (22/09/2013)
 19751                              <1> 	;
 19752                              <1> 	;; 05/10/2013
 19753                              <1>         ;10/12/2013
 19754                              <1> 	;cmp   byte [u.uno], 1
 19755                              <1>         ;ja    short sleep0
 19756                              <1> 	;retn
 19757                              <1> 
 19758                              <1> 	; 20/03/2014
 19759                              <1> 	;mov	bx, [runq]
 19760                              <1> 	;cmp	bl, bh
 19761                              <1> 	;jne	short sleep0	
 19762                              <1> 	; 25/02/2014
 19763                              <1> 	;cmp word ptr [runq], 0
 19764                              <1> 	;ja short sleep0	
 19765                              <1> 	;retn
 19766                              <1> sleep0:
 19767                              <1> 	;
 19768 000054F3 E854000000          <1> 	call	isintr
 19769 000054F8 0F856FEBFFFF        <1> 	jnz	sysret
 19770                              <1> 		; / wait for event
 19771                              <1>        		; jsr r0,isintr / check to see if interrupt 
 19772                              <1> 			      ; / or quit from user
 19773                              <1>                		; br 2f / something happened
 19774                              <1> 			      ; / yes, his interrupt so return
 19775                              <1>                      	      ;	/ to user
 19776                              <1> 
 19777                              <1> 	; 30/06/2015
 19778 000054FE 0FB6DC              <1>     	movzx	ebx, ah ; 30/06/2015
 19779 00005501 81C3[D8700000]      <1> 	add	ebx, wlist
 19780 00005507 8A03                <1> 	mov	al, [ebx]
 19781 00005509 20C0                <1> 	and	al, al
 19782 0000550B 7407                <1> 	jz	short sleep1
 19783 0000550D 53                  <1> 	push	ebx
 19784 0000550E E827FFFFFF          <1> 	call	putlu
 19785 00005513 5B                  <1> 	pop	ebx
 19786                              <1> sleep1:
 19787 00005514 A0[A1740000]        <1> 	mov	al, [u.uno]    
 19788 00005519 8803                <1>   	mov	[ebx], al 	; put the process number
 19789                              <1> 				; in the wait channel
 19790                              <1> 		; mov (r0)+,r1 / put number of wait channel in r1
 19791                              <1> 		; movb wlist(r1),-(sp) / put old process number in there,
 19792                              <1> 				     ; / on the stack
 19793                              <1>        		; movb u.uno,wlist(r1) / put process number of process
 19794                              <1> 				     ; / to put to sleep in there
 19795                              <1>         ; 15/09/2015
 19796 0000551B 0FB6D8              <1> 	movzx	ebx, al
 19797 0000551E C683[D5710000]04    <1>         mov     byte [ebx+p.stat-1], 4 ; SSLEEP
 19798 00005525 FEC4                <1> 	inc	ah
 19799 00005527 88A3[B5710000]      <1> 	mov	[ebx+p.waitc-1], ah ; wait channel + 1
 19800                              <1> 	;
 19801 0000552D 66FF35[3E740000]    <1> 	push    word [cdev]
 19802                              <1> 		; mov cdev,-(sp) / nothing happened in isintr so
 19803 00005534 E833FEFFFF          <1> 	call	swap
 19804                              <1>        		; jsr r0,swap / swap out process that needs to sleep
 19805 00005539 668F05[3E740000]    <1>         pop     word [cdev]
 19806                              <1> 		; mov (sp)+,cdev / restore device
 19807 00005540 E807000000          <1> 	call	isintr
 19808                              <1> 	; 22/09/2013
 19809 00005545 0F8522EBFFFF        <1> 	jnz	sysret         
 19810                              <1> 		; jsr r0,isintr / check for interrupt of new process
 19811                              <1>                		; br 2f / yes, return to new user
 19812                              <1> 		; movb (sp)+,r1 / no, r1 = old process number that was 
 19813                              <1> 				; / originally on the wait channel
 19814                              <1>        		; beq 1f / if 0 branch
 19815                              <1>   		; mov $runq+4,r2 / r2 points to lowest priority queue
 19816                              <1>        		; mov $300,*$ps / processor priority = 6
 19817                              <1> 		; jsr r0,putlu / create link to old process number
 19818                              <1>        		; clr *$ps / clear the status; process priority = 0
 19819                              <1>      ;1:
 19820 0000554B C3                  <1> 	retn
 19821                              <1> 		; rts r0 / return
 19822                              <1>      ;2:
 19823                              <1>         ;;jmp	sysret
 19824                              <1> 		; jmp sysret / return to user
 19825                              <1> 
 19826                              <1> isintr:
 19827                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 19828                              <1> 	;
 19829                              <1> 	; 09/05/2013 - 30/05/2014
 19830                              <1> 	;
 19831                              <1> 	; Retro UNIX 8086 v1 modification !
 19832                              <1> 	; (Process/task switching and quit routine by using
 19833                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 19834                              <1> 	;
 19835                              <1> 	; Retro UNIX 8086 v1 modification:
 19836                              <1> 	; 'isintr' checks if user interrupt request is enabled
 19837                              <1> 	;  and there is a 'quit' request by user;
 19838                              <1> 	;  otherwise, 'isintr' will return with zf=1 that means
 19839                              <1> 	;  "nothing to do". (20/10/2013)
 19840                              <1> 	;
 19841                              <1> 	; 20/10/2013
 19842 0000554C 66833D[88740000]00  <1> 	cmp 	word [u.ttyp], 0 ; has process got a tty ?
 19843 00005554 7622                <1> 	jna	short isintr2 ; retn
 19844                              <1> 	; 03/09/2013
 19845                              <1> 	; (nothing to do)
 19846                              <1> 	;retn
 19847                              <1> 	; 22/09/2013
 19848 00005556 66833D[96740000]00  <1> 	cmp	word [u.intr], 0
 19849 0000555E 7618                <1> 	jna	short isintr2 ; retn
 19850                              <1> 	; 30/05/2014
 19851 00005560 6650                <1> 	push	ax 
 19852 00005562 66A1[98740000]      <1> 	mov	ax, [u.quit]
 19853 00005568 6609C0              <1> 	or	ax, ax ; 0 ?
 19854 0000556B 7409                <1> 	jz	short isintr1 ; zf = 1
 19855 0000556D 6683F8FE            <1> 	cmp	ax, 0FFFEh  ; 'ctrl + brk' check
 19856 00005571 7703                <1> 	ja	short isintr1 ; 0FFFFh, zf = 0
 19857 00005573 6631C0              <1> 	xor	ax, ax ; zf = 1
 19858                              <1> isintr1:
 19859 00005576 6658                <1> 	pop	ax
 19860                              <1> isintr2: ; 22/09/2013
 19861                              <1> 	; zf=1 -> nothing to do
 19862 00005578 C3                  <1> 	retn
 19863                              <1> 
 19864                              <1> 	; UNIX v1 original 'isintr' routine... 
 19865                              <1>        	;mov     r1,-(sp) / put number of wait channel on the stack
 19866                              <1>        	;mov     r2,-(sp) / save r2
 19867                              <1>        	;mov     u.ttyp,r1 / r1 = pointer to buffer of process control
 19868                              <1>         ;                 / typewriter
 19869                              <1>        	;beq     1f / if 0, do nothing except skip return
 19870                              <1>        	;movb    6(r1),r1 / put interrupt char in the tty buffer in r1
 19871                              <1>        	;beq     1f / if its 0 do nothing except skip return
 19872                              <1>        	;cmp     r1,$177 / is interrupt char = delete?
 19873                              <1>        	;bne     3f / no, so it must be a quit (fs)
 19874                              <1>        	;tst     u.intr / yes, value of u.intr determines handling
 19875                              <1>         ;              / of interrupts
 19876                              <1>        	;bne     2f / if not 0, 2f. If zero do nothing.
 19877                              <1>      ;1:
 19878                              <1>        	;tst     (r0)+ / bump r0 past system return (skip)
 19879                              <1>      ;4:
 19880                              <1>        	;mov     (sp)+,r2 / restore r1 and r2
 19881                              <1>        	;mov     (sp)+,r1
 19882                              <1>        	;rts     r0
 19883                              <1>      ;3: / interrupt char = quit (fs)
 19884                              <1>        	;tst     u.quit / value of u.quit determines handling of quits
 19885                              <1>        	;beq     1b / u.quit = 0 means do nothing
 19886                              <1>      ;2: / get here because either u.intr <> 0 or u.qult <> O
 19887                              <1>        	;mov     $tty+6,r1 / move pointer to tty block into r1
 19888                              <1>      ;1: / find process control tty entry in tty block
 19889                              <1>        	;cmp     (r1),u.ttyp / is this the process control tty buffer?
 19890                              <1>        	;beq     1f / block found go to 1f
 19891                              <1>        	;add     $8,r1 / look at next tty block
 19892                              <1>        	;cmp     r1,$tty+[ntty*8]+6 / are we at end of tty blocks
 19893                              <1>        	;blo     1b / no
 19894                              <1>        	;br      4b / no process control tty found so go to 4b
 19895                              <1>      ;1:
 19896                              <1>        	;mov     $240,*$ps / set processor priority to 5
 19897                              <1>        	;movb    -3(r1),0f / load getc call argument; character llst
 19898                              <1>         ;                  / identifier
 19899                              <1>        	;inc     0f / increment
 19900                              <1>      ;1:
 19901                              <1>        	;jsr     r0,getc; 0:.. / erase output char list for control
 19902                              <1>         ;        br 4b / process tty. This prevents a line of stuff
 19903                              <1>         ;             / being typed out after you hit the interrupt
 19904                              <1>         ;             / key
 19905                              <1>        	;br      1b
 19906                                  %include 'u5.s'        ; 03/06/2015
 19907                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS5.INC
 19908                              <1> ; Last Modification: 14/11/2015
 19909                              <1> ; ----------------------------------------------------------------------------
 19910                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 19911                              <1> ; (v0.1 - Beginning: 11/07/2012)
 19912                              <1> ;
 19913                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 19914                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 19915                              <1> ; <Bell Laboratories (17/3/1972)>
 19916                              <1> ; <Preliminary Release of UNIX Implementation Document>
 19917                              <1> ;
 19918                              <1> ; Retro UNIX 8086 v1 - U5.ASM (07/08/2013) //// UNIX v1 -> u5.s
 19919                              <1> ;
 19920                              <1> ; ****************************************************************************
 19921                              <1> 
 19922                              <1> mget:
 19923                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 19924                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 19925                              <1> 	;
 19926                              <1> 	; Get existing or (allocate) a new disk block for file
 19927                              <1> 	; 
 19928                              <1> 	; INPUTS ->
 19929                              <1> 	;    u.fofp (file offset pointer)
 19930                              <1> 	;    inode 
 19931                              <1> 	;    u.off (file offset)
 19932                              <1> 	; OUTPUTS ->
 19933                              <1> 	;    r1 (physical block number)
 19934                              <1> 	;    r2, r3, r5 (internal)
 19935                              <1> 	;
 19936                              <1> 	; ((AX = R1)) output
 19937                              <1> 	;    (Retro UNIX Prototype : 05/03/2013 - 14/11/2012, UNIXCOPY.ASM)
 19938                              <1>         ;    ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 19939                              <1> 
 19940                              <1> 		; mov *u.fofp,mq / file offset in mq
 19941                              <1> 		; clr ac / later to be high sig
 19942                              <1> 		; mov $-8,lsh   / divide ac/mq by 256.
 19943                              <1> 		; mov mq,r2
 19944                              <1> 		; bit $10000,i.flgs / lg/sm is this a large or small file
 19945                              <1> 		; bne 4f / branch for large file
 19946                              <1> mget_0:	
 19947 00005579 8B35[68740000]      <1>         mov     esi, [u.fofp]
 19948 0000557F 0FB65E01            <1>         movzx   ebx, byte [esi+1]
 19949                              <1>         ; BX = r2
 19950 00005583 66F705[26710000]00- <1>         test 	word [i.flgs], 4096 ; 1000h
 19951 0000558B 10                  <1>
 19952                              <1> 			  	     ; is this a large or small file
 19953 0000558C 756F                <1> 	jnz 	short mget_5 ; 4f ; large file
 19954                              <1> 
 19955 0000558E F6C3F0              <1>         test    bl, 0F0h ; !0Fh                    
 19956                              <1> 		; bit $!17,r2
 19957 00005591 7526                <1> 	jnz 	short mget_2
 19958                              <1> 		; bne 3f / branch if r2 greater than or equal to 16
 19959 00005593 80E30E              <1>         and     bl, 0Eh  
 19960                              <1> 		; bic $!16,r2 / clear all bits but bits 1,2,3
 19961 00005596 0FB783[2C710000]    <1> 	movzx 	eax, word [ebx+i.dskp] ; AX = R1, physical block number
 19962                              <1> 		; mov i.dskp(r2),r1 / r1 has physical block number
 19963 0000559D 6609C0              <1> 	or 	ax, ax
 19964 000055A0 7516                <1> 	jnz 	short mget_1 
 19965                              <1> 		; bne 2f / if physical block num is zero then need a new block
 19966                              <1> 		       ; / for file
 19967 000055A2 E8AB000000          <1> 	call 	alloc
 19968                              <1> 		; jsr r0,alloc / allocate a new block
 19969                              <1>          ; eAX (r1) = Physical block number
 19970 000055A7 668983[2C710000]    <1> 	mov 	[ebx+i.dskp], ax
 19971                              <1> 		; mov r1,i.dskp(r2) / physical block number stored in i-node
 19972 000055AE E84C020000          <1> 	call 	setimod	
 19973                              <1> 		; jsr r0,setimod / set inode modified byte (imod)
 19974 000055B3 E8B1FEFFFF          <1> 	call	clear
 19975                              <1> 		; jsr r0,clear / zero out disk/drum block just allocated
 19976                              <1> mget_1: ; 2:
 19977                              <1>         ; eAX (r1) = Physical block number
 19978 000055B8 C3                  <1> 	retn 
 19979                              <1> 		; rts r0
 19980                              <1> mget_2: ; 3: / adding on block which changes small file to a large file
 19981 000055B9 E894000000          <1> 	call 	alloc
 19982                              <1> 		; jsr r0,alloc / allocate a new block for this file;
 19983                              <1> 	                     ; / block number in r1
 19984                              <1>         ; eAX (r1) = Physical block number
 19985 000055BE E8560C0000          <1> 	call 	wslot
 19986                              <1> 		; jsr r0,wslot / set up I/O buffer for write, r5 points to 
 19987                              <1> 			     ; / first data word in buffer
 19988                              <1>         ; eAX (r1) = Physical block number
 19989 000055C3 B908000000          <1> 	mov 	ecx, 8  ; R3, transfer old physical block pointers
 19990                              <1> 		   ; into new indirect block area for the new
 19991                              <1> 		   ; large file		
 19992 000055C8 89DF                <1> 	mov 	edi, ebx ; r5
 19993 000055CA BE[2C710000]        <1> 	mov 	esi, i.dskp 
 19994                              <1> 		; mov $8.,r3 / next 6 instructions transfer old physical 
 19995                              <1> 			   ; / block pointers
 19996                              <1> 		; mov $i.dskp,r2 / into new indirect block for the new 
 19997                              <1> 			  ; / large file
 19998 000055CF 6631C0              <1> 	xor 	ax, ax ; mov ax, 0
 19999                              <1> mget_3: ;1:
 20000 000055D2 66A5                <1> 	movsw
 20001                              <1> 		; mov (r2),(r5)+
 20002 000055D4 668946FE            <1> 	mov 	[esi-2], ax
 20003                              <1> 		; clr (r2)+
 20004 000055D8 E2F8                <1> 	loop	mget_3 ; 1b
 20005                              <1> 		; dec r3
 20006                              <1> 		; bgt 1b
 20007                              <1> 
 20008 000055DA B1F8                <1> 	mov 	cl, 256-8
 20009                              <1> 		; mov $256.-8.,r3 / clear rest of data buffer
 20010                              <1> mget_4:	; 1
 20011 000055DC F366AB              <1> 	rep 	stosw
 20012                              <1> 		; clr (r5)+
 20013                              <1> 		; dec r3
 20014                              <1> 		; bgt 1b
 20015                              <1> 	; 24/03/2013
 20016                              <1>         ; AX (r1) = Physical block number
 20017 000055DF E8510C0000          <1> 	call	dskwr
 20018                              <1> 		; jsr r0,dskwr / write new indirect block on disk
 20019                              <1>         ; eAX (r1) = Physical block number
 20020 000055E4 66A3[2C710000]      <1> 	mov 	[i.dskp], ax
 20021                              <1> 		; mov r1,i.dskp / put pointer to indirect block in i-node
 20022 000055EA 66810D[26710000]00- <1> 	or 	word [i.flgs], 4096 ; 1000h
 20023 000055F2 10                  <1>
 20024                              <1> 		; bis $10000,i.flgs / set large file bit 
 20025                              <1> 				  ; / in i.flgs word of i-node
 20026 000055F3 E807020000          <1> 	call	setimod
 20027                              <1> 		; jsr r0,setimod / set i-node modified flag
 20028 000055F8 E97CFFFFFF          <1>         jmp     mget_0 
 20029                              <1> 		; br mget
 20030                              <1> 
 20031                              <1> mget_5:  ; 4 ; large file
 20032                              <1> 		; mov $-8,lsh / divide byte number by 256.
 20033                              <1> 		; bic $!776,r2 / zero all bits but 1,2,3,4,5,6,7,8; gives offset
 20034                              <1> 			    ; / in indirect block
 20035                              <1> 		; mov r2,-(sp) / save on stack (*)
 20036                              <1> 		; mov mq,r2 / calculate offset in i-node for pointer to proper
 20037                              <1>        		          ; / indirect block
 20038                              <1> 		; bic $!16,r2
 20039 000055FD 80E3FE              <1>         and     bl, 0FEh ; bh = 0
 20040 00005600 53                  <1>         push    ebx  ; i-node pointer offset in indirect block  (*) 
 20041                              <1>         ; 01/03/2013 Max. possible BX (offset) value is 127 (65535/512)
 20042                              <1> 	; 	     for this file system (offset 128 to 255 not in use)
 20043                              <1> 	; There is always 1 indirect block for this file system
 20044 00005601 0FB705[2C710000]    <1> 	movzx 	eax, word [i.dskp] ; i.dskp[0]
 20045                              <1> 		; mov i.dskp(r2),r1
 20046 00005608 6609C0              <1> 	or 	ax, ax ; R1
 20047 0000560B 7515                <1> 	jnz 	short mget_6 ; 2f
 20048                              <1> 		; bne 2f / if no indirect block exists
 20049 0000560D E840000000          <1> 	call 	alloc
 20050                              <1> 		; jsr r0,alloc / allocate a new block
 20051 00005612 66A3[2C710000]      <1> 	mov 	[i.dskp], ax  ; 03/03/2013
 20052                              <1> 		; mov r1,i.dskp(r2) / put block number of new block in i-node
 20053 00005618 E8E2010000          <1> 	call 	setimod
 20054                              <1> 		; jsr r0,setimod / set i-node modified byte
 20055                              <1> 	; eAX = new block number
 20056 0000561D E847FEFFFF          <1> 	call 	clear
 20057                              <1> 		; jsr r0,clear / clear new block
 20058                              <1> mget_6: ;2
 20059                              <1> 	; 05/03/2013
 20060                              <1> 	; eAX = r1, physical block number (of indirect block)
 20061 00005622 E8920B0000          <1> 	call 	dskrd ; read indirect block
 20062                              <1> 		; jsr r0,dskrd / read in indirect block
 20063 00005627 5A                  <1> 	pop 	edx  ; R2, get offset (*)
 20064                              <1> 		; mov (sp)+,r2 / get offset
 20065                              <1> 	; eAX = r1, physical block number (of indirect block)
 20066 00005628 50                  <1> 	push 	eax ; ** ; 24/03/2013
 20067                              <1> 		; mov r1,-(sp) / save block number of indirect block on stack
 20068                              <1> 	; eBX (r5) = pointer to buffer (indirect block)
 20069 00005629 01D3                <1> 	add 	ebx, edx ; / r5 points to first word in indirect block, r2
 20070                              <1> 		; add r5,r2 / r5 points to first word in indirect block, r2
 20071                              <1> 	                  ; / points to location of inter
 20072 0000562B 0FB703              <1> 	movzx 	eax, word [ebx] ; put physical block no of block
 20073                              <1> 			      ; in file sought in R1 (AX)
 20074                              <1> 		; mov (r2),r1 / put physical block no of block in file
 20075                              <1> 	               	    ; / sought in r1
 20076 0000562E 6609C0              <1> 	or 	ax, ax
 20077 00005631 751D                <1>         jnz 	short mget_7 ; 2f
 20078                              <1> 		; bne 2f / if no block exists 
 20079 00005633 E81A000000          <1> 	call 	alloc
 20080                              <1> 		; jsr r0,alloc / allocate a new block
 20081 00005638 668903              <1> 	mov 	[ebx], ax ; R1
 20082                              <1> 		; mov r1,(r2) / put new block number into proper location in
 20083                              <1> 	                    ; / indirect block
 20084 0000563B 5A                  <1> 	pop	edx ; ** ; 24/03/2013
 20085                              <1> 		; mov (sp)+,r1 / get block number of indirect block
 20086 0000563C 52                  <1> 	push 	edx ; ** ; 31/07/2013
 20087 0000563D 50                  <1> 	push	eax ; * ; 24/03/2013, 31/07/2013 (new block number)
 20088 0000563E 89D0                <1> 	mov	eax, edx ; 24/03/2013
 20089                              <1> 		; mov (r2),-(sp) / save block number of new block
 20090                              <1> 	; eAX (r1) = physical block number (of indirect block)
 20091 00005640 E8D40B0000          <1> 	call 	wslot
 20092                              <1> 		; jsr r0,wslot
 20093                              <1>         ; eAX (r1) = physical block number
 20094                              <1> 	; eBX (r5) = pointer to buffer (indirect block)
 20095 00005645 E8EB0B0000          <1> 	call 	dskwr
 20096                              <1> 	; eAX = r1 = physical block number (of indirect block)
 20097                              <1> 		; jsr r0,dskwr / write newly modified indirect block 
 20098                              <1> 			     ; / back out on disk
 20099 0000564A 58                  <1> 	pop	eax ; *  ; 31/07/2013
 20100                              <1> 		; mov (sp),r1 / restore block number of new block	
 20101                              <1> 	; eAX (r1) = physical block number of new block
 20102 0000564B E819FEFFFF          <1> 	call 	clear
 20103                              <1> 		; jsr r0,clear / clear new block	
 20104                              <1> mget_7: ; 2
 20105 00005650 5A                  <1> 	pop 	edx ; **
 20106                              <1> 		; tst (sp)+ / bump stack pointer
 20107                              <1> 	; eAX (r1) = Block number of new block
 20108 00005651 C3                  <1> 	retn
 20109                              <1> 		; rts r0
 20110                              <1> 
 20111                              <1> alloc:
 20112                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20113                              <1> 	; 01/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20114                              <1> 	;
 20115                              <1> 	; get a free block and 
 20116                              <1> 	; set the corresponding bit in the free storage map
 20117                              <1> 	; 
 20118                              <1> 	; INPUTS ->
 20119                              <1> 	;    cdev (current device)
 20120                              <1> 	;    r2 
 20121                              <1> 	;    r3
 20122                              <1> 	; OUTPUTS ->
 20123                              <1> 	;    r1 (physical block number of block assigned)
 20124                              <1> 	;    smod, mmod, systm (super block), mount (mountable super block)	
 20125                              <1> 	;
 20126                              <1> 	; ((AX = R1)) output
 20127                              <1> 	;    (Retro UNIX Prototype : 14/11/2012 - 21/07/2012, UNIXCOPY.ASM)
 20128                              <1>         ;    ((Modified registers: DX, CX))  
 20129                              <1> 
 20130                              <1> 		;mov r2,-(sp) / save r2, r3 on stack
 20131                              <1> 		;mov r3,-(sp)
 20132                              <1> 	;push 	ecx
 20133 00005652 53                  <1> 	push 	ebx ; R2
 20134                              <1> 	;push 	edx ; R3
 20135 00005653 BB[10810000]        <1> 	mov 	ebx, systm ; SuperBlock 
 20136                              <1> 		; mov $systm,r2 / start of inode and free storage map for drum
 20137 00005658 803D[3E740000]00    <1> 	cmp 	byte [cdev], 0
 20138                              <1> 		; tst cdev
 20139 0000565F 7605                <1> 	jna	short alloc_1
 20140                              <1> 		; beq 1f / drum is device
 20141 00005661 BB[18830000]        <1> 	mov	ebx, mount
 20142                              <1> 		; mov $mount,r2 / disk or tape is device, start of inode and
 20143                              <1> 			      ; / free storage map
 20144                              <1> alloc_1: ; 1
 20145 00005666 668B0B              <1>         mov	cx, [ebx]
 20146                              <1> 		; mov (r2)+,r1 / first word contains number of bytes in free
 20147                              <1> 			     ; / storage map
 20148 00005669 66C1E103            <1> 	shl	cx, 3
 20149                              <1> 		; asl r1 / multiply r1 by eight gives 
 20150                              <1> 		; number of blocks in device
 20151                              <1> 		; asl r1
 20152                              <1> 		; asl r1
 20153                              <1> 	;; push cx ;; 01/08/2013
 20154                              <1> 		; mov r1,-(sp) / save # of blocks in device on stack
 20155 0000566D 31C0                <1> 	xor 	eax, eax ; 0
 20156                              <1> 		; clr r1 / r1 contains bit count of free storage map
 20157                              <1> alloc_2: ; 1
 20158 0000566F 43                  <1> 	inc 	ebx ; 18/8/2012
 20159 00005670 43                  <1> 	inc 	ebx ; 
 20160 00005671 668B13              <1> 	mov 	dx, [ebx]
 20161                              <1> 		; mov (r2)+,r3 / word of free storage map in r3 
 20162 00005674 6609D2              <1> 	or 	dx, dx
 20163 00005677 750E                <1> 	jnz 	short alloc_3 ; 1f
 20164                              <1> 		; bne 1f / branch if any free blocks in this word	
 20165 00005679 6683C010            <1> 	add 	ax, 16
 20166                              <1> 		; add $16.,r1
 20167 0000567D 6639C8              <1> 	cmp 	ax, cx    
 20168                              <1> 		; cmp r1 ,(sp) / have we examined all free storage bytes
 20169 00005680 72ED                <1> 	jb 	short alloc_2
 20170                              <1> 		; blo 1b
 20171                              <1> 	; 14/11/2015
 20172                              <1> 	; Note: If the super block buffer has wrong content (zero bytes)
 20173                              <1> 	;	because of a (DMA or another) r/w error, 
 20174                              <1> 	;	we will be here, at 'jmp panic' code address,
 20175                              <1> 	;	even if the (disk) file system space is not full !!!
 20176                              <1> 	;	(cx = 0)	
 20177                              <1> 	;
 20178 00005682 E949E2FFFF          <1> 	jmp     panic 
 20179                              <1> 		; jmp panic / found no free storage
 20180                              <1> alloc_3: ; 1
 20181 00005687 66D1EA              <1> 	shr	dx, 1
 20182                              <1> 		; asr r3 / find a free block
 20183 0000568A 7204                <1> 	jc	short alloc_4 ; 1f
 20184                              <1> 		; bcs 1f / branch when free block found; bit for block k
 20185                              <1> 		       ; / is in byte k/8 / in bit k (mod 8)
 20186 0000568C 6640                <1> 	inc	ax
 20187                              <1> 		; inc r1 / increment bit count in bit k (mod8)
 20188 0000568E EBF7                <1> 	jmp 	short alloc_3
 20189                              <1> 		; br 1b
 20190                              <1> alloc_4: ; 1:
 20191                              <1> 	;; pop cx ;; 01/08/2013
 20192                              <1> 		; tst (sp)+ / bump sp
 20193                              <1> 	; 02/04/2013 
 20194 00005690 E829000000          <1> 	call	free3
 20195                              <1> 		; jsr r0,3f / have found a free block
 20196                              <1> 	; 21/8/2012
 20197 00005695 66F7D2              <1> 	not 	dx ; masking bit is '0' and others are '1'
 20198 00005698 662113              <1> 	and	[ebx], dx   ;; 0 -> allocated 
 20199                              <1> 		; bic r3,(r2) / set bit for this block 
 20200                              <1> 		            ; / i.e. assign block
 20201                              <1> 		; br 2f
 20202 0000569B EB09                <1> 	jmp 	short alloc_5
 20203                              <1> 
 20204                              <1> free:
 20205                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20206                              <1> 	; 07/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20207                              <1> 	;
 20208                              <1> 	; calculates byte address and bit position for given block number
 20209                              <1> 	; then sets the corresponding bit in the free storage map
 20210                              <1> 	; 
 20211                              <1> 	; INPUTS ->
 20212                              <1> 	;    r1 - block number for a block structured device
 20213                              <1> 	;    cdev - current device 
 20214                              <1> 	; OUTPUTS ->
 20215                              <1> 	;    free storage map is updated
 20216                              <1> 	;    smod is incremented if cdev is root device (fixed disk)
 20217                              <1> 	;    mmod is incremented if cdev is a removable disk 	
 20218                              <1> 	;
 20219                              <1> 	;  (Retro UNIX Prototype : 01/12/2012, UNIXCOPY.ASM)
 20220                              <1>         ;  ((Modified registers: DX, CX))  
 20221                              <1> 
 20222                              <1> 		;mov r2,-(sp) / save r2, r3
 20223                              <1> 		;mov r3,-(sp)
 20224                              <1> 	;push 	ecx
 20225 0000569D 53                  <1> 	push 	ebx ; R2
 20226                              <1> 	;push 	edx ; R3 
 20227                              <1> 
 20228 0000569E E81B000000          <1>         call    free3
 20229                              <1> 	     	; jsr r0,3f  / set up bit mask and word no. 
 20230                              <1> 				 ; / in free storage map for block
 20231 000056A3 660913              <1> 	or 	[ebx], dx  
 20232                              <1> 	  	; bis r3, (r2) / set free storage block bit;
 20233                              <1> 			    ;  / indicates free block	
 20234                              <1> 	; 0 -> allocated, 1 -> free
 20235                              <1> 
 20236                              <1> alloc_5:
 20237                              <1> 	; 07/04/2013
 20238                              <1> free_1: ; 2:
 20239                              <1> 	; pop 	edx
 20240                              <1> 		; mov (sp)+,r3 / restore r2, r3
 20241 000056A6 5B                  <1> 	pop	ebx
 20242                              <1> 		; mov (sp)+,r2
 20243                              <1> 	; pop	ecx
 20244 000056A7 803D[3E740000]00    <1> 	cmp 	byte [cdev], 0
 20245                              <1> 		; tst cdev / cdev = 0, block structured, drum; 
 20246                              <1> 			 ; / cdev = 1, mountable device
 20247 000056AE 7707                <1> 	ja	short alloc_6 ; 1f
 20248                              <1> 		; bne 1f
 20249                              <1> 	;mov	byte [smod], 1
 20250 000056B0 FE05[4D740000]      <1> 	inc 	byte [smod]
 20251                              <1> 		; incb smod / set super block modified for drum
 20252                              <1> 	; eAX (r1) = block number
 20253 000056B6 C3                  <1> 	retn
 20254                              <1> 		; rts r0
 20255                              <1> free_2:
 20256                              <1> alloc_6: ; 1:
 20257                              <1> 	;mov 	byte [mmod], 1
 20258 000056B7 FE05[4E740000]      <1> 	inc 	byte [mmod]
 20259                              <1> 		; incb	mmod 
 20260                              <1> 		  ; / set super block modified for mountable device
 20261                              <1> 	; eAX (r1) = block number
 20262 000056BD C3                  <1> 	retn	
 20263                              <1> 		; rts r0
 20264                              <1> free3:
 20265                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20266                              <1> 	; 02/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20267                              <1> 	;
 20268                              <1> 	; free3 is called from 'alloc' and 'free' procedures
 20269                              <1> 	; 
 20270                              <1> alloc_free_3: ; 3
 20271 000056BE 66BA0100            <1> 	mov 	dx, 1
 20272 000056C2 88C1                <1> 	mov 	cl, al
 20273                              <1> 		; mov r1,r2 / block number, k, = 1		
 20274 000056C4 80E10F              <1> 	and 	cl, 0Fh  ; 0Fh <-- (k) mod 16
 20275                              <1> 		; bic $!7,r2 / clear all bits but 0,1,2; r2 = (k) mod (8)
 20276 000056C7 7403                <1> 	jz 	short free4
 20277                              <1> 		; bisb 2f(r2),r3 / use mask to set bit in r3 corresponding to
 20278                              <1> 			       ; / (k) mod 8
 20279 000056C9 66D3E2              <1> 	shl 	dx, cl
 20280                              <1> free4:
 20281 000056CC 0FB7D8              <1> 	movzx 	ebx, ax
 20282                              <1> 		; mov r1,r2 / divide block number by 16
 20283 000056CF 66C1EB04            <1> 	shr 	bx, 4
 20284                              <1> 		; asr r2
 20285                              <1> 		; asr r2
 20286                              <1> 		; asr r2
 20287                              <1> 		; asr r2
 20288                              <1> 		; bcc 1f / branch if bit 3 in r1 was 0 i.e., 
 20289                              <1> 		       ; / bit for block is in lower half of word
 20290                              <1> 		; swab r3 / swap bytes in r3; bit in upper half of word in free
 20291                              <1> 		        ; / storage map
 20292                              <1> alloc_free_4: ; 1
 20293 000056D3 66D1E3              <1> 	shl 	bx, 1
 20294                              <1> 		; asl r2 / multiply block number by 2; r2 = k/8
 20295 000056D6 81C3[12810000]      <1> 	add 	ebx, systm+2 ; SuperBlock+2
 20296                              <1> 		; add $systm+2,r2 / address of word of free storage map for drum
 20297                              <1> 	    		        ; / with block bit in it 	
 20298 000056DC 803D[3E740000]00    <1> 	cmp	byte [cdev], 0
 20299                              <1> 		; tst cdev
 20300 000056E3 7606                <1> 	jna	short alloc_free_5
 20301                              <1> 		; beq 1f / cdev = 0 indicates device is drum
 20302 000056E5 81C308020000        <1> 	add	ebx, mount - systm
 20303                              <1> 		; add $mount-systm,r2 / address of word of free storage map for
 20304                              <1> 				    ; / mountable device with bit of block to be
 20305                              <1> 				    ; / freed
 20306                              <1> alloc_free_5: ; 1 
 20307 000056EB C3                  <1> 	retn
 20308                              <1> 		; rts r0 / return to 'free'
 20309                              <1> 	      ; 2
 20310                              <1> 	        ; .byte	1,2,4,10,20,40,100,200 / masks for bits 0,...,7
 20311                              <1> 	
 20312                              <1> iget:
 20313                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20314                              <1> 	; 07/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 20315                              <1> 	;
 20316                              <1> 	; get a new i-node whose i-number in r1 and whose device is in cdev
 20317                              <1> 	;
 20318                              <1> 	; ('iget' returns current i-number in r1, if input value of r1 is 0)
 20319                              <1> 	; 
 20320                              <1> 	; INPUTS ->
 20321                              <1> 	;    ii - current i-number, rootdir
 20322                              <1> 	;    cdev - new i-node device
 20323                              <1> 	;    idev - current i-node device
 20324                              <1> 	;    imod - current i-node modified flag
 20325                              <1> 	;    mnti - cross device file i-number
 20326                              <1> 	;    r1 - i-numbe rof new i-node
 20327                              <1> 	;    mntd - mountable device number		
 20328                              <1> 	; 	 
 20329                              <1> 	; OUTPUTS ->
 20330                              <1> 	;    cdev, idev, imod, ii, r1
 20331                              <1> 	;
 20332                              <1> 	; ((AX = R1)) input/output
 20333                              <1> 	;
 20334                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 20335                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 20336                              <1> 
 20337 000056EC 8A15[3E740000]      <1> 	mov	dl, [cdev] ; 18/07/2013
 20338 000056F2 8A35[3C740000]      <1> 	mov	dh, [idev] ; 07/08/2013
 20339                              <1> 	;
 20340 000056F8 663B05[3A740000]    <1> 	cmp 	ax, [ii]
 20341                              <1> 		; cmp r1,ii / r1 = i-number of current file
 20342 000056FF 7504                <1> 	jne 	short iget_1
 20343                              <1> 		; bne 1f
 20344 00005701 38F2                <1> 	cmp	dl, dh
 20345                              <1> 		; cmp idev,cdev
 20346                              <1> 			  ; / is device number of i-node = current device
 20347 00005703 7476                <1>         je      short iget_5
 20348                              <1> 		; beq 2f
 20349                              <1> iget_1: ; 1:
 20350 00005705 30DB                <1> 	xor	bl, bl
 20351 00005707 381D[4C740000]      <1> 	cmp	[imod], bl ; 0	
 20352                              <1> 		; tstb imod / has i-node of current file
 20353                              <1> 			  ; / been modified i.e., imod set
 20354 0000570D 762D                <1> 	jna	short iget_2
 20355                              <1> 		; beq 1f
 20356 0000570F 881D[4C740000]      <1> 	mov	[imod], bl ; 0
 20357                              <1> 		;  clrb	imod / if it has, 
 20358                              <1> 			   ; / we must write the new i-node out on disk
 20359 00005715 6650                <1> 	push	ax
 20360                              <1> 		; mov r1,-(sp)
 20361                              <1> 	;mov	dl, [cdev]
 20362 00005717 6652                <1> 	push	dx
 20363                              <1> 		; mov cdev,-(sp)
 20364 00005719 66A1[3A740000]      <1> 	mov	ax, [ii]
 20365                              <1> 		; mov ii,r1
 20366                              <1> 	;mov	dh, [idev]
 20367 0000571F 8835[3E740000]      <1> 	mov	[cdev], dh
 20368                              <1> 		; mov idev,cdev
 20369 00005725 FEC3                <1> 	inc	bl ; 1
 20370                              <1> 	; 31/07/2013
 20371 00005727 881D[D4740000]      <1> 	mov     [rw], bl ; 1 == write 
 20372                              <1> 	;;28/07/2013 rw -> u.rw
 20373                              <1>         ;;mov   [u.rw], bl ; 1 == write
 20374 0000572D E84A000000          <1> 	call	icalc
 20375                              <1> 		; jsr r0,icalc; 1
 20376 00005732 665A                <1> 	pop	dx
 20377 00005734 8815[3E740000]      <1> 	mov	[cdev], dl
 20378                              <1> 		; mov (sp)+,cdev
 20379 0000573A 6658                <1> 	pop	ax
 20380                              <1> 		; mov (sp)+,r1
 20381                              <1> iget_2: ; 1:
 20382 0000573C 6621C0              <1> 	and	ax, ax
 20383                              <1> 		; tst r1 / is new i-number non zero
 20384 0000573F 7434                <1> 	jz	short iget_4 ; 2f
 20385                              <1> 		; beq 2f / branch if r1=0
 20386                              <1> 
 20387                              <1> 	; mov 	dl, [cdev]
 20388 00005741 08D2                <1> 	or	dl, dl
 20389                              <1> 		; tst cdev / is the current device number non zero
 20390                              <1> 			 ; / (i.e., device =/ drum)
 20391 00005743 7517                <1> 	jnz	short iget_3 ;  1f
 20392                              <1> 		; bne 1f / branch 1f cdev =/ 0  ;; (cdev != 0)
 20393 00005745 663B05[44740000]    <1> 	cmp	ax, [mnti]			
 20394                              <1> 		; cmp r1,mnti / mnti is the i-number of the cross device
 20395                              <1> 			    ; / file (root directory of mounted device)
 20396 0000574C 750E                <1> 	jne	short iget_3 ; 1f
 20397                              <1> 		; bne 1f
 20398                              <1>         ;mov    bl, [mntd]
 20399 0000574E FEC2                <1> 	inc	dl ; mov dl, 1 ; 17/07/2013
 20400 00005750 8815[3E740000]      <1>         mov	[cdev], dl ; 17/07/2013 - 09/07/2013
 20401                              <1> 		; mov mntd,cdev / make mounted device the current device
 20402 00005756 66A1[48740000]      <1> 	mov	ax, [rootdir]
 20403                              <1> 		; mov rootdir,r1
 20404                              <1> iget_3: ; 1:
 20405 0000575C 66A3[3A740000]      <1> 	mov	[ii], ax
 20406                              <1> 		; mov r1,ii
 20407 00005762 8815[3C740000]      <1> 	mov	[idev], dl ; cdev
 20408                              <1> 		; mov cdev,idev
 20409 00005768 30DB                <1> 	xor	bl, bl
 20410                              <1>         ; 31/07/2013
 20411 0000576A 881D[D4740000]      <1> 	mov     [rw], bl ; 0 == read 
 20412                              <1> 	;;28/07/2013 rw -> u.rw       
 20413                              <1>         ;;mov   [u.rw], bl ; 0 = read
 20414 00005770 E807000000          <1> 	call	icalc
 20415                              <1> 		; jsr r0,icalc; 0 / read in i-node ii
 20416                              <1> iget_4: ; 2:
 20417 00005775 66A1[3A740000]      <1> 	mov	ax, [ii]
 20418                              <1> 		; mov ii,r1
 20419                              <1> iget_5:
 20420 0000577B C3                  <1> 	retn
 20421                              <1> 		; rts r0
 20422                              <1> 
 20423                              <1> icalc:
 20424                              <1> 	; 02/07/2015
 20425                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20426                              <1> 	; 07/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 20427                              <1> 	;
 20428                              <1> 	; calculate physical block number from i-number then
 20429                              <1> 	; read or write that block
 20430                              <1> 	;
 20431                              <1> 	; 'icalc' is called from 'iget'
 20432                              <1> 	;
 20433                              <1> 	; for original unix v1:
 20434                              <1> 	; / i-node i is located in block (i+31.)/16. and begins 32.*
 20435                              <1>        	; / (i+31.) mod 16. bytes from its start
 20436                              <1> 	;
 20437                              <1> 	; for retro unix 8086 v1:
 20438                              <1> 	;  i-node is located in block (i+47)/16 and
 20439                              <1> 	;  begins 32*(i+47) mod 16 bytes from its start
 20440                              <1> 	;
 20441                              <1> 	; INPUTS ->
 20442                              <1> 	;    r1 - i-number of i-node
 20443                              <1> 	; 	 
 20444                              <1> 	; OUTPUTS ->
 20445                              <1> 	;    inode r/w
 20446                              <1> 	;
 20447                              <1> 	; ((AX = R1)) input
 20448                              <1> 	;
 20449                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 20450                              <1>         ;  ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))  
 20451                              <1> 	;
 20452 0000577C 0FB7D0              <1> 	movzx	edx, ax	
 20453 0000577F 6683C22F            <1> 	add	dx, 47
 20454 00005783 89D0                <1> 	mov	eax, edx
 20455                              <1> 	;add	ax, 47	; add 47 to inode number
 20456                              <1> 		;  add	$31.,r1 / add 31. to i-number
 20457 00005785 50                  <1> 	push	eax
 20458                              <1> 		; mov r1,-(sp) / save i+31. on stack
 20459 00005786 66C1E804            <1> 	shr 	ax, 4
 20460                              <1> 		; asr r1 / divide by 16.
 20461                              <1> 		; asr r1
 20462                              <1> 		; asr r1
 20463                              <1> 		; asr r1 / r1 contains block number of block
 20464                              <1> 		       ; / in which i-node exists
 20465 0000578A E82A0A0000          <1> 	call	dskrd
 20466                              <1> 		; jsr r0,dskrd / read in block containing i-node i.
 20467                              <1> 	; 31/07/2013
 20468 0000578F 803D[D4740000]00    <1>         cmp     byte [rw], 0 ; Retro Unix 8086 v1 feature !
 20469                              <1> 	;; 28/07/2013 rw -> u.rw
 20470                              <1>         ;;cmp     byte [u.rw], 0 ; Retro Unix 8086 v1 feature !
 20471                              <1> 		; tst (r0)
 20472 00005796 7605                <1> 	jna	short icalc_1
 20473                              <1> 		; beq 1f / branch to wslot when argument
 20474                              <1> 		       ; / in icalc call = 1
 20475                              <1> 	; eAX = r1  = block number
 20476 00005798 E87C0A0000          <1> 	call	wslot
 20477                              <1> 		; jsr r0,wslot / set up data buffer for write
 20478                              <1> 			     ; / (will be same buffer as dskrd got)
 20479                              <1> 	; eBX = r5 points to first word in data area for this block
 20480                              <1> icalc_1: ; 1:
 20481 0000579D 5A                  <1> 	pop	edx 
 20482 0000579E 83E20F              <1> 	and 	edx, 0Fh ; (i+47) mod 16
 20483                              <1> 		; bic $!17,(sp) / zero all but last 4 bits; 
 20484                              <1> 			      ; / gives (i+31.) mod 16
 20485 000057A1 C1E205              <1> 	shl 	edx, 5
 20486                              <1> 	; eDX = 32 * ((i+47) mod 16)
 20487 000057A4 89DE                <1> 	mov	esi, ebx  ; ebx points 1st word of the buffer
 20488 000057A6 01D6                <1> 	add	esi, edx  ; edx is inode offset in the buffer
 20489                              <1>           	; eSI (r5) points to first word in i-node i.	
 20490                              <1> 		; mov (sp)+,mq / calculate offset in data buffer; 
 20491                              <1> 			     ; / 32.*(i+31.)mod16
 20492                              <1> 		; mov $5,lsh / for i-node i.
 20493                              <1> 		; add mq,r5 / r5 points to first word in i-node i.
 20494 000057A8 BF[26710000]        <1> 	mov	edi, inode
 20495                              <1> 		; mov $inode,r1 / inode is address of first word 
 20496                              <1> 			      ; / of current i-node
 20497 000057AD B908000000          <1> 	mov 	ecx, 8 ; 02/07/2015(32 bit modification)
 20498                              <1> 		; mov $16.,r3
 20499                              <1>        ; 31/07/2013
 20500 000057B2 382D[D4740000]      <1>   	cmp     [rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 20501                              <1>        ;;28/07/2013 rw -> u.rw                 
 20502                              <1>        ;;cmp    [u.rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 20503                              <1> 		; tst (r0)+ / branch to 2f when argument in icalc call = 0
 20504 000057B8 760A                <1> 	jna	short icalc_3
 20505                              <1> 		; beq 2f / r0 now contains proper return address 
 20506                              <1> 		       ; / for rts r0
 20507                              <1> icalc_2: ; 1:
 20508 000057BA 87F7                <1> 	xchg 	esi, edi
 20509                              <1> 	; overwrite old i-node (in buffer to be written)
 20510 000057BC F3A5                <1> 	rep 	movsd
 20511                              <1> 		; mov (r1)+,(r5)+ / over write old i-node
 20512                              <1> 		; dec r3
 20513                              <1> 		; bgt 1b
 20514 000057BE E8720A0000          <1> 	call	dskwr
 20515                              <1> 		; jsr r0,dskwr / write inode out on device
 20516 000057C3 C3                  <1> 	retn
 20517                              <1> 		; rts r0
 20518                              <1> icalc_3: ; 2:
 20519                              <1> 	; copy new i-node into inode area of (core) memory
 20520 000057C4 F3A5                <1> 	rep 	movsd
 20521                              <1> 		; mov (r5)+,(r1)+ / read new i-node into 
 20522                              <1> 		                ; / "inode" area of core
 20523                              <1> 		; dec r3
 20524                              <1> 		; bgt 2b
 20525 000057C6 C3                  <1> 	retn
 20526                              <1> 		; rts r0
 20527                              <1> 
 20528                              <1> access:
 20529                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20530                              <1> 	; 24/04/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 20531                              <1> 	;
 20532                              <1> 	; check whether user is owner of file or user has read or write
 20533                              <1> 	; permission (based on i.flgs).
 20534                              <1> 	;
 20535                              <1> 	; INPUTS ->
 20536                              <1> 	;    r1 - i-number of file
 20537                              <1> 	;    u.uid
 20538                              <1> 	; arg0 -> (owner flag mask)	 		
 20539                              <1> 	;     Retro UNIX 8086 v1 feature -> owner flag mask in DL (DX) 	 
 20540                              <1> 	; OUTPUTS ->
 20541                              <1> 	;    inode (or jump to error)
 20542                              <1> 	;
 20543                              <1> 	; ((AX = R1)) input/output
 20544                              <1> 	;
 20545                              <1>         ;  ((Modified registers: eCX, eBX, eDX, eSI, eDI, eBP))  
 20546                              <1> 	;
 20547 000057C7 6652                <1> 	push	dx  ; save flags (DL)
 20548 000057C9 E81EFFFFFF          <1> 	call	iget
 20549                              <1> 		; jsr r0,iget / read in i-node for current directory
 20550                              <1> 			    ; / (i-number passed in r1)
 20551 000057CE 8A0D[26710000]      <1> 	mov	cl, [i.flgs]
 20552                              <1> 		; mov i.flgs,r2
 20553 000057D4 665A                <1> 	pop	dx  ; restore flags (DL)
 20554 000057D6 8A35[9E740000]      <1> 	mov	dh, [u.uid]
 20555 000057DC 3A35[29710000]      <1> 	cmp	dh, [i.uid]
 20556                              <1> 		; cmpb i.uid,u.uid / is user same as owner of file
 20557 000057E2 7503                <1> 	jne	short access_1
 20558                              <1> 		; bne 1f / no, then branch
 20559 000057E4 C0E902              <1> 	shr	cl, 2
 20560                              <1> 		; asrb r2 / shift owner read write bits into non owner
 20561                              <1> 		        ; / read/write bits
 20562                              <1> 		; asrb r2
 20563                              <1> access_1: ; 1:
 20564 000057E7 20D1                <1> 	and	cl, dl
 20565                              <1> 		; bit r2,(r0)+ / test read-write flags against argument
 20566                              <1> 			     ; / in access call
 20567 000057E9 7513                <1> 	jnz	short access_2
 20568                              <1> 		; bne 1f
 20569 000057EB 08F6                <1> 	or	dh, dh	; super user  (root) ?
 20570                              <1> 		; tstb u.uid
 20571 000057ED 740F                <1> 	jz	short access_2 ; yes, super user
 20572                              <1> 	;jnz	error
 20573                              <1> 		; beq 1f
 20574                              <1> 		; jmp error
 20575 000057EF C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS 
 20576 000057F7 0000                <1>
 20577                              <1> 			; 'permission denied !' error
 20578 000057F9 E94FE8FFFF          <1> 	jmp	error
 20579                              <1> 
 20580                              <1> access_2: ; 1:
 20581                              <1> 	; DL = flags
 20582 000057FE C3                  <1> 	retn
 20583                              <1> 		; rts r0
 20584                              <1> 
 20585                              <1> setimod:
 20586                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20587                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 20588                              <1> 	;
 20589                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
 20590                              <1> 	; the inode has been modified. Also puts the time of modification
 20591                              <1> 	; into the inode.
 20592                              <1> 	;
 20593                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
 20594                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
 20595                              <1> 	;
 20596                              <1> 	
 20597                              <1> 	; push 	edx
 20598 000057FF 50                  <1> 	push	eax
 20599                              <1> 
 20600 00005800 C605[4C740000]01    <1> 	mov 	byte [imod], 1
 20601                              <1> 		; movb $1,imod / set current i-node modified bytes
 20602                              <1> 	; Erdogan Tan 14-7-2012
 20603 00005807 E87CE3FFFF          <1> 	call 	epoch
 20604                              <1> 		 ; mov s.time,i.mtim 
 20605                              <1> 			    ; / put present time into file modified time
 20606                              <1> 		 ; mov s.time+2,i.mtim+2
 20607                              <1> 
 20608 0000580C A3[40710000]        <1> 	mov 	[i.mtim], eax
 20609                              <1> 	
 20610                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
 20611                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
 20612 00005811 833D[3C710000]00    <1> 	cmp	dword [i.ctim], 0
 20613 00005818 7505                <1> 	jnz	short setimod_ok
 20614                              <1> 
 20615 0000581A A3[3C710000]        <1> 	mov 	[i.ctim], eax
 20616                              <1> 
 20617                              <1> setimod_ok: ; 31/07/2013
 20618 0000581F 58                  <1> 	pop	eax
 20619                              <1> 	;pop	edx
 20620                              <1> 	
 20621 00005820 C3                  <1> 	retn
 20622                              <1> 		; rts r0
 20623                              <1> 
 20624                              <1> itrunc:
 20625                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20626                              <1> 	; 23/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 20627                              <1> 	;
 20628                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
 20629                              <1> 	;  to zero length.
 20630                              <1> 	;
 20631                              <1> 	; INPUTS ->
 20632                              <1> 	;    r1 - i-number of i-node
 20633                              <1> 	;    i.dskp - pointer to contents or indirect block in an i-node
 20634                              <1> 	;    i.flgs - large file flag		
 20635                              <1> 	;    i.size - size of file	
 20636                              <1> 	; 	 
 20637                              <1> 	; OUTPUTS ->
 20638                              <1> 	;    i.flgs - large file flag is cleared
 20639                              <1> 	;    i.size - set to 0	
 20640                              <1> 	;    i.dskp .. i.dskp+16 - entire list is cleared
 20641                              <1> 	;    setimod - set to indicate i-node has been modified
 20642                              <1> 	;    r1 - i-number of i-node  					
 20643                              <1> 	;
 20644                              <1> 	; ((AX = R1)) input/output
 20645                              <1> 	;
 20646                              <1> 	;  (Retro UNIX Prototype : 01/12/2012 - 10/03/2013, UNIXCOPY.ASM)
 20647                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 20648                              <1> 
 20649 00005821 E8C6FEFFFF          <1> 	call	iget
 20650                              <1> 		; jsr r0,iget
 20651 00005826 BE[2C710000]        <1> 	mov	esi, i.dskp
 20652                              <1> 		; mov $i.dskp,r2 / address of block pointers in r2
 20653 0000582B 31C0                <1> 	xor	eax, eax
 20654                              <1> itrunc_1: ; 1:
 20655 0000582D 66AD                <1> 	lodsw
 20656                              <1> 		; mov (r2)+,r1 / move physical block number into r1
 20657 0000582F 6609C0              <1> 	or 	ax, ax
 20658 00005832 743B                <1> 	jz	short itrunc_5
 20659                              <1> 		; beq 5f
 20660 00005834 56                  <1> 	push	esi
 20661                              <1> 		; mov r2,-(sp)
 20662 00005835 66F705[26710000]00- <1> 	test    word [i.flgs], 1000h    
 20663 0000583D 10                  <1>
 20664                              <1> 		; bit $10000,i.flgs / test large file bit?
 20665 0000583E 7429                <1> 	jz	short itrunc_4
 20666                              <1> 		; beq 4f / if clear, branch
 20667 00005840 50                  <1> 	push	eax
 20668                              <1> 		; mov r1,-(sp) / save block number of indirect block
 20669 00005841 E873090000          <1> 	call	dskrd
 20670                              <1> 		; jsr r0,dskrd / read in block, 1st data word 
 20671                              <1> 			     ; / pointed to by r5
 20672                              <1> 	; eBX = r5 = Buffer data address (the 1st word)
 20673 00005846 B900010000          <1> 	mov	ecx, 256
 20674                              <1> 		; mov $256.,r3 / move word count into r3
 20675 0000584B 89DE                <1> 	mov	esi, ebx
 20676                              <1> itrunc_2: ; 2:
 20677 0000584D 66AD                <1> 	lodsw
 20678                              <1> 		; mov (r5)+,r1 / put 1st data word in r1; 
 20679                              <1> 			     ; / physical block number
 20680 0000584F 6621C0              <1> 	and	ax, ax
 20681 00005852 7409                <1> 	jz	short itrunc_3
 20682                              <1> 		; beq 3f / branch if zero
 20683                              <1> 	;push	ecx
 20684 00005854 6651                <1> 	push	cx
 20685                              <1> 		; mov r3,-(sp) / save r3, r5 on stack
 20686                              <1> 	;push	esi
 20687                              <1> 		; mov r5,-(sp)
 20688 00005856 E842FEFFFF          <1> 	call	free
 20689                              <1> 		; jsr r0,free / free block in free storage map
 20690                              <1> 	;pop	esi
 20691                              <1> 		; mov(sp)+,r5
 20692 0000585B 6659                <1> 	pop	cx
 20693                              <1> 	;pop	ecx
 20694                              <1> 		; mov (sp)+,r3
 20695                              <1> itrunc_3: ; 3:
 20696 0000585D E2EE                <1> 	loop	itrunc_2
 20697                              <1> 		; dec r3 / decrement word count
 20698                              <1> 		; bgt 2b / branch if positive
 20699 0000585F 58                  <1> 	pop	eax
 20700                              <1> 		; mov (sp)+,r1 / put physical block number of 
 20701                              <1> 			     ; / indirect block
 20702                              <1> 	; 01/08/2013
 20703 00005860 668125[26710000]FF- <1>         and     word [i.flgs], 0EFFFh ; 1110111111111111b
 20704 00005868 EF                  <1>
 20705                              <1> itrunc_4: ; 4:
 20706 00005869 E82FFEFFFF          <1> 	call	free
 20707                              <1> 		; jsr r0,free / free indirect block
 20708 0000586E 5E                  <1> 	pop	esi
 20709                              <1> 		; mov (sp)+,r2
 20710                              <1> itrunc_5: ; 5:
 20711 0000586F 81FE[3C710000]      <1> 	cmp	esi, i.dskp+16
 20712                              <1> 		; cmp r2,$i.dskp+16.
 20713 00005875 72B6                <1> 	jb	short itrunc_1	
 20714                              <1> 		; bne 1b / branch until all i.dskp entries check
 20715                              <1> 	; 01/08/2013
 20716                              <1> 	;and     word [i.flgs], 0EFFFh ; 1110111111111111b
 20717                              <1> 		; bic $10000,i.flgs / clear large file bit
 20718 00005877 BF[2C710000]        <1> 	mov	edi, i.dskp
 20719 0000587C 66B90800            <1> 	mov	cx, 8
 20720 00005880 6631C0              <1> 	xor 	ax, ax
 20721 00005883 66A3[2A710000]      <1> 	mov	[i.size], ax ; 0
 20722                              <1> 		; clr i.size / zero file size
 20723 00005889 F366AB              <1> 	rep	stosw
 20724                              <1> 		; jsr r0,copyz; i.dskp; i.dskp+16. 
 20725                              <1> 			   ; / zero block pointers
 20726 0000588C E86EFFFFFF          <1> 	call	setimod
 20727                              <1> 		; jsr r0,setimod / set i-node modified flag
 20728 00005891 66A1[3A740000]      <1> 	mov	ax, [ii]
 20729                              <1> 		; mov ii,r1
 20730 00005897 C3                  <1> 	retn
 20731                              <1> 		; rts r0
 20732                              <1> 
 20733                              <1> imap:
 20734                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 20735                              <1> 	; 26/04/2013 (Retro UNIX 8086 v1)
 20736                              <1> 	;
 20737                              <1> 	; 'imap' finds the byte in core (superblock) containing
 20738                              <1> 	; allocation bit for an i-node whose number in r1.
 20739                              <1> 	;
 20740                              <1> 	; INPUTS ->
 20741                              <1> 	;    r1 - contains an i-number
 20742                              <1> 	;    fsp - start of table containing open files
 20743                              <1> 	;
 20744                              <1> 	; OUTPUTS ->
 20745                              <1> 	;    r2 - byte address of byte with the allocation bit
 20746                              <1> 	;    mq - a mask to locate the bit position.	
 20747                              <1> 	;	  (a 1 is in calculated bit posisiton)
 20748                              <1> 	;
 20749                              <1> 	; ((AX = R1)) input/output
 20750                              <1> 	; ((DL/DX = MQ)) output
 20751                              <1> 	; ((BX = R2)) output
 20752                              <1> 	;
 20753                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 20754                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI))  
 20755                              <1> 	;
 20756                              <1> 		; / get the byte that has the allocation bit for 
 20757                              <1> 		; / the i-number contained in r1
 20758                              <1> 	;mov	dx, 1
 20759 00005898 B201                <1> 	mov	dl, 1
 20760                              <1> 		; mov $1,mq / put 1 in the mq
 20761 0000589A 0FB7D8              <1> 	movzx	ebx, ax
 20762                              <1> 		; mov r1,r2 / r2 now has i-number whose byte
 20763                              <1>  		          ; / in the map we must find
 20764 0000589D 6683EB29            <1> 	sub	bx, 41
 20765                              <1> 		; sub $41.,r2 / r2 has i-41
 20766 000058A1 88D9                <1> 	mov	cl, bl
 20767                              <1> 		; mov r2,r3 / r3 has i-41
 20768 000058A3 80E107              <1> 	and	cl, 7
 20769                              <1> 		; bic $!7,r3 / r3 has (i-41) mod 8 to get 
 20770                              <1> 			   ; / the bit position
 20771 000058A6 7402                <1> 	jz	short imap1
 20772                              <1> 	;shl	dx, cl
 20773 000058A8 D2E2                <1> 	shl	dl, cl
 20774                              <1> 		; mov r3,lsh / move the 1 over (i-41) mod 8 positions
 20775                              <1> imap1:			   ; / to the left to mask the correct bit
 20776 000058AA 66C1EB03            <1> 	shr	bx, 3
 20777                              <1> 		; asr r2
 20778                              <1> 		; asr r2
 20779                              <1> 		; asr r2 / r2 has (i-41) base 8 of the byte number
 20780                              <1> 		       ; / from the start of the map
 20781                              <1> 		; mov r2,-(sp) / put (i-41) base 8 on the stack
 20782 000058AE BE[10810000]        <1> 	mov	esi, systm
 20783                              <1> 		; mov $systm,r2 / r2 points to the in-core image of
 20784                              <1> 				; / the super block for drum
 20785                              <1> 	;cmp	word [cdev], 0
 20786 000058B3 803D[3E740000]00    <1> 	cmp	byte [cdev], 0
 20787                              <1> 		; tst cdev / is the device the disk
 20788 000058BA 7606                <1> 	jna	short imap2
 20789                              <1> 		; beq 1f / yes
 20790 000058BC 81C608020000        <1> 	add	esi, mount - systm
 20791                              <1> 		; add $mount-systm,r2 / for mounted device,
 20792                              <1> 			; / r2 points to 1st word of its super block
 20793                              <1> imap2: ; 1:
 20794 000058C2 66031E              <1> 	add	bx, [esi] ;; add free map size to si
 20795                              <1> 		; add (r2)+,(sp) / get byte address of allocation bit
 20796 000058C5 6683C304            <1> 	add	bx, 4
 20797 000058C9 01F3                <1> 	add	ebx, esi
 20798                              <1>         	; add (sp)+,r2 / ?
 20799                              <1> 	;add	ebx, 4 ;; inode map offset in superblock
 20800                              <1> 		      ;; (2 + free map size + 2)
 20801                              <1> 		; add $2,r2 / ?
 20802                              <1>  	; DL/DX (MQ) has a 1 in the calculated bit position
 20803                              <1>         ; BX (R2) has byte address of the byte with allocation bit
 20804 000058CB C3                  <1> 	retn
 20805                              <1> 		; rts r0
 20806                                  %include 'u6.s'        ; 31/05/2015
 20807                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS6.INC
 20808                              <1> ; Last Modification: 18/11/2015
 20809                              <1> ; ----------------------------------------------------------------------------
 20810                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 20811                              <1> ; (v0.1 - Beginning: 11/07/2012)
 20812                              <1> ;
 20813                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 20814                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 20815                              <1> ; <Bell Laboratories (17/3/1972)>
 20816                              <1> ; <Preliminary Release of UNIX Implementation Document>
 20817                              <1> ;
 20818                              <1> ; Retro UNIX 8086 v1 - U6.ASM (23/07/2014) //// UNIX v1 -> u6.s
 20819                              <1> ;
 20820                              <1> ; ****************************************************************************
 20821                              <1> 
 20822                              <1> readi:
 20823                              <1> 	; 20/05/2015
 20824                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 20825                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 20826                              <1> 	;
 20827                              <1> 	; Reads from an inode whose number in R1
 20828                              <1> 	; 
 20829                              <1> 	; INPUTS ->
 20830                              <1> 	;    r1 - inode number
 20831                              <1> 	;    u.count - byte count user desires
 20832                              <1> 	;    u.base - points to user buffer
 20833                              <1> 	;    u.fofp - points to word with current file offset
 20834                              <1> 	; OUTPUTS ->
 20835                              <1> 	;    u.count - cleared
 20836                              <1> 	;    u.nread - accumulates total bytes passed back
 20837                              <1> 	;
 20838                              <1> 	; ((AX = R1)) input/output
 20839                              <1> 	;    (Retro UNIX Prototype : 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
 20840                              <1>         ;    ((Modified registers: edx, ebx, ecx, esi, esi, ebp))  
 20841                              <1> 
 20842 000058CC 31D2                <1> 	xor	edx, edx ; 0
 20843 000058CE 8915[80740000]      <1> 	mov 	[u.nread], edx ; 0
 20844                              <1> 		 ; clr u.nread / accumulates number of bytes transmitted
 20845 000058D4 668915[B7740000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
 20846 000058DB 3915[7C740000]      <1> 	cmp 	[u.count], edx ; 0
 20847                              <1> 	         ; tst u.count / is number of bytes to be read greater than 0
 20848 000058E1 7701                <1> 	ja 	short readi_1 ; 1f
 20849                              <1> 		 ; bgt 1f / yes, branch
 20850 000058E3 C3                  <1> 	retn
 20851                              <1> 		 ; rts r0 / no, nothing to read; return to caller
 20852                              <1> readi_1: ; 1:
 20853                              <1> 	         ; mov r1,-(sp) / save i-number on stack
 20854 000058E4 6683F828            <1> 	cmp	ax, 40
 20855                              <1> 		 ; cmp r1,$40. / want to read a special file 
 20856                              <1> 		 ;             / (i-nodes 1,...,40 are for special files)
 20857 000058E8 0F87D3000000        <1>         ja      dskr 
 20858                              <1> 		 ; ble 1f / yes, branch
 20859                              <1> 		 ; jmp dskr / no, jmp to dskr; 
 20860                              <1> 		 ;         / read file with i-node number (r1)
 20861                              <1> 		 ;    / starting at byte ((u.fofp)), read in u.count bytes
 20862                              <1> 	; (20/05/2015)
 20863 000058EE 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 20864                              <1> 	; 1:
 20865 000058EF 0FB6D8              <1> 	movzx	ebx, al
 20866 000058F2 66C1E302            <1> 	shl	bx, 2
 20867                              <1> 		 ; asl r1 / multiply inode number by 2
 20868 000058F6 81C3[FA580000]      <1> 	add	ebx, readi_2 - 4
 20869 000058FC FF23                <1> 	jmp	dword [ebx]	
 20870                              <1> 		 ; jmp *1f-2(r1)
 20871                              <1> readi_2: ; 1:
 20872 000058FE [4A590000]          <1> 	dd	rtty ; tty, AX = 1 (runix)
 20873                              <1> 		 ;rtty / tty; r1=2
 20874                              <1> 		 ;rppt / ppt; r1=4
 20875 00005902 [9D590000]          <1> 	dd	rmem ; mem, AX = 2 (runix)
 20876                              <1> 		 ;rmem / mem; r1=6
 20877                              <1> 		 ;rrf0 / rf0
 20878                              <1> 		 ;rrk0 / rk0
 20879                              <1> 		 ;rtap / tap0
 20880                              <1> 		 ;rtap / tap1
 20881                              <1> 		 ;rtap / tap2
 20882                              <1> 		 ;rtap / tap3
 20883                              <1> 		 ;rtap / tap4
 20884                              <1> 		 ;rtap / tap5
 20885                              <1> 		 ;rtap / tap6
 20886                              <1> 		 ;rtap / tap7
 20887 00005906 [5F600000]          <1> 	dd	rfd ; fd0, AX = 3 (runix only)
 20888 0000590A [5F600000]          <1> 	dd	rfd ; fd1, AX = 4 (runix only)
 20889 0000590E [5F600000]          <1> 	dd	rhd ; hd0, AX = 5 (runix only)
 20890 00005912 [5F600000]          <1> 	dd	rhd ; hd1, AX = 6 (runix only)	
 20891 00005916 [5F600000]          <1> 	dd	rhd ; hd2, AX = 7 (runix only)
 20892 0000591A [5F600000]          <1> 	dd	rhd ; hd3, AX = 8 (runix only)	
 20893 0000591E [B2590000]          <1> 	dd	rlpr ; lpr, AX = 9 (invalid, write only device !?)
 20894 00005922 [99590000]          <1> 	dd	rcvt ; tty0, AX = 10 (runix)	  
 20895                              <1> 		 ;rcvt / tty0
 20896 00005926 [99590000]          <1> 	dd	rcvt ; tty1, AX = 11 (runix)	  
 20897                              <1> 		 ;rcvt / tty1
 20898 0000592A [99590000]          <1> 	dd	rcvt ; tty2, AX = 12 (runix)	  
 20899                              <1> 		 ;rcvt / tty2
 20900 0000592E [99590000]          <1> 	dd	rcvt ; tty3, AX = 13 (runix)	  
 20901                              <1> 		 ;rcvt / tty3
 20902 00005932 [99590000]          <1> 	dd	rcvt ; tty4, AX = 14 (runix)	  
 20903                              <1> 		 ;rcvt / tty4
 20904 00005936 [99590000]          <1> 	dd	rcvt ; tty5, AX = 15 (runix)	  
 20905                              <1> 		 ;rcvt / tty5
 20906 0000593A [99590000]          <1> 	dd	rcvt ; tty6, AX = 16 (runix)	  
 20907                              <1> 		 ;rcvt / tty6
 20908 0000593E [99590000]          <1> 	dd	rcvt ; tty7, AX = 17 (runix)	  
 20909                              <1> 		 ;rcvt / tty7
 20910 00005942 [99590000]          <1> 	dd	rcvt ; COM1, AX = 18 (runix only)	  
 20911                              <1> 		 ;rcrd / crd
 20912 00005946 [99590000]          <1> 	dd	rcvt ; COM2, AX = 19 (runix only)
 20913                              <1> 
 20914                              <1> rtty: ; / read from console tty
 20915                              <1> 	; 17/10/2015 - 16/07/2015 (Retro UNIX 8086 v1)
 20916                              <1> 	; 	     (Only 1 byte is read, by ignoring byte count!)
 20917                              <1> 	;  	     WHAT FOR: Every character from Keyboard input 
 20918                              <1> 	;	     must be written immediate on video page (screen)
 20919                              <1> 	;	     when it is required.	
 20920                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 20921                              <1> 	; 11/03/2013 - 19/06/2014 (Retro UNIX 8086 v1)
 20922                              <1> 	;
 20923                              <1> 	; Console tty buffer is PC keyboard buffer
 20924                              <1> 	; and keyboard-keystroke handling is different than original
 20925                              <1> 	; unix (PDP-11) here. TTY/Keyboard procedures here are changed
 20926                              <1> 	; according to IBM PC compatible ROM BIOS keyboard functions. 
 20927                              <1> 	;
 20928                              <1> 	; 06/12/2013
 20929 0000594A 0FB61D[A1740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 20930 00005951 8A83[A5710000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 20931                              <1> rttys:
 20932                              <1> 		; mov tty+[8*ntty]-8+6,r5 / r5 is the address of the 4th word of
 20933                              <1> 	               ; / of the control and status block
 20934                              <1> 		; tst 2(r5) / for the console tty; this word points to the console
 20935                              <1> 		       ; / tty buffer
 20936                              <1> 	; 28/07/2013
 20937 00005957 A2[A6740000]        <1> 	mov 	[u.ttyn], al
 20938                              <1> 	; 13/01/2014
 20939 0000595C FEC0                <1> 	inc	al
 20940 0000595E A2[88740000]        <1> 	mov	[u.ttyp], al ; tty number + 1
 20941                              <1> rtty_nc: ; 01/02/2014
 20942                              <1> 	; 29/09/2013
 20943 00005963 B90A000000          <1> 	mov	ecx, 10
 20944                              <1> rtty_1: 	; 01/02/2014
 20945 00005968 6651                <1> 	push 	cx ; 29/09/2013
 20946                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
 20947 0000596A B001                <1> 	mov 	al, 1
 20948 0000596C E8330B0000          <1> 	call 	getc
 20949 00005971 6659                <1> 	pop 	cx ; 29/09/2013	
 20950 00005973 7516                <1> 	jnz	short rtty_2
 20951                              <1> 		; bne 1f / 2nd word of console tty buffer contains number
 20952                              <1> 	               ; / of chars. Is this number non-zero?
 20953 00005975 E20D                <1> 	loop	rtty_idle ; 01/02/2014
 20954                              <1> 	; 05/10/2013
 20955 00005977 8A25[A6740000]      <1> 	mov	ah, [u.ttyn]
 20956                              <1> 	; 29/09/2013
 20957 0000597D E871FBFFFF          <1> 	call	sleep
 20958                              <1> 		; jsr r0,canon; ttych / if 0, call 'canon' to get a line
 20959                              <1>                 ;           / (120 chars.)
 20960                              <1> 	;byte [u.ttyn] = tty number (0 to 9) 
 20961 00005982 EBDF                <1> 	jmp	short rtty_nc ; 01/02/2014
 20962                              <1> 
 20963                              <1> rtty_idle:
 20964                              <1> 	; 29/07/2013
 20965 00005984 E8D6FAFFFF          <1> 	call 	idle
 20966 00005989 EBDD                <1> 	jmp	short rtty_1 ; 01/02/2014
 20967                              <1> 	;1:
 20968                              <1> 		; tst 2(r5) / is the number of characters zero
 20969                              <1> 		; beq ret1 / yes, return to caller via 'ret1'
 20970                              <1> 		; movb *4(r5),r1 / no, put character in r1
 20971                              <1> 		; inc 4(r5) / 3rd word of console tty buffer points to byte which
 20972                              <1> 		          ; / contains the next char.
 20973                              <1> 		; dec 2(r5) / decrement the character count
 20974                              <1> rtty_2:
 20975 0000598B 30C0                <1> 	xor 	al, al
 20976 0000598D E8120B0000          <1> 	call 	getc
 20977 00005992 E892000000          <1> 	call	passc
 20978                              <1> 		; jsr r0,passc / move the character to core (user)
 20979                              <1> 	;; 17/10/2015 - 16/07/2015
 20980                              <1> 	; 19/06/2014
 20981                              <1> 	;;jnz	short rtty_nc
 20982 00005997 58                  <1> 	pop	eax  ; (20/05/2015)
 20983 00005998 C3                  <1> 	retn 
 20984                              <1> ;ret1:
 20985                              <1> 		; jmp ret / return to caller via 'ret'
 20986                              <1> 
 20987                              <1> rcvt:   ; < receive/read character from tty >
 20988                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 20989                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 20990                              <1> 	;
 20991                              <1> 	; Retro UNIX 8086 v1 modification !
 20992                              <1> 	; 
 20993                              <1> 	; In original UNIX v1, 'rcvt' routine 
 20994                              <1> 	;		(exactly different than this one)
 20995                              <1> 	;	was in 'u9.s' file.
 20996                              <1> 	;
 20997 00005999 2C0A                <1> 	sub 	al, 10
 20998                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 20999                              <1> 	; 16/07/2013
 21000                              <1> 	; 21/05/2013
 21001 0000599B EBBA                <1>         jmp     short rttys
 21002                              <1>       
 21003                              <1> ;rppt: / read paper tape
 21004                              <1> ;	jsr	r0,pptic / gets next character in clist for ppt input and
 21005                              <1> ;			 / places
 21006                              <1> ;		br ret / it in r1; if there 1s no problem with reader, it
 21007                              <1> ;		       / also enables read bit in prs
 21008                              <1> ;	jsr	r0,passc / place character in users buffer area
 21009                              <1> ;	br	rppt
 21010                              <1> 
 21011                              <1> rmem: ; / transfer characters from memory to a user area of core
 21012                              <1> 	; 17/10/2015
 21013                              <1> 	; 11/06/2015
 21014                              <1> 	; 24/05/2015
 21015                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21016                              <1> 	;
 21017 0000599D 8B35[68740000]      <1> 	mov     esi, [u.fofp]
 21018                              <1> rmem_1:
 21019 000059A3 8B1E                <1>         mov     ebx, [esi]        
 21020                              <1> 	        ; mov *u.fofp,r1 / save file offset which points to the char
 21021                              <1> 		               ; / to be transferred to user
 21022 000059A5 FF06                <1>         inc     dword [esi] ; 17/10/2015
 21023                              <1> 		; inc *u.fofp / increment file offset to point to 'next' 
 21024                              <1> 			    ; / char in memory file
 21025 000059A7 8A03                <1> 	mov	al, [ebx]
 21026                              <1> 		; movb (r1),r1 / get character from memory file, 
 21027                              <1> 		             ; / put it in r1
 21028 000059A9 E87B000000          <1> 	call	passc        ; jsr r0,passc / move this character to 
 21029                              <1> 			     ;  / the next byte of the users core area
 21030                              <1> 		; br rmem / continue
 21031 000059AE 75F3                <1> 	jnz	short rmem_1
 21032                              <1> ret_:
 21033 000059B0 58                  <1> 	pop	eax ; 09/06/2015
 21034 000059B1 C3                  <1> 	retn
 21035                              <1> 
 21036                              <1> rlpr:
 21037                              <1> ;1:
 21038                              <1> ;rcrd:
 21039 000059B2 C705[A7740000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 21040 000059BA 0000                <1>
 21041 000059BC E98CE6FFFF          <1> 	jmp	error
 21042                              <1> 		;jmp	error / see 'error' routine
 21043                              <1> 
 21044                              <1> dskr:
 21045                              <1> 	; 12/10/2015
 21046                              <1> 	; 21/08/2015
 21047                              <1> 	; 25/07/2015
 21048                              <1> 	; 10/07/2015
 21049                              <1> 	; 16/06/2015
 21050                              <1> 	; 31/05/2015
 21051                              <1> 	; 24/05/2015 (Retro UNIX 386 v1 - Beginning)
 21052                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 21053                              <1> dskr_0:
 21054 000059C1 50                  <1> 	push	eax
 21055                              <1> 		; mov (sp),r1 / i-number in r1
 21056                              <1> 	; AX = i-number
 21057 000059C2 E825FDFFFF          <1> 	call	iget
 21058                              <1> 		; jsr r0,iget / get i-node (r1) into i-node section of core
 21059 000059C7 0FB715[2A710000]    <1>         movzx   edx, word [i.size] ; 16/06/2015
 21060                              <1> 		; mov i.size,r2 / file size in bytes in r2
 21061 000059CE 8B1D[68740000]      <1> 	mov	ebx, [u.fofp]
 21062 000059D4 2B13                <1> 	sub	edx, [ebx]
 21063                              <1> 		; sub *u.fofp,r2 / subtract file offset
 21064                              <1>         ; 12/10/2015
 21065                              <1> 	; jna     short ret_ 
 21066                              <1> 		; blos ret
 21067 000059D6 7709                <1> 	ja	short dskr_1
 21068                              <1> 	;
 21069                              <1> dskr_retn: ; 12/10/2015
 21070 000059D8 58                  <1> 	pop	eax
 21071 000059D9 C605[B9740000]00    <1> 	mov	byte [u.kcall], 0
 21072 000059E0 C3                  <1> 	retn	
 21073                              <1> dskr_1: 
 21074 000059E1 3B15[7C740000]      <1> 	cmp     edx, [u.count] 
 21075                              <1> 		; cmp r2,u.count / are enough bytes left in file 
 21076                              <1> 			       ; / to carry out read
 21077 000059E7 7306                <1> 	jnb	short dskr_2
 21078                              <1> 		; bhis 1f
 21079 000059E9 8915[7C740000]      <1> 	mov	[u.count], edx
 21080                              <1> 		; mov r2,u.count / no, just read to end of file
 21081                              <1> dskr_2: ; 1:
 21082                              <1> 	; AX = i-number
 21083 000059EF E885FBFFFF          <1> 	call	mget
 21084                              <1> 		; jsr r0,mget / returns physical block number of block 
 21085                              <1> 			    ; / in file where offset points
 21086                              <1> 	; eAX = physical block number
 21087 000059F4 E8C0070000          <1> 	call	dskrd
 21088                              <1> 		; jsr r0,dskrd / read in block, r5 points to 
 21089                              <1> 			     ; / 1st word of data in buffer
 21090                              <1> 	; 09/06/2015
 21091 000059F9 803D[B9740000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
 21092 00005A00 770F                <1> 	ja	short dskr_4	  ; zf=0 -> the caller is 'namei'
 21093 00005A02 66833D[B7740000]00  <1> 	cmp	word [u.pcount], 0
 21094 00005A0A 7705                <1> 	ja	short dskr_4
 21095                              <1> dskr_3:
 21096                              <1> 	; [u.base] = virtual address to transfer (as destination address)
 21097 00005A0C E853000000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 21098                              <1> dskr_4:
 21099                              <1> 	; eBX (r5) = system (I/O) buffer address -physical-
 21100 00005A11 E8C7020000          <1> 	call	sioreg
 21101                              <1> 		; jsr r0,sioreg
 21102 00005A16 87F7                <1> 	xchg	esi, edi
 21103                              <1> 	; eDI = file (user data) offset
 21104                              <1> 	; eSI = sector (I/O) buffer offset
 21105                              <1> 	; eCX = byte count
 21106 00005A18 F3A4                <1> 	rep	movsb
 21107                              <1> 		; movb (r2)+,(r1)+ / move data from buffer into working core
 21108                              <1> 		                 ; / starting at u.base
 21109                              <1> 		; dec r3
 21110                              <1> 		; bne 2b / branch until proper number of bytes are transferred
 21111                              <1> 	; 25/07/2015
 21112                              <1> 	; eax = remain bytes in buffer
 21113                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 21114 00005A1A 09C0                <1> 	or	eax, eax
 21115 00005A1C 75EE                <1> 	jnz	short dskr_3 ; (page end before system buffer end!)		
 21116                              <1> 	; 03/08/2013
 21117                              <1> 	;pop	eax
 21118 00005A1E 390D[7C740000]      <1> 	cmp	[u.count], ecx ; 0
 21119                              <1> 		; tst u.count / all bytes read off disk
 21120                              <1> 		; bne dskr
 21121                              <1> 		; br ret
 21122                              <1>         ;ja      short dskr_0
 21123                              <1> 	;mov	[u.kcall], cl ; 0 ; 09/06/2015
 21124                              <1> 	;retn
 21125                              <1> 	; 12/10/2015
 21126 00005A24 76B2                <1> 	jna	short dskr_retn
 21127 00005A26 58                  <1> 	pop	eax  ; (i-node number)
 21128 00005A27 EB98                <1> 	jmp	short dskr_0
 21129                              <1> 	
 21130                              <1> passc:
 21131                              <1> 	; 18/10/2015
 21132                              <1> 	; 10/07/2015
 21133                              <1> 	; 01/07/2015
 21134                              <1> 	; 08/06/2015
 21135                              <1> 	; 04/06/2015
 21136                              <1> 	; 20/05/2015
 21137                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21138                              <1> 	;
 21139                              <1>    	;(Retro UNIX 386 v1 - translation from user's virtual address
 21140                              <1> 	;		      to physical address
 21141 00005A29 66833D[B7740000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 21142                              <1> 			     ; 1-4095 --> use previous physical base address
 21143                              <1> 			     ; in [u.pbase]
 21144 00005A31 7705                <1> 	ja	short passc_3
 21145                              <1> 	; 08/06/2015 - 10/07/2015
 21146 00005A33 E82C000000          <1> 	call	trans_addr_w
 21147                              <1> passc_3:
 21148                              <1> 	; 19/05/2015
 21149 00005A38 66FF0D[B7740000]    <1> 	dec	word [u.pcount]
 21150                              <1> 	;
 21151 00005A3F 8B1D[B3740000]      <1> 	mov	ebx, [u.pbase]
 21152 00005A45 8803                <1> 	mov	[ebx], al
 21153                              <1> 		; movb r1,*u.base / move a character to the next byte of the
 21154                              <1> 		               ; / users buffer
 21155 00005A47 FF05[78740000]      <1> 	inc	dword [u.base]
 21156                              <1> 		; inc u.base / increment the pointer to point to 
 21157                              <1> 			  ; / the next byte in users buffer
 21158 00005A4D FF05[B3740000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 21159 00005A53 FF05[80740000]      <1> 	inc	dword [u.nread]
 21160                              <1> 		; inc u.nread / increment the number of bytes read
 21161 00005A59 FF0D[7C740000]      <1> 	dec	dword [u.count]
 21162                              <1> 		; dec u.count / decrement the number of bytes to be read
 21163                              <1> 		; bne 1f / any more bytes to read?; yes, branch
 21164 00005A5F C3                  <1> 	retn
 21165                              <1> 		; mov (sp)+,r0 / no, do a non-local return to the caller of
 21166                              <1> 		             ; / 'readi' by:
 21167                              <1> 		;/ (1) pop the return address off the stack into r0
 21168                              <1> 		; mov (sp)+,r1 / (2) pop the i-number off the stack into r1
 21169                              <1> 	;1:
 21170                              <1> 		; clr	*$ps / clear processor status
 21171                              <1> 		; rts r0 / return to address currently on top of stack
 21172                              <1> 
 21173                              <1> trans_addr_r:
 21174                              <1> 	; Translate virtual address to physical address 
 21175                              <1> 	; for reading from user's memory space
 21176                              <1> 	; (Retro UNIX 386 v1 feature only !)
 21177                              <1> 	; 18/10/2015
 21178                              <1> 	; 10/07/2015
 21179                              <1> 	; 09/06/2015
 21180                              <1> 	; 08/06/2015 
 21181                              <1> 	; 04/06/2015
 21182                              <1> 	;
 21183                              <1> 	; 18/10/2015
 21184 00005A60 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
 21185 00005A62 EB04                <1> 	jmp 	short trans_addr_rw
 21186                              <1> 
 21187                              <1> 	;push	eax
 21188                              <1> 	;push	ebx
 21189                              <1> 	;mov	ebx, [u.base]
 21190                              <1> 	;call	get_physical_addr ; get physical address
 21191                              <1> 	;;jnc	short cpass_0
 21192                              <1> 	;jnc	short passc_1
 21193                              <1> 	;mov	[u.error], eax
 21194                              <1> 	;;pop	ebx
 21195                              <1> 	;;pop	eax
 21196                              <1> 	;jmp	error
 21197                              <1> ;cpass_0:
 21198                              <1> 	; 18/10/2015
 21199                              <1> 	; 20/05/2015
 21200                              <1> 	;mov 	[u.pbase], eax ; physical address	
 21201                              <1> 	;mov	[u.pcount], cx ; remain byte count in page (1-4096)
 21202                              <1> 	;pop	ebx
 21203                              <1> 	;pop	eax
 21204                              <1> 	;retn	; 08/06/2015
 21205                              <1> 
 21206                              <1> trans_addr_w:
 21207                              <1> 	; Translate virtual address to physical address 
 21208                              <1> 	; for writing to user's memory space
 21209                              <1> 	; (Retro UNIX 386 v1 feature only !)
 21210                              <1> 	; 18/10/2015
 21211                              <1> 	; 29/07/2015
 21212                              <1> 	; 10/07/2015
 21213                              <1> 	; 09/06/2015
 21214                              <1> 	; 08/06/2015
 21215                              <1> 	; 04/06/2015 (passc)
 21216                              <1> 	;
 21217                              <1> 	; 18/10/2015
 21218 00005A64 29D2                <1> 	sub	edx, edx
 21219 00005A66 FEC2                <1> 	inc	dl ; 1 (write access sign)
 21220                              <1> trans_addr_rw:
 21221 00005A68 50                  <1> 	push	eax
 21222 00005A69 53                  <1> 	push	ebx
 21223                              <1> 	; 18/10/2015
 21224 00005A6A 52                  <1> 	push 	edx ; r/w sign (in DL)
 21225                              <1> 	;
 21226 00005A6B 8B1D[78740000]      <1> 	mov	ebx, [u.base]
 21227 00005A71 E812DCFFFF          <1> 	call	get_physical_addr ; get physical address
 21228 00005A76 730A                <1> 	jnc	short passc_0
 21229 00005A78 A3[A7740000]        <1> 	mov	[u.error], eax
 21230                              <1> 	;pop	edx
 21231                              <1> 	;pop 	ebx
 21232                              <1> 	;pop	eax
 21233 00005A7D E9CBE5FFFF          <1> 	jmp	error
 21234                              <1> passc_0:
 21235 00005A82 F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page ; 18/10/2015
 21236 00005A85 5A                  <1> 	pop	edx ; 18/10/2015
 21237 00005A86 751C                <1> 	jnz	short passc_1
 21238                              <1> 	; 18/10/2015
 21239 00005A88 20D2                <1> 	and 	dl, dl
 21240 00005A8A 7418                <1> 	jz	short passc_1
 21241                              <1> 	; 20/05/2015
 21242                              <1> 	; read only (duplicated) page -must be copied to a new page-
 21243                              <1> 	; EBX = linear address
 21244 00005A8C 51                  <1> 	push 	ecx
 21245 00005A8D E80BD9FFFF          <1> 	call 	copy_page
 21246 00005A92 59                  <1> 	pop	ecx
 21247 00005A93 721E                <1> 	jc	short passc_2
 21248 00005A95 50                  <1> 	push	eax ; physical address of the new/allocated page
 21249 00005A96 E817DBFFFF          <1> 	call	add_to_swap_queue	
 21250 00005A9B 58                  <1> 	pop	eax
 21251                              <1> 	; 18/10/2015
 21252 00005A9C 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
 21253                              <1> 	;mov 	ecx, PAGE_SIZE
 21254                              <1> 	;sub	ecx, ebx 
 21255 00005AA2 01D8                <1> 	add	eax, ebx  
 21256                              <1> passc_1: 
 21257                              <1> 	; 18/10/2015
 21258                              <1> 	; 20/05/2015
 21259 00005AA4 A3[B3740000]        <1> 	mov 	[u.pbase], eax ; physical address	
 21260 00005AA9 66890D[B7740000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
 21261 00005AB0 5B                  <1> 	pop	ebx
 21262 00005AB1 58                  <1> 	pop	eax
 21263 00005AB2 C3                  <1> 	retn	; 08/06/2015
 21264                              <1> passc_2:
 21265 00005AB3 C705[A7740000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
 21266 00005ABB 0000                <1>
 21267                              <1> 	;pop 	ebx
 21268                              <1> 	;pop	eax
 21269 00005ABD E98BE5FFFF          <1> 	jmp	error
 21270                              <1> 
 21271                              <1> writei:
 21272                              <1> 	; 20/05/2015
 21273                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21274                              <1> 	; 12/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 21275                              <1> 	;
 21276                              <1> 	; Write data to file with inode number in R1
 21277                              <1> 	; 
 21278                              <1> 	; INPUTS ->
 21279                              <1> 	;    r1 - inode number
 21280                              <1> 	;    u.count - byte count to be written
 21281                              <1> 	;    u.base - points to user buffer
 21282                              <1> 	;    u.fofp - points to word with current file offset
 21283                              <1> 	; OUTPUTS ->
 21284                              <1> 	;    u.count - cleared
 21285                              <1> 	;    u.nread - accumulates total bytes passed back	
 21286                              <1> 	; ((AX = R1))
 21287                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 11/11/2012, UNIXCOPY.ASM)
 21288                              <1> 	;    ((Modified registers: DX, BX, CX, SI, DI, BP)) 	
 21289                              <1> 
 21290 00005AC2 31C9                <1> 	xor	ecx, ecx
 21291 00005AC4 890D[80740000]      <1> 	mov 	[u.nread], ecx  ; 0
 21292                              <1> 		; clr u.nread / clear the number of bytes transmitted during
 21293                              <1> 		            ; / read or write calls
 21294 00005ACA 66890D[B7740000]    <1> 	mov	[u.pcount], cx ; 19/05/2015
 21295 00005AD1 390D[7C740000]      <1> 	cmp 	[u.count], ecx
 21296                              <1> 	;	; tst u.count / test the byte count specified by the user
 21297 00005AD7 7701                <1> 	ja 	short writei_1 ; 1f
 21298                              <1> 		; bgt 1f / any bytes to output; yes, branch
 21299 00005AD9 C3                  <1> 	retn
 21300                              <1> 	;	; rts r0 / no, return - no writing to do
 21301                              <1> writei_1: ;1:
 21302                              <1> 		; mov r1 ,-(sp) / save the i-node number on the stack
 21303 00005ADA 6683F828            <1> 	cmp 	ax, 40
 21304                              <1> 		; cmp r1,$40.
 21305                              <1> 		; / does the i-node number indicate a special file?
 21306 00005ADE 0F87F2000000        <1>         ja      dskw 
 21307                              <1> 		; bgt dskw / no, branch to standard file output
 21308                              <1> 	; (20/05/2015)
 21309 00005AE4 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 21310 00005AE5 0FB6D8              <1> 	movzx	ebx, al
 21311 00005AE8 66C1E302            <1> 	shl	bx, 2
 21312                              <1> 		; asl r1 / yes, calculate the index into the special file
 21313 00005AEC 81C3[F05A0000]      <1> 	add	ebx, writei_2 - 4
 21314 00005AF2 FF23                <1> 	jmp	dword [ebx]	
 21315                              <1> 		; jmp *1f-2(r1)
 21316                              <1> 		; / jump table and jump to the appropriate routine
 21317                              <1> writei_2: ;1:
 21318 00005AF4 [405B0000]          <1> 	dd	wtty ; tty, AX = 1 (runix)
 21319                              <1> 		 ;wtty / tty; r1=2
 21320                              <1> 		 ;wppt / ppt; r1=4
 21321 00005AF8 [A65B0000]          <1> 	dd	wmem ; mem, AX = 2 (runix)
 21322                              <1> 		 ;wmem / mem; r1=6
 21323                              <1> 		 ;wrf0 / rf0
 21324                              <1> 		 ;wrk0 / rk0
 21325                              <1> 		 ;wtap / tap0
 21326                              <1> 		 ;wtap / tap1
 21327                              <1> 		 ;wtap / tap2
 21328                              <1> 		 ;wtap / tap3
 21329                              <1> 		 ;wtap / tap4
 21330                              <1> 		 ;wtap / tap5
 21331                              <1> 		 ;wtap / tap6
 21332                              <1> 		 ;wtap / tap7
 21333 00005AFC [E1600000]          <1> 	dd	wfd ; fd0, AX = 3 (runix only)
 21334 00005B00 [E1600000]          <1> 	dd	wfd ; fd1, AX = 4 (runix only)
 21335 00005B04 [E1600000]          <1> 	dd	whd ; hd0, AX = 5 (runix only)
 21336 00005B08 [E1600000]          <1> 	dd	whd ; hd1, AX = 6 (runix only)	
 21337 00005B0C [E1600000]          <1> 	dd	whd ; hd2, AX = 7 (runix only)
 21338 00005B10 [E1600000]          <1> 	dd	whd ; hd3, AX = 8 (runix only)	
 21339 00005B14 [975B0000]          <1> 	dd	wlpr ; lpr, AX = 9   (runix)
 21340 00005B18 [915B0000]          <1> 	dd	xmtt ; tty0, AX = 10 (runix)	  
 21341                              <1> 		 ;xmtt / tty0
 21342 00005B1C [915B0000]          <1> 	dd	xmtt ; tty1, AX = 11 (runix)	  
 21343                              <1> 		 ;xmtt / tty1
 21344 00005B20 [915B0000]          <1> 	dd	xmtt ; tty2, AX = 12 (runix)	  
 21345                              <1> 		 ;xmtt / tty2
 21346 00005B24 [915B0000]          <1> 	dd	xmtt ; tty3, AX = 13 (runix)	  
 21347                              <1> 		 ;xmtt / tty3
 21348 00005B28 [915B0000]          <1> 	dd	xmtt ; tty4, AX = 14 (runix)	  
 21349                              <1> 		 ;xmtt / tty4
 21350 00005B2C [915B0000]          <1> 	dd	xmtt ; tty5, AX = 15 (runix)	  
 21351                              <1> 		 ;xmtt / tty5
 21352 00005B30 [915B0000]          <1> 	dd	xmtt ; tty6, AX = 16 (runix)	  
 21353                              <1> 		 ;xmtt / tty6
 21354 00005B34 [915B0000]          <1> 	dd	xmtt ; tty7, AX = 17 (runix)	  
 21355                              <1> 		 ;xmtt / tty7
 21356 00005B38 [915B0000]          <1> 	dd	xmtt ; COM1, AX = 18 (runix only)	  
 21357                              <1> 		; / wlpr / lpr
 21358 00005B3C [915B0000]          <1> 	dd	xmtt ; COM2, AX = 19 (runix only)	
 21359                              <1> 
 21360                              <1> wtty: ; write to console tty (write to screen)
 21361                              <1> 	; 18/11/2015
 21362                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21363                              <1> 	; 12/03/2013 - 07/07/2014 (Retro UNIX 8086 v1)
 21364                              <1> 	;
 21365                              <1> 	; Console tty output is on current video page
 21366                              <1> 	; Console tty character output procedure is changed here
 21367                              <1> 	; acconding to IBM PC compatible ROM BIOS video (text mode) functions.
 21368                              <1> 	;
 21369 00005B40 0FB61D[A1740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 21370 00005B47 8AA3[A5710000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 21371 00005B4D 88E0                <1> 	mov	al, ah ; 07/07/2014
 21372                              <1> wttys:	
 21373                              <1> 	; 10/10/2013
 21374 00005B4F 8825[A6740000]      <1> 	mov 	[u.ttyn], ah
 21375                              <1> 	; 13/01/2014
 21376 00005B55 FEC0                <1> 	inc	al
 21377 00005B57 A2[89740000]        <1> 	mov	[u.ttyp+1], al ; tty number + 1
 21378                              <1> wtty_nc: ; 15/05/2013
 21379                              <1> 	; AH = [u.ttyn] = tty number ; 28/07/2013
 21380 00005B5C E81C010000          <1> 	call	cpass
 21381                              <1> 		; jsr r0,cpass / get next character from user buffer area; if
 21382                              <1> 		             ; / none go to return address in syswrite
 21383                              <1> 		; tst r1 / is character = null
 21384                              <1> 		; beq wtty / yes, get next character
 21385                              <1> 	; 10/10/2013
 21386 00005B61 742C                <1> 	jz	short wret
 21387                              <1> 	;1 :
 21388                              <1> 		;mov 	$240,*$ps / no, set processor priority to five
 21389                              <1> 		;cmpb	cc+1,$20. / is character count for console tty greater
 21390                              <1> 		;	          / than 20
 21391                              <1> 		;bhis	2f / yes; branch to put process to sleep
 21392                              <1> 	; 27/06/2014
 21393                              <1> wtty_1:
 21394                              <1> 	; AH = tty number
 21395                              <1> 	; AL = ASCII code of the character
 21396                              <1> 	; 15/04/2014
 21397 00005B63 6650                <1> 	push	ax
 21398 00005B65 E8AF0A0000          <1> 	call	putc ; 14/05/2013
 21399 00005B6A 731F                <1> 	jnc	short wtty_2
 21400                              <1> 	; 18/11/2015
 21401 00005B6C E8EEF8FFFF          <1> 	call	idle
 21402 00005B71 668B0424            <1> 	mov	ax, [esp]
 21403 00005B75 E89F0A0000          <1> 	call	putc
 21404 00005B7A 730F                <1> 	jnc	short wtty_2 
 21405                              <1> 	; 02/06/2014
 21406 00005B7C 8A25[A6740000]      <1> 	mov	ah, [u.ttyn]
 21407 00005B82 E86CF9FFFF          <1> 	call	sleep
 21408 00005B87 6658                <1> 	pop	ax
 21409 00005B89 EBD8                <1> 	jmp 	short wtty_1
 21410                              <1> 		; jc 	error ; 15/05/2013 (COM1 or COM2 serial port error)
 21411                              <1> 		; jsr 	r0,putc; 1 / find place in freelist to assign to 
 21412                              <1> 			      ; / console tty and
 21413                              <1> 		; br 	2f / place character in list; if none available
 21414                              <1> 		   	  ; / branch to put process to sleep
 21415                              <1> 		; jsr	r0,startty / attempt to output character on tty
 21416                              <1> wtty_2:
 21417                              <1> 	; 15/04/2014
 21418 00005B8B 6658                <1> 	pop	ax
 21419 00005B8D EBCD                <1> 	jmp	short wtty_nc
 21420                              <1> 		; br wtty
 21421                              <1> wret:	; 10/10/2013 (20/05/2015)
 21422 00005B8F 58                  <1> 	pop	eax
 21423 00005B90 C3                  <1> 	retn
 21424                              <1> 	;2:
 21425                              <1> 		;mov	r1,-(sp) / place character on stack
 21426                              <1> 		;jsr	r0,sleep; 1 / put process to sleep
 21427                              <1> 		;mov	(sp)+,r1 / remove character from stack
 21428                              <1> 		;br	1b / try again to place character in clist and output
 21429                              <1> 
 21430                              <1> xmtt:   ; < send/write character to tty >
 21431                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21432                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 21433                              <1> 	;
 21434                              <1> 	; Retro UNIX 8086 v1 modification !
 21435                              <1> 	; 
 21436                              <1> 	; In original UNIX v1, 'xmtt' routine 
 21437                              <1> 	;		(exactly different than this one)
 21438                              <1> 	;	was in 'u9.s' file.
 21439                              <1> 	;
 21440 00005B91 2C0A                <1> 	sub 	al, 10
 21441                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 21442                              <1> 	 ; 10/10/2013
 21443 00005B93 88C4                <1> 	mov	ah, al
 21444                              <1> 	; 28/07/2013
 21445 00005B95 EBB8                <1> 	jmp	short wttys
 21446                              <1> 
 21447                              <1> ;wppt:
 21448                              <1> ;	jsr	r0,cpass / get next character from user buffer area,
 21449                              <1> ;		         / if none return to writei's calling routine
 21450                              <1> ;	jsr	r0,pptoc / output character on ppt
 21451                              <1> ;	br	wppt
 21452                              <1> wlpr:
 21453 00005B97 C705[A7740000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 21454 00005B9F 0000                <1>
 21455 00005BA1 E9A7E4FFFF          <1> 	jmp 	error   ; ... Printing procedure will be located here ...
 21456                              <1> 		;/	jsr	r0,cpass
 21457                              <1> 		;/	cmp	r0,$'a
 21458                              <1> 		;/	blo	1f
 21459                              <1> 		;/	cmp	r1,$'z
 21460                              <1> 		;/	bhi	1f
 21461                              <1> 		;/	sub	$40,r1
 21462                              <1> 		;/1:
 21463                              <1> 		;/	jsr	r0,lptoc
 21464                              <1> 		;/	br	wlpr
 21465                              <1> 		; br rmem / continue
 21466                              <1> 
 21467                              <1> wmem: ; / transfer characters from a user area of core to memory file
 21468                              <1> 	; 17/10/2015
 21469                              <1> 	; 11/06/2015
 21470                              <1> 	; 24/05/2015
 21471                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21472                              <1> 	;
 21473 00005BA6 813D[D8070000]-     <1> 	cmp	dword [x_timer], clock ; multi tasking clock/timer
 21474 00005BAC [83540000]          <1>
 21475 00005BB0 7415                <1>         je      short wmem_acc_err
 21476                              <1> 	;
 21477 00005BB2 8B35[68740000]      <1>         mov     esi, [u.fofp] 
 21478                              <1> wmem_1:
 21479 00005BB8 E8C0000000          <1> 	call	cpass
 21480                              <1> 		; jsr r0,cpass / get next character from users area of
 21481                              <1> 			     ; / core and put it in r1
 21482                              <1>         	; mov r1,-(sp) / put character on the stack
 21483                              <1> 	; 20/09/2013
 21484 00005BBD 74D0                <1> 	jz	short wret ; wmem_2  
 21485 00005BBF 8B1E                <1>         mov     ebx, [esi]
 21486                              <1> 		; mov *u.fofp,r1 / save file offset in r1
 21487 00005BC1 FF06                <1>         inc     dword [esi] ; 17/10/2015
 21488                              <1> 		; inc *u.fofp / increment file offset to point to next
 21489                              <1> 			    ; / available location in file
 21490 00005BC3 8803                <1> 	mov	[ebx], al	
 21491                              <1> 		; movb (sp)+,(r1) / pop char off stack, put in memory loc 
 21492                              <1> 			        ; / assigned to it
 21493 00005BC5 EBF1                <1> 	jmp	short wmem_1
 21494                              <1> 		; br wmem / continue
 21495                              <1> 	;1:
 21496                              <1> 	;jmp	error / ?
 21497                              <1> ;wmem_2:	
 21498                              <1> ;	; 20/09/2013
 21499                              <1> ;	pop	ax
 21500                              <1> ;	retn
 21501                              <1> 
 21502                              <1> wmem_acc_err:
 21503 00005BC7 C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 21504 00005BCF 0000                <1>
 21505 00005BD1 E977E4FFFF          <1> 	jmp	error
 21506                              <1> 
 21507                              <1> 
 21508                              <1> dskw: ; / write routine for non-special files
 21509                              <1> 	;
 21510                              <1> 	; 25/07/2015
 21511                              <1> 	; 16/06/2015
 21512                              <1> 	; 09/06/2015
 21513                              <1> 	; 31/05/2015 (Retro UNIX 386 v1 - Beginning)
 21514                              <1> 	; 26/04/2013 - 20/09/2013 (Retro UNIX 8086 v1)
 21515                              <1> 	;
 21516                              <1> 	; 01/08/2013 (mkdir_w check)
 21517 00005BD6 6650                <1> 	push	ax ; 26/04/2013
 21518                              <1> 		; mov (sp),r1 / get an i-node number from the stack into r1
 21519                              <1> 	; AX = inode number
 21520 00005BD8 E80FFBFFFF          <1> 	call	iget
 21521                              <1> 		; jsr r0,iget / write i-node out (if modified), 
 21522                              <1> 		            ; / read i-node 'r1' into i-node area of core
 21523 00005BDD 8B1D[68740000]      <1>         mov     ebx, [u.fofp] 
 21524 00005BE3 8B13                <1> 	mov 	edx, [ebx]
 21525                              <1> 		; mov *u.fofp,r2 / put the file offset [(u.off) or the offset
 21526                              <1> 			       ; / in the fsp entry for this file] in r2
 21527 00005BE5 0315[7C740000]      <1> 	add 	edx, [u.count]	
 21528                              <1> 		; add u.count,r2 / no. of bytes to be written
 21529                              <1> 			       ; / + file offset is put in r2
 21530                              <1> 	; 16/06/2015        
 21531 00005BEB 81FAFFFF0000        <1> 	cmp	edx, 65535 ; file size limit (for UNIX v1 file system)
 21532 00005BF1 760F                <1> 	jna	short dskw_0
 21533 00005BF3 C705[A7740000]1400- <1> 	mov	dword [u.error], ERR_FILE_SIZE ; 'file size error !'
 21534 00005BFB 0000                <1>
 21535 00005BFD E94BE4FFFF          <1> 	jmp	error
 21536                              <1> dskw_0:	
 21537 00005C02 663B15[2A710000]    <1> 	cmp     dx, [i.size]
 21538                              <1> 		; cmp r2,i.size / is this greater than the present size of
 21539                              <1> 		              ; / the file?
 21540 00005C09 760C                <1> 	jna	short dskw_1
 21541                              <1> 		; blos 1f / no, branch
 21542 00005C0B 668915[2A710000]    <1>         mov     [i.size], dx
 21543                              <1> 	 	; mov r2,i.size / yes, increase the file size to 
 21544                              <1> 			      ; / file offset + no. of data bytes
 21545 00005C12 E8E8FBFFFF          <1> 	call	setimod
 21546                              <1> 	 	; jsr r0,setimod / set imod=1 (i.e., core inode has been
 21547                              <1> 		          ; / modified), stuff time of modification into
 21548                              <1> 	          	  ; / core image of i-node
 21549                              <1> dskw_1: ; 1:	
 21550 00005C17 E85DF9FFFF          <1> 	call	mget
 21551                              <1> 	; eAX = Block number
 21552                              <1> 		; jsr r0,mget / get the block no. in which to write 
 21553                              <1> 			    ; /	the next data byte
 21554                              <1> 	; eax = block number
 21555 00005C1C 8B1D[68740000]      <1> 	mov     ebx, [u.fofp]
 21556 00005C22 8B13                <1> 	mov	edx, [ebx]
 21557 00005C24 81E2FF010000        <1> 	and	edx, 1FFh  
 21558                              <1> 		; bit *u.fofp,$777 / test the lower 9 bits of the file offset
 21559 00005C2A 750C                <1> 	jnz	short dskw_2
 21560                              <1> 		; bne 2f / if its non-zero, branch; if zero, file offset = 0,
 21561                              <1> 		       ; / 512, 1024,...(i.e., start of new block)
 21562 00005C2C 813D[7C740000]0002- <1> 	cmp	dword [u.count], 512
 21563 00005C34 0000                <1>
 21564                              <1> 		; cmp u.count,$512. / if zero, is there enough data to fill
 21565                              <1> 				  ; / an entire block? (i.e., no. of
 21566 00005C36 7305                <1> 	jnb	short dskw_3
 21567                              <1> 		; bhis 3f / bytes to be written greater than 512.? 
 21568                              <1> 			; / Yes, branch. Don't have to read block
 21569                              <1> dskw_2: ; 2: / in as no past info. is to be saved (the entire block will be
 21570                              <1>    		; / overwritten).
 21571 00005C38 E87C050000          <1> 	call	dskrd
 21572                              <1> 		; jsr r0,dskrd / no, must retain old info.. 
 21573                              <1> 			     ; / Hence, read block 'r1' into an I/O buffer
 21574                              <1> dskw_3: ; 3:
 21575                              <1> 	; eAX (r1) = block/sector number
 21576 00005C3D E8D7050000          <1> 	call	wslot
 21577                              <1> 		; jsr r0,wslot / set write and inhibit bits in I/O queue, 
 21578                              <1> 			   ; / proc. status=0, r5 points to 1st word of data
 21579 00005C42 803D[B9740000]00    <1> 	cmp	byte [u.kcall], 0
 21580 00005C49 770F                <1> 	ja	short dskw_5 ; zf=0 -> the caller is 'mkdir'
 21581                              <1> 	;
 21582 00005C4B 66833D[B7740000]00  <1> 	cmp	word [u.pcount], 0
 21583 00005C53 7705                <1> 	ja	short dskw_5
 21584                              <1> dskw_4:
 21585                              <1> 	; [u.base] = virtual address to transfer (as source address)
 21586 00005C55 E806FEFFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 21587                              <1> dskw_5:
 21588                              <1> 	; eBX (r5) = system (I/O) buffer address
 21589 00005C5A E87E000000          <1> 	call	sioreg
 21590                              <1> 		; jsr r0,sioreg / r3 = no. of bytes of data, 
 21591                              <1> 			     ; / r1 = address of data, r2 points to location
 21592                              <1> 			     ; / in buffer in which to start writing data
 21593                              <1> 	; eSI = file (user data) offset
 21594                              <1> 	; eDI = sector (I/O) buffer offset
 21595                              <1> 	; eCX = byte count
 21596                              <1> 	;
 21597 00005C5F F3A4                <1>   	rep	movsb
 21598                              <1> 		; movb (r1 )+,(r2)+ 
 21599                              <1> 		         ; / transfer a byte of data to the I/O buffer
 21600                              <1> 		; dec r3 / decrement no. of bytes to be written
 21601                              <1> 		; bne 2b / have all bytes been transferred? No, branch
 21602                              <1> 	; 25/07/2015
 21603                              <1> 	; eax = remain bytes in buffer
 21604                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 21605 00005C61 09C0                <1> 	or	eax, eax
 21606 00005C63 75F0                <1> 	jnz	short dskw_4 ; (page end before system buffer end!)	
 21607                              <1> dskw_6:
 21608 00005C65 E8CB050000          <1> 	call	dskwr
 21609                              <1> 		; jsr r0,dskwr / yes, write the block and the i-node
 21610 00005C6A 833D[7C740000]00    <1>         cmp     dword [u.count], 0
 21611                              <1> 		; tst u.count / any more data to write?
 21612 00005C71 77A4                <1> 	ja	short dskw_1
 21613                              <1> 		; bne 1b / yes, branch
 21614                              <1> 	; 03/08/2013
 21615 00005C73 C605[B9740000]00    <1> 	mov	byte [u.kcall], 0
 21616                              <1> 	; 20/09/2013 (;;)
 21617 00005C7A 6658                <1> 	pop	ax
 21618 00005C7C C3                  <1> 	retn
 21619                              <1> 	;;jmp 	short dskw_ret 
 21620                              <1> 	        ; jmp ret / no, return to the caller via 'ret'
 21621                              <1> 
 21622                              <1> cpass: ; / get next character from user area of core and put it in r1
 21623                              <1> 	; 18/10/2015
 21624                              <1> 	; 10/10/2015
 21625                              <1> 	; 10/07/2015
 21626                              <1> 	; 02/07/2015
 21627                              <1> 	; 01/07/2015
 21628                              <1> 	; 24/06/2015
 21629                              <1> 	; 08/06/2015
 21630                              <1> 	; 04/06/2015
 21631                              <1> 	; 20/05/2015
 21632                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21633                              <1> 	;
 21634                              <1> 	; INPUTS -> 
 21635                              <1> 	;     [u.base] = virtual address in user area
 21636                              <1> 	;     [u.count] = byte count (max.)
 21637                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
 21638                              <1> 	; OUTPUTS -> 
 21639                              <1> 	;     AL = the character which is pointed by [u.base]
 21640                              <1> 	;     zf = 1 -> transfer count has been completed	
 21641                              <1>         ;
 21642                              <1> 	; ((Modified registers:  EAX, EDX, ECX))
 21643                              <1> 	;
 21644                              <1> 	;
 21645 00005C7D 833D[7C740000]00    <1> 	cmp 	dword [u.count], 0  ; 14/08/2013
 21646                              <1> 		; tst u.count / have all the characters been transferred
 21647                              <1> 			    ; / (i.e., u.count, # of chars. left
 21648 00005C84 763F                <1> 	jna	short cpass_3
 21649                              <1> 		; beq 1f / to be transferred = 0?) yes, branch
 21650 00005C86 FF0D[7C740000]      <1> 	dec	dword [u.count]
 21651                              <1> 		; dec u.count / no, decrement u.count
 21652                              <1>         ; 19/05/2015 
 21653                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
 21654                              <1> 	;		      to physical address
 21655 00005C8C 66833D[B7740000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 21656                              <1> 			     ; 1-4095 --> use previous physical base address
 21657                              <1> 			     ; in [u.pbase]
 21658 00005C94 770E                <1> 	ja	short cpass_1
 21659                              <1> 	; 02/07/2015
 21660 00005C96 833D[AF740000]00    <1>         cmp     dword [u.ppgdir], 0  ; is the caller os kernel
 21661 00005C9D 7427                <1>         je      short cpass_k       ; (sysexec, '/etc/init') ? 
 21662                              <1> 	; 08/06/2015 - 10/07/2015
 21663 00005C9F E8BCFDFFFF          <1> 	call	trans_addr_r
 21664                              <1> cpass_1:
 21665                              <1> 	; 02/07/2015
 21666                              <1> 	; 24/06/2015
 21667 00005CA4 66FF0D[B7740000]    <1> 	dec	word [u.pcount]
 21668                              <1> cpass_2: 
 21669                              <1> 	 ;10/10/2015
 21670                              <1> 	; 02/07/2015
 21671 00005CAB 8B15[B3740000]      <1> 	mov	edx, [u.pbase]
 21672 00005CB1 8A02                <1> 	mov	al, [edx] ; 10/10/2015
 21673                              <1> 		; movb *u.base,r1 / take the character pointed to 
 21674                              <1> 				; / by u.base and put it in r1
 21675 00005CB3 FF05[80740000]      <1> 	inc	dword [u.nread]
 21676                              <1> 		; inc u.nread / increment no. of bytes transferred
 21677 00005CB9 FF05[78740000]      <1> 	inc	dword [u.base]
 21678                              <1> 		; inc u.base / increment the buffer address to point to the
 21679                              <1> 			   ; / next byte
 21680 00005CBF FF05[B3740000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 21681                              <1> cpass_3:
 21682 00005CC5 C3                  <1> 	retn
 21683                              <1> 		; rts	r0 / next byte
 21684                              <1> 	; 1: 
 21685                              <1> 		; mov (sp)+,r0 
 21686                              <1> 		         ; / put return address of calling routine into r0
 21687                              <1> 		; mov (sp)+,r1 / i-number in r1
 21688                              <1> 		; rts r0 / non-local return
 21689                              <1> cpass_k:
 21690                              <1> 	; 02/07/2015
 21691                              <1> 	; The caller is os kernel 
 21692                              <1> 	; (get sysexec arguments from kernel's memory space)
 21693                              <1> 	;
 21694 00005CC6 8B1D[78740000]      <1> 	mov	ebx, [u.base]
 21695 00005CCC 66C705[B7740000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
 21696 00005CD4 10                  <1>
 21697 00005CD5 891D[B3740000]      <1> 	mov	[u.pbase], ebx
 21698 00005CDB EBCE                <1> 	jmp	short cpass_2
 21699                              <1> 	
 21700                              <1> sioreg: 
 21701                              <1> 	; 25/07/2015
 21702                              <1> 	; 18/07/2015
 21703                              <1> 	; 02/07/2015
 21704                              <1> 	; 17/06/2015
 21705                              <1> 	; 09/06/2015
 21706                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 21707                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
 21708                              <1> 	;
 21709                              <1> 	; INPUTS -> 
 21710                              <1> 	;     eBX = system buffer (data) address (r5)
 21711                              <1> 	;     [u.fofp] = pointer to file offset pointer
 21712                              <1> 	;     [u.base] = virtual address of the user buffer
 21713                              <1> 	;     [u.pbase] = physical address of the user buffer
 21714                              <1> 	;     [u.count] = byte count
 21715                              <1> 	;     [u.pcount] = byte count within page frame 			
 21716                              <1> 	; OUTPUTS -> 
 21717                              <1> 	;     eSI = user data offset (r1)
 21718                              <1> 	;     eDI = system (I/O) buffer offset (r2)
 21719                              <1> 	;     eCX = byte count (r3)
 21720                              <1> 	;     EAX = remain bytes after byte count within page frame
 21721                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
 21722                              <1>         ;
 21723                              <1> 	; ((Modified registers:  EDX))
 21724                              <1>  
 21725 00005CDD 8B35[68740000]      <1>         mov     esi, [u.fofp]
 21726 00005CE3 8B3E                <1>         mov     edi, [esi]
 21727                              <1> 		; mov *u.fofp,r2 / file offset (in bytes) is moved to r2
 21728 00005CE5 89F9                <1> 	mov	ecx, edi
 21729                              <1> 		; mov r2,r3 / and also to r3
 21730 00005CE7 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
 21731                              <1> 		; bis $177000,r3 / set bits 9,...,15 of file offset in r3
 21732 00005CED 81E7FF010000        <1> 	and	edi, 1FFh
 21733                              <1> 		; bic $!777,r2 / calculate file offset mod 512.
 21734 00005CF3 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
 21735                              <1> 		; add r5,r2 / r2 now points to 1st byte in system buffer
 21736                              <1> 			  ; / where data is to be placed
 21737                              <1>                 ; mov u.base,r1 / address of data is in r1
 21738 00005CF5 F7D9                <1> 	neg	ecx
 21739                              <1> 		; neg r3 / 512 - file offset (mod512.) in r3 
 21740                              <1> 		       ; / (i.e., the no. of free bytes in the file block)
 21741 00005CF7 3B0D[7C740000]      <1> 	cmp	ecx, [u.count]
 21742                              <1> 		; cmp r3,u.count / compare this with the no. of data bytes
 21743                              <1> 			       ; / to be written to the file
 21744 00005CFD 7606                <1> 	jna	short sioreg_0
 21745                              <1> 		; blos	2f / if less than branch. Use the no. of free bytes
 21746                              <1> 			 ; / in the file block as the number to be written
 21747 00005CFF 8B0D[7C740000]      <1> 	mov	ecx, [u.count]
 21748                              <1> 		; mov u.count,r3 / if greater than, use the no. of data 
 21749                              <1> 			       ; / bytes as the number to be written
 21750                              <1> sioreg_0:
 21751                              <1> 	; 17/06/2015
 21752 00005D05 803D[B9740000]00    <1> 	cmp	byte [u.kcall], 0 
 21753 00005D0C 7613                <1> 	jna	short sioreg_1
 21754                              <1> 	; 25/07/2015
 21755                              <1> 	 ; the caller is 'mkdir' or 'namei'
 21756 00005D0E A1[78740000]        <1> 	mov	eax, [u.base] ; 25/07/2015
 21757 00005D13 A3[B3740000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
 21758 00005D18 66890D[B7740000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
 21759 00005D1F EB0B                <1> 	jmp	short sioreg_2
 21760                              <1> sioreg_1:
 21761                              <1> 	; 25/07/2015
 21762                              <1> 	; 18/07/2015
 21763                              <1> 	; 09/06/2015 
 21764 00005D21 0FB715[B7740000]    <1> 	movzx	edx, word [u.pcount]
 21765                              <1> 		; ecx and [u.pcount] are always > 0, here
 21766 00005D28 39D1                <1> 	cmp	ecx, edx	
 21767 00005D2A 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
 21768                              <1> sioreg_2: ; 2:
 21769 00005D2C 31C0                <1> 	xor 	eax, eax ; 25/07/2015
 21770                              <1> sioreg_3:
 21771 00005D2E 010D[80740000]      <1> 	add 	[u.nread], ecx
 21772                              <1> 		; add r3,u.nread / r3 + number of bytes xmitted 
 21773                              <1> 			         ; / during write is put into u.nread
 21774 00005D34 290D[7C740000]      <1> 	sub 	[u.count], ecx
 21775                              <1> 		; sub r3,u.count / u.count = no. of bytes that still 
 21776                              <1> 			       ; / must be written or read
 21777 00005D3A 010D[78740000]      <1> 	add 	[u.base], ecx
 21778                              <1> 		; add r3,u.base / u.base points to the 1st of the remaining
 21779                              <1> 			      ; / data bytes
 21780 00005D40 010E                <1>         add 	[esi], ecx 
 21781                              <1> 		; add r3,*u.fofp / new file offset = number of bytes done
 21782                              <1> 			       ; / + old file offset
 21783                              <1> 	; 25/07/2015
 21784 00005D42 8B35[B3740000]      <1> 	mov	esi, [u.pbase]
 21785 00005D48 66290D[B7740000]    <1> 	sub	[u.pcount], cx
 21786 00005D4F 010D[B3740000]      <1> 	add	[u.pbase], ecx
 21787 00005D55 C3                  <1>         retn
 21788                              <1> 		; rts r0
 21789                              <1> 		; transfer count > [u.pcount]
 21790                              <1> sioreg_4:
 21791                              <1> 	; 25/07/2015
 21792                              <1> 	; transfer count > [u.pcount] 
 21793                              <1> 	; (ecx > edx)
 21794 00005D56 89C8                <1> 	mov	eax, ecx
 21795 00005D58 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
 21796 00005D5A 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
 21797 00005D5C EBD0                <1> 	jmp	short sioreg_3
 21798                                  %include 'u7.s'        ; 18/04/2015
 21799                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS7.INC
 21800                              <1> ; Last Modification: 14/11/2015
 21801                              <1> ; ----------------------------------------------------------------------------
 21802                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 21803                              <1> ; (v0.1 - Beginning: 11/07/2012)
 21804                              <1> ;
 21805                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 21806                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 21807                              <1> ; <Bell Laboratories (17/3/1972)>
 21808                              <1> ; <Preliminary Release of UNIX Implementation Document>
 21809                              <1> ;
 21810                              <1> ; Retro UNIX 8086 v1 - U7.ASM (13/07/2014) //// UNIX v1 -> u7.s
 21811                              <1> ;
 21812                              <1> ; ****************************************************************************
 21813                              <1> 
 21814                              <1> sysmount: ; / mount file system; args special; name
 21815                              <1> 	; 14/11/2015
 21816                              <1> 	; 24/10/2015
 21817                              <1> 	; 13/10/2015
 21818                              <1> 	; 10/07/2015
 21819                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 21820                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 21821                              <1> 	;
 21822                              <1> 	; 'sysmount' anounces to the system that a removable 
 21823                              <1> 	; file system has been mounted on a special file.
 21824                              <1> 	; The device number of the special file is obtained via
 21825                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
 21826                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
 21827                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
 21828                              <1> 	; to read file system into core, i.e. the first block on the
 21829                              <1> 	; mountable file system is read in. This block is super block
 21830                              <1> 	; for the file system. This call is super user restricted.	
 21831                              <1> 	;
 21832                              <1> 	; Calling sequence:
 21833                              <1> 	;	sysmount; special; name
 21834                              <1> 	; Arguments:
 21835                              <1> 	;	special - pointer to name of special file (device)
 21836                              <1> 	;	name -  pointer to name of the root directory of the
 21837                              <1> 	;		newly mounted file system. 'name' should 
 21838                              <1> 	;		always be a directory.
 21839                              <1> 	; Inputs: - 
 21840                              <1> 	; Outputs: -
 21841                              <1> 	; ...............................................................
 21842                              <1> 	;				
 21843                              <1> 	; Retro UNIX 8086 v1 modification: 
 21844                              <1> 	;       'sysmount' system call has two arguments; so,
 21845                              <1> 	;	* 1st argument, special is pointed to by BX register
 21846                              <1> 	;	* 2nd argument, name is in CX register
 21847                              <1> 	;
 21848                              <1> 	;	NOTE: Device numbers, names and related procedures are 
 21849                              <1> 	;	       already modified for IBM PC compatibility and 
 21850                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
 21851                              <1> 	
 21852                              <1> 	;call	arg2
 21853                              <1> 		; jsr r0,arg2 / get arguments special and name
 21854 00005D5E 891D[70740000]      <1> 	mov	[u.namep], ebx
 21855 00005D64 51                  <1> 	push	ecx ; directory name
 21856 00005D65 66833D[44740000]00  <1> 	cmp	word [mnti], 0
 21857                              <1> 		; tst mnti / is the i-number of the cross device file
 21858                              <1> 			 ; / zero?
 21859                              <1> 	;ja	error
 21860                              <1>         	; bne errora / no, error
 21861 00005D6D 0F87E9000000        <1> 	ja	sysmnt_err0
 21862                              <1> 	;
 21863 00005D73 E8CC000000          <1> 	call	getspl
 21864                              <1> 		; jsr r0,getspl / get special files device number in r1
 21865                              <1> 	; 13/10/2015
 21866 00005D78 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
 21867 00005D7B F683[7A6B0000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
 21868 00005D82 750F                <1> 	jnz	short sysmnt_1
 21869                              <1> sysmnt_err1:
 21870 00005D84 C705[A7740000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
 21871 00005D8C 0000                <1>
 21872 00005D8E E9BAE2FFFF          <1> 	jmp	error
 21873                              <1> sysmnt_1:
 21874 00005D93 8F05[70740000]      <1> 	pop	dword [u.namep]
 21875                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
 21876                              <1> 				  ; / on the device
 21877                              <1> 	; 14/11/2015
 21878 00005D99 53                  <1> 	push	ebx ; 13/10/2015
 21879                              <1> 		; mov r1,-(sp) / save the device number
 21880                              <1>         ;
 21881 00005D9A E85DF1FFFF          <1> 	call	namei
 21882                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 21883                              <1> 		       ; ax = 0 -> file not found 	
 21884                              <1> 	;jz	error
 21885                              <1> 	;jc	error
 21886                              <1> 		; jsr r0,namei / get the i-number of the file
 21887                              <1>                	; br errora
 21888 00005D9F 730F                <1> 	jnc	short sysmnt_2
 21889                              <1> sysmnt_err2:
 21890 00005DA1 C705[A7740000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
 21891 00005DA9 0000                <1>
 21892 00005DAB E99DE2FFFF          <1> 	jmp	error
 21893                              <1> sysmnt_2:	
 21894 00005DB0 66A3[44740000]      <1> 	mov	[mnti], ax
 21895                              <1>         	; mov r1,mnti / put it in mnti
 21896                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
 21897                              <1> sysmnt_3: ;1:
 21898                              <1>         ;cmp	byte [ebx+1], 0
 21899                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
 21900                              <1> 			   ; / dismountable device set?
 21901                              <1>         ;jna	short sysmnt_4		
 21902                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
 21903                              <1> 	;call	idle 	; (wait for hardware interrupt)
 21904                              <1> 	;jmp	short sysmnt_3
 21905                              <1> sysmnt_4:   
 21906 00005DB6 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
 21907 00005DB7 A2[41740000]        <1> 	mov	[mdev], al
 21908                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
 21909 00005DBC 8803                <1> 	mov	[ebx], al
 21910                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
 21911                              <1> 			      ; / of the I/O queue entry
 21912                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
 21913                              <1>         	; mov (sp)+,cdev / put device number in cdev
 21914 00005DBE 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
 21915                              <1> 		; bis $2000,sb1 / set the read bit
 21916                              <1> 	; Retro UNIX 386 v1 modification : 
 21917                              <1> 	;	32 bit block number at buffer header offset 4
 21918 00005DC3 C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
 21919 00005DCA E8A3050000          <1> 	call 	diskio
 21920 00005DCF 731C                <1> 	jnc	short sysmnt_5
 21921 00005DD1 31C0                <1> 	xor 	eax, eax
 21922 00005DD3 66A3[44740000]      <1> 	mov	[mnti], ax ; 0
 21923 00005DD9 A2[41740000]        <1> 	mov	[mdev], al ; 0
 21924                              <1> 	;mov	[cdev], al ; 0
 21925                              <1> sysmnt_invd:
 21926                              <1> 	; 14/11/2015
 21927 00005DDE FEC8                <1> 	dec 	al
 21928 00005DE0 8903                <1> 	mov	[ebx], eax ; 000000FFh
 21929 00005DE2 FEC0                <1> 	inc	al
 21930 00005DE4 48                  <1> 	dec	eax
 21931 00005DE5 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
 21932 00005DE8 E960E2FFFF          <1> 	jmp	error
 21933                              <1> sysmnt_5:
 21934                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
 21935                              <1> 	; (Following check is needed to prevent mounting an
 21936                              <1> 	; in valid valid file system (in valid super block).
 21937                              <1> 	; 
 21938 00005DED 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
 21939 00005DF0 C0E002              <1> 	shl	al, 2 ; 4*index
 21940 00005DF3 8B88[5E6B0000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
 21941 00005DF9 C1E103              <1> 	shl 	ecx, 3
 21942 00005DFC 0FB715[14830000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
 21943 00005E03 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
 21944                              <1> 			 ; (in sectors), if they are not equal
 21945                              <1> 			 ; the disk to be mounted is an...	
 21946 00005E05 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
 21947                              <1> 			 ; (which has not got a valid super block)
 21948                              <1> 	;
 21949 00005E07 C6430100            <1> 	mov	byte [ebx+1], 0
 21950                              <1> 	       	; jsr r0,ppoke / read in entire file system
 21951                              <1> ;sysmnt_6: ;1:
 21952                              <1> 	;;cmp	byte [sb1+1], 0
 21953                              <1> 		; tstb   sb1+1 / done reading?
 21954                              <1>    	;;jna	sysret
 21955                              <1> 	;;call	idle ; (wait for hardware interrupt)
 21956                              <1> 	;;jmp	short sysmnt_6
 21957                              <1> 		;bne 1b / no, wait
 21958                              <1>         	;br sysreta / yes
 21959 00005E0B E95DE2FFFF          <1> 	jmp	sysret
 21960                              <1> 
 21961                              <1> sysumount: ; / special dismount file system
 21962                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 21963                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 21964                              <1> 	;
 21965                              <1> 	; 04/11/2013
 21966                              <1> 	; 09/07/2013
 21967                              <1> 	; 'sysumount' anounces to the system that the special file, 
 21968                              <1> 	; indicated as an argument is no longer contain a removable
 21969                              <1> 	; file system. 'getspl' gets the device number of the special
 21970                              <1> 	; file. If no file system was mounted on that device an error
 21971                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
 21972                              <1> 	; to 'sysret'.
 21973                              <1> 	;
 21974                              <1> 	; Calling sequence:
 21975                              <1> 	;	sysmount; special
 21976                              <1> 	; Arguments:
 21977                              <1> 	;	special - special file to dismount (device)
 21978                              <1> 	;
 21979                              <1> 	; Inputs: - 
 21980                              <1> 	; Outputs: -
 21981                              <1> 	; ...............................................................
 21982                              <1> 	;				
 21983                              <1> 	; Retro UNIX 8086 v1 modification: 
 21984                              <1> 	;       'sysumount' system call has one argument; so,
 21985                              <1> 	;	* Single argument, special is pointed to by BX register
 21986                              <1> 	;
 21987                              <1> 	
 21988                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
 21989                              <1> 	;call	arg
 21990                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
 21991 00005E10 891D[70740000]      <1>         mov	[u.namep], ebx
 21992 00005E16 E829000000          <1> 	call	getspl
 21993                              <1> 		; jsr r0,getspl / get the device number in r1
 21994 00005E1B 3A05[41740000]      <1> 	cmp	al, [mdev]
 21995                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
 21996 00005E21 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
 21997                              <1> 	;jne	error
 21998                              <1>         	; bne errora / no error
 21999 00005E23 30C0                <1> 	xor	al, al ; ah = 0
 22000                              <1> sysumnt_0: ;1:
 22001 00005E25 3805[11830000]      <1>      	cmp 	[sb1+1], al ; 0
 22002                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
 22003                              <1> 			   ; / (inhibit bit set)?
 22004 00005E2B 7607                <1> 	jna	short sysumnt_1		
 22005                              <1> 		; bne 1b / yes, wait
 22006 00005E2D E82DF6FFFF          <1> 	call	idle ; (wait for hardware interrupt)
 22007 00005E32 EBF1                <1> 	jmp	short sysumnt_0
 22008                              <1> sysumnt_1:        
 22009 00005E34 A2[41740000]        <1> 	mov	[mdev], al
 22010                              <1> 	     	; clr mntd / no, clear these
 22011 00005E39 66A3[44740000]      <1>    	mov	[mnti], ax
 22012                              <1>         	; clr mnti
 22013 00005E3F E929E2FFFF          <1>         jmp	sysret
 22014                              <1> 		; br sysreta / return
 22015                              <1> 
 22016                              <1> getspl: ; / get device number from a special file name
 22017 00005E44 E8B3F0FFFF          <1> 	call	namei
 22018                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 22019                              <1> 		       ; ax = 0 -> file not found 	
 22020 00005E49 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
 22021                              <1> 	;jz	error
 22022                              <1> 	;jc	error
 22023                              <1> 		; jsr r0,namei / get the i-number of the special file
 22024                              <1>                 ; br errora / no such file
 22025 00005E4F 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
 22026                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
 22027                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
 22028 00005E53 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
 22029                              <1> 	;jc	error
 22030                              <1> 		; ble errora / less than 0?  yes, error
 22031 00005E55 6683F805            <1>         cmp	ax, 5 ;
 22032                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
 22033 00005E59 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
 22034                              <1> 	;ja	error
 22035                              <1>         	; bgt errora / yes, error
 22036                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
 22037                              <1> iopen_retn:
 22038 00005E5B C3                  <1> 	retn
 22039                              <1> 		; rts    r0 / return with device number in r1
 22040                              <1> sysmnt_err0:
 22041 00005E5C C705[A7740000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 22042 00005E64 0000                <1>
 22043 00005E66 E9E2E1FFFF          <1> 	jmp	error
 22044                              <1> iopen:
 22045                              <1> 	; 19/05/2015
 22046                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 22047                              <1> 	; 21/05/2013 - 27/08/2013 (Retro UNIX 8086 v1)
 22048                              <1> 	;
 22049                              <1> 	; open file whose i-number is in r1
 22050                              <1> 	; 
 22051                              <1> 	; INPUTS ->
 22052                              <1> 	;    r1 - inode number
 22053                              <1> 	; OUTPUTS ->
 22054                              <1> 	;    file's inode in core	
 22055                              <1> 	;    r1 - inode number (positive)
 22056                              <1> 	;
 22057                              <1> 	; ((AX = R1))
 22058                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, edi, ebp)) 
 22059                              <1> 	;        
 22060                              <1> ; / open file whose i-number is in r1
 22061 00005E6B F6C480              <1> 	test	ah, 80h ; Bit 15 of AX
 22062                              <1> 		;tst r1 / write or read access?
 22063 00005E6E 756A                <1>         jnz	short iopen_2
 22064                              <1> 		;blt 2f / write, go to 2f
 22065 00005E70 B202                <1> 	mov	dl, 2 ; read access
 22066 00005E72 E850F9FFFF          <1> 	call	access
 22067                              <1>         	; jsr r0,access; 2 
 22068                              <1> 	; / get inode into core with read access
 22069                              <1> 	; DL=2
 22070                              <1> iopen_0:
 22071 00005E77 6683F828            <1>         cmp	ax, 40
 22072                              <1> 		; cmp r1,$40. / is it a special file
 22073 00005E7B 77DE                <1>         ja	short iopen_retn
 22074                              <1> 		;bgt  3f / no. 3f
 22075 00005E7D 6650                <1> 	push	ax
 22076                              <1> 		; mov r1,-(sp) / yes, figure out
 22077 00005E7F 0FB6D8              <1> 	movzx	ebx, al
 22078 00005E82 66C1E302            <1> 	shl	bx, 2
 22079                              <1> 		; asl r1
 22080 00005E86 81C3[8A5E0000]      <1>         add     ebx, iopen_1 - 4
 22081 00005E8C FF23                <1> 	jmp	dword [ebx]
 22082                              <1>         	; jmp *1f-2(r1) / which one and transfer to it
 22083                              <1> iopen_1: ; 1:
 22084 00005E8E [F45E0000]          <1> 	dd	otty ; tty, AX = 1 (runix)
 22085                              <1>  		 ;otty / tty ; r1=2
 22086                              <1>         	 ;oppt / ppt ; r1=4
 22087 00005E92 [915F0000]          <1> 	dd	sret ; mem, AX = 2 (runix)
 22088                              <1> 		 ;sret / mem ; r1=6
 22089                              <1> 		 ;sret / rf0
 22090                              <1>         	 ;sret / rk0
 22091                              <1>         	 ;sret / tap0
 22092                              <1>         	 ;sret / tap1
 22093                              <1>         	 ;sret / tap2
 22094                              <1>         	 ;sret / tap3
 22095                              <1>         	 ;sret / tap4
 22096                              <1>         	 ;sret / tap5
 22097                              <1>         	 ;sret / tap6
 22098                              <1>         	 ;sret / tap7
 22099 00005E96 [915F0000]          <1>         dd	sret ; fd0, AX = 3 (runix only)
 22100 00005E9A [915F0000]          <1>         dd	sret ; fd1, AX = 4 (runix only)
 22101 00005E9E [915F0000]          <1>         dd	sret ; hd0, AX = 5 (runix only)
 22102 00005EA2 [915F0000]          <1>         dd	sret ; hd1, AX = 6 (runix only) 
 22103 00005EA6 [915F0000]          <1>         dd	sret ; hd2, AX = 7 (runix only)
 22104 00005EAA [915F0000]          <1>         dd	sret ; hd3, AX = 8 (runix only) 
 22105                              <1> 	;dd	error ; lpr, AX = 9 (error !)
 22106 00005EAE [915F0000]          <1>         dd      sret ; lpr, AX = 9 (runix)
 22107 00005EB2 [035F0000]          <1> 	dd	ocvt ; tty0, AX = 10 (runix)	  
 22108                              <1> 		 ;ocvt / tty0
 22109 00005EB6 [035F0000]          <1> 	dd	ocvt ; tty1, AX = 11 (runix)	  
 22110                              <1> 		 ;ocvt / tty1
 22111 00005EBA [035F0000]          <1> 	dd	ocvt ; tty2, AX = 12 (runix)	  
 22112                              <1> 		 ;ocvt / tty2
 22113 00005EBE [035F0000]          <1> 	dd	ocvt ; tty3, AX = 13 (runix)	  
 22114                              <1> 		 ;ocvt / tty3
 22115 00005EC2 [035F0000]          <1> 	dd	ocvt ; tty4, AX = 14 (runix)	  
 22116                              <1> 		 ;ocvt / tty4
 22117 00005EC6 [035F0000]          <1> 	dd	ocvt ; tty5, AX = 15 (runix)	  
 22118                              <1> 		 ;ocvt / tty5
 22119 00005ECA [035F0000]          <1> 	dd	ocvt ; tty6, AX = 16 (runix)	  
 22120                              <1> 		 ;ocvt / tty6
 22121 00005ECE [035F0000]          <1> 	dd	ocvt ; tty7, AX = 17 (runix)	  
 22122                              <1> 		 ;ocvt / tty7
 22123 00005ED2 [035F0000]          <1> 	dd	ocvt ; COM1, AX = 18 (runix only)	  
 22124                              <1> 		 ;error / crd
 22125 00005ED6 [035F0000]          <1> 	dd	ocvt ; COM2, AX = 19 (runix only)
 22126                              <1> 
 22127                              <1> iopen_2: ; 2: / check open write access
 22128 00005EDA 66F7D8              <1> 	neg	ax
 22129                              <1> 		;neg r1 / make inode number positive
 22130 00005EDD B201                <1> 	mov	dl, 1 ; write access
 22131 00005EDF E8E3F8FFFF          <1> 	call	access
 22132                              <1> 		;jsr r0,access; 1 / get inode in core
 22133                              <1> 	; DL=1
 22134 00005EE4 66F705[26710000]00- <1> 	test	word [i.flgs], 4000h ; Bit 14 : Directory flag
 22135 00005EEC 40                  <1>
 22136                              <1>  		;bit $40000,i.flgs / is it a directory?
 22137 00005EED 7488                <1> 	jz	short iopen_0
 22138                              <1> 	;mov	[u.error], ERR_DIR_ACCESS
 22139                              <1> 	;jmp	error ; permission denied !
 22140 00005EEF E968FFFFFF          <1> 	jmp	sysmnt_err0
 22141                              <1> 	;;jnz	error		
 22142                              <1>        		; bne 2f / yes, transfer (error)
 22143                              <1>         ;;jmp     short iopen_0
 22144                              <1> 	;cmp	ax, 40
 22145                              <1> 		; cmp r1,$40. / no, is it a special file?
 22146                              <1>         ;ja	short iopen_2
 22147                              <1> 		 ;bgt 3f / no, return
 22148                              <1> 	;push	ax
 22149                              <1> 		;mov r1,-(sp) / yes
 22150                              <1> 	;movzx	ebx, al
 22151                              <1> 	;shl	bx, 1
 22152                              <1> 		; asl r1
 22153                              <1> 	;add	ebx, ipen_3 - 2
 22154                              <1> 	;jmp	dword [ebx]
 22155                              <1> 		; jmp *1f-2(r1) / figure out 
 22156                              <1> 			; / which special file it is and transfer
 22157                              <1> ;iopen_3: ; 1:
 22158                              <1> ;	dd 	otty ; tty, AX = 1 (runix)
 22159                              <1>  		 ;otty / tty ; r1=2
 22160                              <1>         	 ;leadr / ppt ; r1=4
 22161                              <1> ;	dd	sret ; mem, AX = 2 (runix)
 22162                              <1> 		 ;sret / mem ; r1=6
 22163                              <1> 		 ;sret / rf0
 22164                              <1>         	 ;sret / rk0
 22165                              <1>         	 ;sret / tap0
 22166                              <1>         	 ;sret / tap1
 22167                              <1>         	 ;sret / tap2
 22168                              <1>         	 ;sret / tap3
 22169                              <1>         	 ;sret / tap4
 22170                              <1>         	 ;sret / tap5
 22171                              <1>         	 ;sret / tap6
 22172                              <1>         	 ;sret / tap7
 22173                              <1> ;	dd 	sret ; fd0, AX = 3 (runix only)
 22174                              <1> ;	dd 	sret ; fd1, AX = 4 (runix only)
 22175                              <1> ;	dd 	sret ; hd0, AX = 5 (runix only)
 22176                              <1> ;	dd 	sret ; hd1, AX = 6 (runix only)	
 22177                              <1> ;	dd 	sret ; hd2, AX = 7 (runix only)
 22178                              <1> ;	dd 	sret ; hd3, AX = 8 (runix only)	
 22179                              <1> ;	dd	sret ; lpr, AX = 9  (runix)
 22180                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 22181                              <1> ;	dd	sret ; tty0, AX = 10 (runix)	  
 22182                              <1> 		 ;ocvt / tty0
 22183                              <1> ;	dd	sret ; tty1, AX = 11 (runix)	  
 22184                              <1> 		 ;ocvt / tty1
 22185                              <1> ;	dd	sret ; tty2, AX = 12 (runix)	  
 22186                              <1> 		 ;ocvt / tty2
 22187                              <1> ;	dd	sret ; tty3, AX = 13 (runix)	  
 22188                              <1> 		 ;ocvt / tty3
 22189                              <1> ;	dd	sret ; tty4, AX = 14 (runix)	  
 22190                              <1> 		 ;ocvt / tty4
 22191                              <1> ;	dd	sret ; tty5, AX = 15 (runix)	  
 22192                              <1> 		 ;ocvt / tty5
 22193                              <1> ;	dd	sret ; tty6, AX = 16 (runix)	  
 22194                              <1> 		 ;ocvt / tty6
 22195                              <1> ;	dd	sret ; tty7, AX = 17 (runix)	  
 22196                              <1> 		 ;ocvt / tty7
 22197                              <1> ;	dd	ocvt ; COM1, AX = 18 (runix only)	  
 22198                              <1> 		 ;/ ejec / lpr
 22199                              <1> ;	dd	ocvt ; COM2, AX = 19 (runix only)
 22200                              <1> 
 22201                              <1> 
 22202                              <1> otty: ;/ open console tty for reading or writing
 22203                              <1> 	; 16/11/2015
 22204                              <1> 	; 12/11/2015
 22205                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 22206                              <1> 	; 21/05/2013 - 13/07/2014 (Retro UNIX 8086 v1)
 22207                              <1> 	; 16/07/2013
 22208                              <1> 	; Retro UNIX 8086 v1 modification:
 22209                              <1> 	;  If a tty is open for read or write by
 22210                              <1> 	;     a process (u.uno), only same process can open
 22211                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 22212                              <1> 	;
 22213                              <1> 	; (INPUT: DL=2 for Read, DL=1 for Write, DL=0 for sysstty)
 22214                              <1> 	;
 22215 00005EF4 0FB61D[A1740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 22216 00005EFB 8A83[A5710000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 22217                              <1> 	; 13/01/2014
 22218 00005F01 EB02                <1> 	jmp	short ottyp
 22219                              <1> ocvt:
 22220 00005F03 2C0A                <1> 	sub	al, 10
 22221                              <1> ottyp:
 22222                              <1> 	; 16/11/2015
 22223                              <1> 	; 12/11/2015
 22224                              <1> 	; 18/05/2015 (32 bit modifications)
 22225                              <1> 	; 06/12/2013 - 13/07/2014
 22226 00005F05 88C6                <1> 	mov	dh, al ; tty number
 22227 00005F07 0FB6D8              <1> 	movzx 	ebx, al ; AL = tty number (0 to 9), AH = 0
 22228 00005F0A D0E3                <1> 	shl 	bl, 1  ; aligned to word
 22229                              <1> 	;26/01/2014	
 22230 00005F0C 81C3[C4700000]      <1> 	add 	ebx, ttyl
 22231 00005F12 668B0B              <1> 	mov 	cx, [ebx]
 22232                              <1> 		   ; CL = lock value (0 or process number)
 22233                              <1> 		   ; CH = open count 
 22234 00005F15 20C9                <1> 	and 	cl, cl
 22235                              <1> 	; 13/01/2014
 22236 00005F17 7439                <1> 	jz 	short otty_ret
 22237                              <1> 	;
 22238                              <1> 	; 16/11/2015
 22239 00005F19 3A0D[A1740000]      <1> 	cmp 	cl, [u.uno]
 22240 00005F1F 745C                <1> 	je	short ottys_3
 22241                              <1> 	;
 22242 00005F21 0FB6D9              <1> 	movzx 	ebx, cl ; the process which has locked the tty
 22243 00005F24 D0E3                <1> 	shl 	bl, 1
 22244 00005F26 668B83[44710000]    <1> 	mov 	ax, [ebx+p.pid-2]
 22245                              <1> 	;movzx 	ebx, byte [u.uno]
 22246 00005F2D 8A1D[A1740000]      <1> 	mov	bl, [u.uno]
 22247 00005F33 D0E3                <1> 	shl 	bl, 1
 22248 00005F35 663B83[64710000]    <1> 	cmp 	ax, [ebx+p.ppid-2]
 22249 00005F3C 743F                <1> 	je 	short ottys_3  ; 16/11/2015
 22250                              <1> 	;
 22251                              <1> 	; the tty is locked by another process
 22252                              <1> 	; except the parent process (p.ppid)
 22253                              <1>         ;
 22254 00005F3E C705[A7740000]0B00- <1> 	mov     dword [u.error], ERR_DEV_ACCESS
 22255 00005F46 0000                <1>
 22256                              <1> 			; permission denied ! error
 22257                              <1> otty_err: ; 13/01/2014
 22258 00005F48 08D2                <1> 	or 	dl, dl ; DL = 0 -> called by sysstty
 22259 00005F4A 0F85FDE0FFFF        <1> 	jnz	error
 22260 00005F50 F9                  <1> 	stc
 22261 00005F51 C3                  <1> 	retn
 22262                              <1> otty_ret: 
 22263                              <1> 	; 13/01/2014
 22264 00005F52 80FE07              <1> 	cmp 	dh, 7
 22265 00005F55 761C                <1> 	jna	short ottys_2
 22266                              <1> 	; 16/11/2015
 22267                              <1> com_port_check:
 22268 00005F57 BE[E2700000]        <1> 	mov	esi, com1p
 22269 00005F5C 80FE08              <1> 	cmp	dh, 8	; COM1 (tty8) ?
 22270 00005F5F 7601                <1> 	jna	short ottys_1 ; yes, it is COM1
 22271 00005F61 46                  <1> 	inc	esi	; no, it is COM2 (tty9)
 22272                              <1> ottys_1:
 22273                              <1> 	; 12/11/2015
 22274 00005F62 803E00              <1> 	cmp	byte [esi], 0 ; E3h (or 23h)
 22275 00005F65 770C                <1> 	ja	short com_port_ready
 22276                              <1> 	;
 22277 00005F67 C705[A7740000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY
 22278 00005F6F 0000                <1>
 22279                              <1> 			   ; device not ready ! error
 22280 00005F71 EBD5                <1> 	jmp	short otty_err	 
 22281                              <1> com_port_ready:
 22282                              <1> ottys_2:
 22283 00005F73 08C9                <1> 	or	cl, cl  ; cl = lock/owner, ch = open count
 22284 00005F75 7506                <1> 	jnz	short ottys_3
 22285 00005F77 8A0D[A1740000]      <1> 	mov	cl, [u.uno]
 22286                              <1> ottys_3:
 22287 00005F7D FEC5                <1> 	inc 	ch
 22288 00005F7F 66890B              <1> 	mov 	[ebx], cx ; set tty lock again
 22289                              <1> 	; 06/12/2013
 22290 00005F82 FEC6                <1> 	inc	dh ; tty number + 1
 22291 00005F84 BB[88740000]        <1> 	mov	ebx, u.ttyp
 22292                              <1> 	; 13/01/2014
 22293 00005F89 F6C202              <1> 	test	dl, 2 ; open for read sign
 22294 00005F8C 7501                <1> 	jnz	short ottys_4
 22295 00005F8E 43                  <1> 	inc	ebx
 22296                              <1> ottys_4:
 22297                              <1> 	; Set 'u.ttyp' ('the recent TTY') value
 22298 00005F8F 8833                <1> 	mov 	[ebx], dh ; tty number + 1
 22299                              <1> sret:
 22300 00005F91 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 22301 00005F93 7402                <1> 	jz	short iclose_retn
 22302 00005F95 6658                <1> 	pop 	ax
 22303                              <1> iclose_retn:	
 22304 00005F97 C3                  <1> 	retn
 22305                              <1> 
 22306                              <1> 	;
 22307                              <1> 	; Original UNIX v1 'otty' routine:
 22308                              <1> 	;	
 22309                              <1> 	;mov    $100,*$tks / set interrupt enable bit (zero others) in
 22310                              <1>         ;                 / reader status reg
 22311                              <1>         ;mov    $100,*$tps / set interrupt enable bit (zero others) in
 22312                              <1>         ;                 / punch status reg
 22313                              <1>         ;mov    tty+[ntty*8]-8+6,r5 / r5 points to the header of the
 22314                              <1>         ;                          / console tty buffer
 22315                              <1>         ;incb   (r5) / increment the count of processes that opened the
 22316                              <1>         ;            / console tty
 22317                              <1>         ;tst    u.ttyp / is there a process control tty (i.e., has a tty
 22318                              <1>         ;             / buffer header
 22319                              <1>         ;bne    sret / address been loaded into u.ttyp yet)?  yes, branch
 22320                              <1>         ;mov    r5,u.ttyp / no, make the console tty the process control
 22321                              <1>         ;                 / tty
 22322                              <1>         ;br     sret / ?
 22323                              <1> ;sret:
 22324                              <1> 		;clr *$ps / set processor priority to zero
 22325                              <1> ;	pop	ax
 22326                              <1>         	;mov (sp)+,r1 / pop stack to r1
 22327                              <1> ;3:
 22328                              <1> ;	retn
 22329                              <1>         	;rts r0
 22330                              <1> 	
 22331                              <1> ;ocvt:	; < open tty >
 22332                              <1> 	; 13/01/2014
 22333                              <1> 	; 06/12/2013 (major modification: p.ttyc, u.ttyp)
 22334                              <1> 	; 24/09/2013 consistency check -> ok
 22335                              <1> 	; 16/09/2013
 22336                              <1> 	; 03/09/2013
 22337                              <1> 	; 27/08/2013
 22338                              <1> 	; 16/08/2013
 22339                              <1> 	; 16/07/2013
 22340                              <1> 	; 27/05/2013
 22341                              <1> 	; 21/05/2013
 22342                              <1> 	;
 22343                              <1> 	; Retro UNIX 8086 v1 modification !
 22344                              <1> 	; 
 22345                              <1> 	; In original UNIX v1, 'ocvt' routine 
 22346                              <1> 	;		(exactly different than this one)
 22347                              <1> 	;	was in 'u9.s' file.
 22348                              <1> 	;
 22349                              <1> 	; 16/07/2013
 22350                              <1> 	; Retro UNIX 8086 v1 modification:
 22351                              <1> 	;  If a tty is open for read or write by
 22352                              <1> 	;     a process (u.uno), only same process can open
 22353                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 22354                              <1> 	;
 22355                              <1> 	; INPUT: DL=2 for Read DL=1 for Write
 22356                              <1> 
 22357                              <1> 	; 16/09/2013
 22358                              <1> 	; sub 	al, 10
 22359                              <1> 	
 22360                              <1> 	; 06/12/2013
 22361                              <1> 	;cmp	al, 7
 22362                              <1>         ;jna     short ottyp
 22363                              <1> 	; 13/01/2014
 22364                              <1> 	;jmp	short ottyp
 22365                              <1> 
 22366                              <1> 
 22367                              <1> ;oppt: / open paper tape for reading or writing
 22368                              <1> ;        mov    $100,*$prs / set reader interrupt enable bit
 22369                              <1> ;        tstb   pptiflg / is file already open
 22370                              <1> ;        bne    2f / yes, branch
 22371                              <1> ;1:
 22372                              <1> ;        mov    $240,*$ps / no, set processor priority to 5
 22373                              <1> ;        jsr    r0,getc; 2 / remove all entries in clist
 22374                              <1> ;               br .+4 / for paper tape input and place in free list
 22375                              <1> ;        br     1b
 22376                              <1> ;        movb   $2,pptiflg / set pptiflg to indicate file just open
 22377                              <1> ;        movb   $10.,toutt+1 / place 10 in paper tape input tout entry
 22378                              <1> ;        br     sret
 22379                              <1> ;2:
 22380                              <1> ;        jmp    error / file already open
 22381                              <1> 
 22382                              <1> iclose: 
 22383                              <1> 	; 19/05/2015
 22384                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 22385                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 22386                              <1> 	;
 22387                              <1> 	; close file whose i-number is in r1
 22388                              <1> 	; 
 22389                              <1> 	; INPUTS ->
 22390                              <1> 	;    r1 - inode number
 22391                              <1> 	; OUTPUTS ->
 22392                              <1> 	;    file's inode in core	
 22393                              <1> 	;    r1 - inode number (positive)
 22394                              <1> 	;
 22395                              <1> 	; ((AX = R1))
 22396                              <1>         ;    ((Modified registers: -ebx-, edx)) 
 22397                              <1> 	;        
 22398                              <1> ;/ close file whose i-number is in r1
 22399 00005F98 B202                <1> 	mov	dl, 2 ; 12/01/2014
 22400 00005F9A F6C480              <1> 	test	ah, 80h ; Bit 15 of AX
 22401                              <1> 		;tst r1 / test i-number
 22402                              <1>         ;jnz	short iclose_2
 22403                              <1> 		;blt 2f / if neg., branch
 22404 00005F9D 7405                <1> 	jz	short iclose_0 ; 30/07/2013
 22405                              <1> 	; 16/07/2013 
 22406 00005F9F 66F7D8              <1> 	neg	ax ; make it positive
 22407                              <1> 	; 12/01/2014
 22408 00005FA2 FECA                <1> 	dec	dl ; dl = 1 (open for write)
 22409                              <1> iclose_0:
 22410 00005FA4 6683F828            <1> 	cmp	ax, 40
 22411                              <1> 		;cmp r1,$40. / is it a special file
 22412 00005FA8 77ED                <1>         ja	short iclose_retn  ; 13/01/2014
 22413                              <1> 		;bgt 3b / no, return
 22414                              <1> 	; 12/01/2014
 22415                              <1> 	; DL=2 -> special file was opened for reading
 22416                              <1> 	; DL=1 -> special file was opened for writing
 22417 00005FAA 6650                <1> 	push	ax
 22418                              <1> 		;mov r1,-(sp) / yes, save r1 on stack
 22419 00005FAC 0FB6D8              <1> 	movzx	ebx, al
 22420 00005FAF 66C1E302            <1> 	shl	bx, 2
 22421                              <1> 		; asl r1
 22422 00005FB3 81C3[B75F0000]      <1> 	add	ebx, iclose_1 - 4
 22423 00005FB9 FF23                <1> 	jmp	dword [ebx]
 22424                              <1> 		; jmp *1f-2(r1) / compute jump address and transfer
 22425                              <1> iclose_1 :
 22426 00005FBB [07600000]          <1> 	dd	ctty ; tty, AX = 1 (runix)
 22427 00005FBF [58600000]          <1> 	dd	cret ; mem, AX = 2 (runix)
 22428 00005FC3 [58600000]          <1> 	dd	cret ; fd0, AX = 3 (runix only)
 22429 00005FC7 [58600000]          <1> 	dd	cret ; fd1, AX = 4 (runix only)
 22430 00005FCB [58600000]          <1> 	dd	cret ; hd0, AX = 5 (runix only)
 22431 00005FCF [58600000]          <1> 	dd	cret ; hd1, AX = 6 (runix only)	
 22432 00005FD3 [58600000]          <1> 	dd	cret ; hd2, AX = 7 (runix only)
 22433 00005FD7 [58600000]          <1> 	dd	cret ; hd3, AX = 8 (runix only)	
 22434 00005FDB [58600000]          <1> 	dd	cret ; lpr, AX = 9 (runix)
 22435                              <1> 	;dd	error; lpr, AX = 9 (error !)
 22436                              <1> 	;;dd	offset ejec ;;lpr, AX = 9  
 22437 00005FDF [16600000]          <1> 	dd	ccvt ; tty0, AX = 10 (runix)	  
 22438 00005FE3 [16600000]          <1> 	dd	ccvt ; tty1, AX = 11 (runix)	  
 22439 00005FE7 [16600000]          <1> 	dd	ccvt ; tty2, AX = 12 (runix)	  
 22440 00005FEB [16600000]          <1> 	dd	ccvt ; tty3, AX = 13 (runix)	  
 22441 00005FEF [16600000]          <1> 	dd	ccvt ; tty4, AX = 14 (runix)	  
 22442 00005FF3 [16600000]          <1> 	dd	ccvt ; tty5, AX = 15 (runix)	  
 22443 00005FF7 [16600000]          <1> 	dd	ccvt ; tty6, AX = 16 (runix)	  
 22444 00005FFB [16600000]          <1> 	dd	ccvt ; tty7, AX = 17 (runix)	  
 22445 00005FFF [16600000]          <1> 	dd	ccvt ; COM1, AX = 18 (runix only)	  
 22446 00006003 [16600000]          <1> 	dd	ccvt ; COM2, AX = 19 (runix only)
 22447                              <1> 
 22448                              <1> 	; 1:
 22449                              <1> 	;        ctty   / tty
 22450                              <1> 	;        cppt   / ppt
 22451                              <1> 	;        sret   / mem
 22452                              <1> 	;        sret   / rf0
 22453                              <1> 	;        sret   / rk0
 22454                              <1> 	;        sret   / tap0
 22455                              <1> 	;        sret   / tap1
 22456                              <1> 	;        sret   / tap2
 22457                              <1> 	;        sret   / tap3
 22458                              <1> 	;        sret   / tap4
 22459                              <1> 	;        sret   / tap5
 22460                              <1> 	;        sret   / tap6
 22461                              <1> 	;        sret   / tap7
 22462                              <1> 	;        ccvt   / tty0
 22463                              <1> 	;        ccvt   / tty1
 22464                              <1> 	;        ccvt   / tty2
 22465                              <1> 	;        ccvt   / tty3
 22466                              <1> 	;        ccvt   / tty4
 22467                              <1> 	;        ccvt   / tty5
 22468                              <1> 	;        ccvt   / tty6
 22469                              <1> 	;        ccvt   / tty7
 22470                              <1> 	;        error / crd
 22471                              <1> 
 22472                              <1> ;iclose_2: ; 2: / negative i-number
 22473                              <1> 	;neg	ax
 22474                              <1> 		;neg r1 / make it positive
 22475                              <1> 	;cmp	ax, 40
 22476                              <1> 		;cmp r1,$40. / is it a special file?
 22477                              <1>         ;ja	short @b
 22478                              <1> 		;bgt    3b / no. return
 22479                              <1> 	;push	ax
 22480                              <1> 		;mov r1,-(sp)
 22481                              <1> 	;movzx	ebx, al
 22482                              <1> 	;shl	bx, 1
 22483                              <1> 		;asl r1 / yes. compute jump address and transfer
 22484                              <1> 	;add	ebx, iclose_3 - 2
 22485                              <1> 	;jmp	dword [ebx]
 22486                              <1> 		;jmp *1f-2(r1) / figure out 
 22487                              <1> ;iclose_3:
 22488                              <1> 	;dd	ctty ; tty, AX = 1 (runix)
 22489                              <1> 	;dd	sret ; mem, AX = 2 (runix)
 22490                              <1> 	;dd	sret ; fd0, AX = 3 (runix only)
 22491                              <1> 	;dd	sret ; fd1, AX = 4 (runix only)
 22492                              <1> 	;dd	sret ; hd0, AX = 5 (runix only)
 22493                              <1> 	;dd	sret ; hd1, AX = 6 (runix only)	
 22494                              <1> 	;dd	sret ; hd2, AX = 7 (runix only)
 22495                              <1> 	;dd	sret ; hd3, AX = 8 (runix only)
 22496                              <1> 	 ;dd	sret ; lpr, AX = 9	
 22497                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 22498                              <1> 	;dd	ccvt ; tty0, AX = 10 (runix)	  
 22499                              <1> 	;dd	ccvt ; tty1, AX = 11 (runix)	  
 22500                              <1> 	;dd	ccvt ; tty2, AX = 12 (runix)	  
 22501                              <1> 	;dd	ccvt ; tty3, AX = 13 (runix)	  
 22502                              <1> 	;dd	ccvt ; tty4, AX = 14 (runix)	  
 22503                              <1> 	;dd	ccvt ; tty5, AX = 15 (runix)	  
 22504                              <1> 	;dd	ccvt ; tty6, AX = 16 (runix)	  
 22505                              <1> 	;dd	ccvt ; tty7, AX = 17 (runix)	  
 22506                              <1> 	;dd	ccvt ; COM1, AX = 18 (runix only)	  
 22507                              <1> 	;dd	ccvt ; COM2, AX = 19 (runix only) 
 22508                              <1> 	
 22509                              <1> 	;1:
 22510                              <1> 	;      	ctty   / tty
 22511                              <1> 	;       leadr  / ppt
 22512                              <1> 	;       sret   / mem
 22513                              <1> 	;       sret   / rf0
 22514                              <1> 	;       sret   / rk0
 22515                              <1> 	;       sret   / tap0
 22516                              <1> 	;       sret   / tap1
 22517                              <1> 	;       sret   / tap2
 22518                              <1> 	;       sret   / tap3
 22519                              <1> 	;       sret   / tap4
 22520                              <1> 	;       sret   / tap5
 22521                              <1> 	;       sret   / tap6
 22522                              <1> 	;       sret   / tap7
 22523                              <1> 	;       ccvt   / tty0
 22524                              <1> 	;       ccvt   / tty1
 22525                              <1> 	;       ccvt   / tty2
 22526                              <1> 	;       ccvt   / tty3
 22527                              <1> 	;       ccvt   / tty4
 22528                              <1> 	;       ccvt   / tty5
 22529                              <1> 	;       ccvt   / tty6
 22530                              <1> 	;       ccvt   / tty7
 22531                              <1> 	;/       ejec / lpr
 22532                              <1> 
 22533                              <1> ctty: ; / close console tty
 22534                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 22535                              <1> 	; 21/05/2013 - 26/01/2014 (Retro UNIX 8086 v1)
 22536                              <1> 	;
 22537                              <1> 	; Retro UNIX 8086 v1 modification !
 22538                              <1> 	; (DL = 2 -> it is open for reading)
 22539                              <1> 	; (DL = 1 -> it is open for writing)
 22540                              <1> 	; (DL = 0 -> it is open for sysstty system call)
 22541                              <1> 	;
 22542                              <1> 	; 06/12/2013
 22543 00006007 0FB61D[A1740000]    <1>         movzx   ebx, byte [u.uno] ; process number
 22544 0000600E 8A83[A5710000]      <1>         mov     al, [ebx+p.ttyc-1]
 22545                              <1> 	; 13/01/2014
 22546 00006014 EB02                <1> 	jmp	short cttyp
 22547                              <1> ccvt:
 22548 00006016 2C0A                <1> 	sub 	al, 10
 22549                              <1> cttyp:	
 22550                              <1> 	; 18/05/2015 (32 bit modifications)
 22551                              <1> 	; 16/08/2013 - 26/01/2014
 22552 00006018 0FB6D8              <1> 	movzx 	ebx, al ; tty number (0 to 9)
 22553 0000601B D0E3                <1> 	shl 	bl, 1  ; aligned to word	
 22554                              <1> 	; 26/01/2014
 22555 0000601D 81C3[C4700000]      <1> 	add 	ebx, ttyl
 22556 00006023 88C6                <1> 	mov 	dh, al ; tty number
 22557 00006025 668B03              <1> 	mov 	ax, [ebx]
 22558                              <1> 		   ; AL = lock value (0 or process number)
 22559                              <1> 		   ; AH = open count 
 22560 00006028 20E4                <1> 	and 	ah, ah
 22561 0000602A 750F                <1> 	jnz	short ctty_ret
 22562 0000602C C705[A7740000]0A00- <1>         mov     dword [u.error], ERR_DEV_NOT_OPEN
 22563 00006034 0000                <1>
 22564                              <1> 			; device not open ! error
 22565                              <1> 	;jmp 	short ctty_err ; open count = 0, it is not open !
 22566 00006036 E912E0FFFF          <1> 	jmp	error
 22567                              <1> 	; 26/01/2014
 22568                              <1> ctty_ret:
 22569 0000603B FECC                <1> 	dec 	ah ; decrease open count
 22570 0000603D 7502                <1> 	jnz	short ctty_1
 22571 0000603F 30C0                <1> 	xor	al, al ; unlock/free tty
 22572                              <1> ctty_1:
 22573 00006041 668903              <1> 	mov 	[ebx], ax ; close tty instance
 22574                              <1> 	;
 22575 00006044 BB[88740000]        <1> 	mov	ebx, u.ttyp
 22576 00006049 F6C201              <1> 	test	dl, 1 ; open for write sign
 22577 0000604C 7401                <1> 	jz	short ctty_2
 22578 0000604E 43                  <1> 	inc	ebx
 22579                              <1> ctty_2:
 22580 0000604F FEC6                <1> 	inc	dh ; tty number + 1
 22581 00006051 3A33                <1> 	cmp	dh, [ebx]
 22582 00006053 7503                <1> 	jne	short cret
 22583                              <1> 	; Reset/Clear 'u.ttyp' ('the recent TTY') value
 22584 00006055 C60300              <1> 	mov	byte [ebx], 0
 22585                              <1> cret:
 22586 00006058 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 22587 0000605A 7402                <1> 	jz	short ctty_3
 22588 0000605C 6658                <1> 	pop	ax
 22589                              <1> ctty_3:
 22590 0000605E C3                  <1> 	retn
 22591                              <1> 
 22592                              <1> ;ctty_err: ; 13/01/2014
 22593                              <1> ;	or 	dl, dl ; DL = 0 -> called by sysstty
 22594                              <1> ;	jnz	error
 22595                              <1> ;	stc
 22596                              <1> ;	retn
 22597                              <1> 
 22598                              <1> 
 22599                              <1> 	; Original UNIX v1 'ctty' routine:
 22600                              <1> 	;	
 22601                              <1>         ;mov    tty+[ntty*8]-8+6,r5 
 22602                              <1> 	;		;/ point r5 to the console tty buffer
 22603                              <1>         ;decb   (r5) / dec number of processes using console tty
 22604                              <1>         ;br     sret / return via sret
 22605                              <1> 
 22606                              <1> ;ccvt:	; < close tty >
 22607                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 22608                              <1> 	;
 22609                              <1> 	; Retro UNIX 8086 v1 modification !
 22610                              <1> 	; 
 22611                              <1> 	; In original UNIX v1, 'ccvt' routine 
 22612                              <1> 	;		(exactly different than this one)
 22613                              <1> 	;	was in 'u9.s' file.
 22614                              <1> 	;
 22615                              <1> 	; DL = 2 -> it is open for reading
 22616                              <1> 	; DL = 1 -> it is open for writing
 22617                              <1> 	;
 22618                              <1> 	; 17/09/2013
 22619                              <1> 	;sub 	al, 10
 22620                              <1> 	;cmp	al, 7
 22621                              <1> 	;jna	short cttyp
 22622                              <1> 	; 13/01/2014
 22623                              <1> 	;jmp	short cttyp
 22624                              <1> 
 22625                              <1> ;cppt: / close paper tape
 22626                              <1> ;        clrb   pptiflg / set pptiflg to indicate file not open
 22627                              <1> ;1:
 22628                              <1> ;        mov    $240,*$ps /set process or priority to 5
 22629                              <1> ;        jsr    r0,getc; 2 / remove all ppt input entries from clist
 22630                              <1> ;                          / and assign to free list
 22631                              <1> ;               br sret
 22632                              <1> ;        br     1b
 22633                              <1> 
 22634                              <1> ;ejec:	
 22635                              <1> ;	jmp	error
 22636                              <1> ;/ejec:
 22637                              <1> ;/       mov    $100,*$lps / set line printer interrupt enable bit
 22638                              <1> ;/       mov    $14,r1 / 'form feed' character in r1 (new page).
 22639                              <1> ;/       jsr    r0,lptoc / space the printer to a new page
 22640                              <1> ;/       br     sret / return to caller via 'sret'
 22641                                  %include 'u8.s'        ; 11/06/2015
 22642                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS8.INC
 22643                              <1> ; Last Modification: 24/10/2015
 22644                              <1> ; ----------------------------------------------------------------------------
 22645                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 22646                              <1> ; (v0.1 - Beginning: 11/07/2012)
 22647                              <1> ;
 22648                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 22649                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 22650                              <1> ; <Bell Laboratories (17/3/1972)>
 22651                              <1> ; <Preliminary Release of UNIX Implementation Document>
 22652                              <1> ;
 22653                              <1> ; Retro UNIX 8086 v1 - U8.ASM (18/01/2014) //// UNIX v1 -> u8.s
 22654                              <1> ;
 22655                              <1> ; ****************************************************************************
 22656                              <1> 
 22657                              <1> ;; I/O Buffer - Retro UNIX 386 v1 modification
 22658                              <1> ;;     (8+512 bytes, 8 bytes header, 512 bytes data)
 22659                              <1> ;; Word 1, byte 0 = device id
 22660                              <1> ;; Word 1, byte 1 = status bits (bits 8 to 15)
 22661                              <1> ;;          bit 9 = write bit
 22662                              <1> ;;	    bit 10 = read bit	  
 22663                              <1> ;;	    bit 12 = waiting to write bit	
 22664                              <1> ;;	    bit 13 = waiting to read bit
 22665                              <1> ;;	    bit 15 = inhibit bit
 22666                              <1> ;; Word 2 (byte 2 & byte 3) = reserved (for now - 07/06/2015)
 22667                              <1> ;; Word 3 + Word 4 (byte 4,5,6,7) = physical block number 
 22668                              <1> ;;		   (In fact, it is 32 bit LBA for Retro UNIX 386 v1)
 22669                              <1> ;;
 22670                              <1> ;; I/O Buffer ((8+512 bytes in original Unix v1))
 22671                              <1> ;;	      ((4+512 bytes in Retro UNIX 8086 v1))
 22672                              <1> ;;
 22673                              <1> ;; I/O Queue Entry (of original UNIX operating system v1)
 22674                              <1> ;; Word 1, Byte 0 = device id
 22675                              <1> ;; Word 1, Byte 1 = (bits 8 to 15)
 22676                              <1> ;;          bit 9 = write bit
 22677                              <1> ;;	    bit 10 = read bit	  
 22678                              <1> ;;	    bit 12 = waiting to write bit	
 22679                              <1> ;;	    bit 13 = waiting to read bit
 22680                              <1> ;;	    bit 15 = inhibit bit
 22681                              <1> ;; Word 2 = physical block number (In fact, it is LBA for Retro UNIX 8086 v1)
 22682                              <1> ;;
 22683                              <1> ;; Original UNIX v1 ->
 22684                              <1> ;;		Word 3 = number of words in buffer (=256) 		
 22685                              <1> ;; Original UNIX v1 -> 
 22686                              <1> ;;		Word 4 = bus address (addr of first word of data buffer)
 22687                              <1> ;;
 22688                              <1> ;; Retro UNIX 8086 v1 -> Buffer Header (I/O Queue Entry) size is 4 bytes !
 22689                              <1> ;;
 22690                              <1> ;; Device IDs (of Retro Unix 8086 v1)
 22691                              <1> ;;          0 = fd0
 22692                              <1> ;;	    1 = fd1
 22693                              <1> ;;	    2 = hd0
 22694                              <1> ;;	    3 = hd1
 22695                              <1> ;;	    4 = hd2
 22696                              <1> ;;	    5 = hd3
 22697                              <1> 
 22698                              <1> ; Retro UNIX 386 v1 - 32 bit modifications (rfd, wfd, rhd, whd) - 09/06/2015
 22699                              <1> 
 22700                              <1> rfd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22701                              <1> 	; 26/04/2013
 22702                              <1>    	; 13/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 22703                              <1>    	;sub 	ax, 3 ; zero based device number (Floppy disk)
 22704                              <1>       	;jmp 	short bread ; **** returns to routine that called readi			
 22705                              <1> 
 22706                              <1> rhd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22707                              <1> 	; 26/04/2013
 22708                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 22709                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 22710                              <1>    	;jmp	short bread ; **** returns to routine that called readi	
 22711                              <1> 
 22712                              <1> bread: 
 22713                              <1> 	; 14/07/2015
 22714                              <1> 	; 10/07/2015
 22715                              <1> 	; 09/06/2015
 22716                              <1> 	; 07/06/2015 (Retro UNIX 386 v1 - Beginning)
 22717                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 22718                              <1> 	;	
 22719                              <1> 	; / read a block from a block structured device
 22720                              <1> 	;
 22721                              <1> 	; INPUTS ->
 22722                              <1> 	;    [u.fopf] points to the block number
 22723                              <1> 	;    CX = maximum block number allowed on device
 22724                              <1> 	;	 ; that was an arg to bread, in original Unix v1, but
 22725                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 22726                              <1> 	;    [u.count]	number of bytes to read in
 22727                              <1> 	; OUTPUTS ->
 22728                              <1> 	;    [u.base] starting address of data block or blocks in user area  	
 22729                              <1> 	;    [u.fopf] points to next consecutive block to be read
 22730                              <1> 	;
 22731                              <1> 	; ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))
 22732                              <1> 	;
 22733                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if read
 22734                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 22735                              <1> 	;	is increased by 1. For example: If user/program request 
 22736                              <1> 	;       to read 16 bytes in current block, 'sys read' increases
 22737                              <1> 	;  	the next block number just as 512 byte reading is done.
 22738                              <1> 	;       This wrong is done in 'bread'. So, in Retro UNIX 8086 v1, 
 22739                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 22740                              <1> 	;       enough to keep byte position/offset of the disk), this
 22741                              <1> 	;	defect will not be corrected, user/program must request
 22742                              <1> 	;	512 byte read per every 'sys read' call to block devices
 22743                              <1> 	;       for achieving correct result. In future version(s), 
 22744                              <1> 	;	this defect will be corrected by using different 
 22745                              <1> 	;       user (u) structure.  26/07/2013 - Erdogan Tan 	
 22746                              <1> 
 22747                              <1> 	   	; jsr r0,tstdeve / error on special file I/O 
 22748                              <1> 			       ; / (only works on tape)
 22749                              <1> 		; mov *u.fofp,r1 / move block number to r1
 22750                              <1> 		; mov $2.-cold,-(sp) / "2-cold" to stack
 22751                              <1> ;1:
 22752                              <1> 		; cmp r1,(r0) / is this block # greater than or equal to
 22753                              <1> 			    ; / maximum block # allowed on device
 22754                              <1> 		; jnb short @f
 22755                              <1> 		; bhis	1f / yes, 1f (error)
 22756                              <1> 		; mov r1,-(sp) / no, put block # on stack
 22757                              <1> 		; jsr r0,preread / read in the block into an I/O buffer
 22758                              <1> 		; mov (sp)+,r1 / return block # to r1
 22759                              <1> 		; inc r1 / bump block # to next consecutive block
 22760                              <1> 		; dec (sp) / "2-1-cold" on stack
 22761                              <1> 		; bgt 1b / 2-1-cold = 0?  No, go back and read in next block
 22762                              <1> ;1:
 22763                              <1> 		; tst (sp)+ / yes, pop stack to clear off cold calculation
 22764                              <1> 	;push	ecx ; **
 22765                              <1> 	;26/04/2013
 22766                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 22767 0000605F 2C03                <1> 	sub	al, 3
 22768                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 22769 00006061 A2[BA740000]        <1> 	mov	[u.brwdev], al
 22770                              <1> 	; 09/06/2015
 22771 00006066 0FB6D8              <1> 	movzx	ebx, al
 22772 00006069 8B8B[5E6B0000]      <1> 	mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 22773                              <1> bread_0:
 22774 0000606F 51                  <1> 	push	ecx ; ** ; 09/06/2015 
 22775                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 22776                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 22777 00006070 8B1D[68740000]      <1> 	mov	ebx, [u.fofp]
 22778 00006076 8B03                <1> 	mov	eax, [ebx]
 22779 00006078 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 22780                              <1> 		; mov *u.fofp,r1 / restore r1 to initial value of the
 22781                              <1> 			       ; / block #
 22782 0000607B 39C8                <1> 	cmp	eax, ecx
 22783                              <1> 		; cmp r1,(r0)+ / block # greater than or equal to maximum
 22784                              <1>        	                     ; / block number allowed
 22785                              <1> 	;jnb	error 	     ; 18/04/2013
 22786                              <1> 		; bhis error10 / yes, error
 22787 0000607D 720F                <1> 	jb	short bread_1
 22788 0000607F C705[A7740000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error	
 22789 00006087 0000                <1>
 22790 00006089 E9BFDFFFFF          <1> 	jmp	error
 22791                              <1> bread_1:
 22792                              <1> 	; inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 22793                              <1> 		; inc *u.fofp / no, *u.fofp has next block number
 22794                              <1> 	; eAX = Block number (zero based)
 22795                              <1> 		;;jsr r0,preread / read in the block whose number is in r1
 22796                              <1> preread: ;; call preread
 22797 0000608E BF[BA740000]        <1> 	mov	edi, u.brwdev ; block device number for direct I/O
 22798 00006093 E864020000          <1> 	call	bufaloc_0 ; 26/04/2013
 22799                              <1> 	;; jc 	error
 22800                              <1> 	; eBX = Buffer (Header) Address -Physical-
 22801                              <1>         ; eAX = Block/Sector number (r1)
 22802                              <1> 	       ; jsr r0,bufaloc / get a free I/O buffer (r1 has block number)
 22803                              <1> 	; 14/03/2013
 22804 00006098 740A                <1>         jz	short bread_2 ; Retro UNIX 8086 v1 modification
 22805                              <1>        		; br 1f / branch if block already in a I/O buffer
 22806 0000609A 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 22807                              <1>         	; bis $2000,(r5) / set read bit (bit 10 in I/O buffer)
 22808 0000609F E8B3010000          <1> 	call	poke
 22809                              <1>         	; jsr r0,poke / perform the read
 22810                              <1> 	;;jc	error ;2 0/07/2013
 22811                              <1> ; 1:
 22812                              <1>  		; clr *$ps / ps = 0
 22813                              <1>         	; rts r0
 22814                              <1> ;; return from preread
 22815                              <1> bread_2:
 22816 000060A4 66810B0040          <1> 	or	word [ebx], 4000h 
 22817                              <1> 		; bis $40000,(r5) 
 22818                              <1> 			; / set bit 14 of the 1st word of the I/O buffer
 22819                              <1> bread_3: ; 1:
 22820 000060A9 66F7030024          <1> 	test	word [ebx], 2400h
 22821                              <1> 		; bit $22000,(r5) / are 10th and 13th bits set (read bits)
 22822 000060AE 7407                <1> 	jz	short bread_4
 22823                              <1> 		; beq 1f / no
 22824                              <1> 		; cmp cdev,$1 / disk or drum?
 22825                              <1> 		; ble 2f / yes
 22826                              <1> 		; tstb uquant / is the time quantum = 0?
 22827                              <1> 		; bne 2f / no, 2f
 22828                              <1> 		; mov r5,-(sp) / yes, save r5 (buffer address)
 22829                              <1> 		; jsr r0,sleep; 31. 
 22830                              <1> 			; / put process to sleep in channel 31 (tape)
 22831                              <1> 		; mov (sp)+,r5 / restore r5
 22832                              <1> 		; br 1b / go back
 22833                              <1> ; 2: / drum or disk
 22834                              <1>         ;; mov     cx, [s.wait_]+2 ;; 29/07/2013
 22835 000060B0 E8AAF3FFFF          <1> 	call	idle
 22836                              <1> 		; jsr r0,idle; s.wait+2 / wait
 22837 000060B5 EBF2                <1> 	jmp	short bread_3
 22838                              <1>        		; br 1b
 22839                              <1> bread_4: ; 1: / 10th and 13th bits not set
 22840 000060B7 668123FFBF          <1> 	and	word [ebx], 0BFFFh ; 1011111111111111b
 22841                              <1> 		; bic $40000,(r5) / clear bit 14
 22842                              <1>        		; jsr r0,tstdeve / test device for error (tape)
 22843 000060BC 83C308              <1> 	add	ebx, 8
 22844                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 22845                              <1> 	; 09/06/2015
 22846 000060BF 66833D[B7740000]00  <1> 	cmp	word [u.pcount], 0
 22847 000060C7 7705                <1> 	ja	short bread_5
 22848 000060C9 E896F9FFFF          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 22849                              <1> bread_5:
 22850                              <1> 	; eBX = system (I/O) buffer address
 22851 000060CE E870000000          <1> 	call	dioreg
 22852                              <1>        		; jsr r0,dioreg / do bookkeeping on u.count etc.
 22853                              <1> 	; esi =  start address of the transfer (in the buffer)
 22854                              <1> 	; edi =  [u.pbase], destination address in user's memory space
 22855                              <1> 	; ecx =  transfer count (in bytes)
 22856                              <1> 	;
 22857                              <1> ;1: / r5 points to beginning of data in I/O buffer, r2 points to beginning
 22858                              <1> ;   / of users data
 22859 000060D3 F3A4                <1> 	rep	movsb
 22860                              <1> 		; movb (r5)+,(r2)+ / move data from the I/O buffer
 22861                              <1>        		; dec r3 / to the user's area in core starting at u.base
 22862                              <1>        		; bne 1b
 22863 000060D5 59                  <1> 	pop	ecx ; **
 22864 000060D6 833D[7C740000]00    <1> 	cmp	dword [u.count], 0
 22865                              <1> 		; tst u.count / done
 22866 000060DD 7790                <1> 	ja	short bread_0 ; 09/06/2015
 22867                              <1>        		; beq 1f / yes, return
 22868                              <1> 		; tst -(r0) / no, point r0 to the argument again
 22869                              <1>        		; br bread / read some more
 22870                              <1> ; 1:
 22871 000060DF 58                  <1> 	pop	eax ; ****
 22872                              <1>        		; mov (sp)+,r0
 22873 000060E0 C3                  <1>         retn		; 09/06/2015
 22874                              <1> 	;jmp     ret_ 
 22875                              <1> 		;jmp ret  / jump to routine that called readi
 22876                              <1> 
 22877                              <1> wfd:    ; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22878                              <1> 	; 26/04/2013
 22879                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 22880                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 22881                              <1>    	;jmp	short bwrite ; **** returns to routine that called writei
 22882                              <1> 				
 22883                              <1> whd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22884                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 22885                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 22886                              <1>    	;jmp 	short bwrite ; **** returns to routine that called writei ('jmp ret')
 22887                              <1> 
 22888                              <1> bwrite: 
 22889                              <1> 	; 14/07/2015
 22890                              <1> 	; 10/07/2015
 22891                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22892                              <1> 	; 14/03/2013 - 20/07/2013 (Retro UNIX 8086 v1)
 22893                              <1> 	;	
 22894                              <1> 	;; / write on block structured device
 22895                              <1> 	;
 22896                              <1> 	; INPUTS ->
 22897                              <1> 	;    [u.fopf] points to the block number
 22898                              <1> 	;    CX = maximum block number allowed on device
 22899                              <1> 	;	 ; that was an arg to bwrite, in original Unix v1, but
 22900                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 22901                              <1> 	;    [u.count]	number of bytes to user desires to write
 22902                              <1> 	; OUTPUTS ->
 22903                              <1> 	;    [u.fopf] points to next consecutive block to be written into
 22904                              <1> 	;
 22905                              <1> 	; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))
 22906                              <1> 	;
 22907                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if write
 22908                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 22909                              <1> 	;	is increased by 1. For example: If user/program request 
 22910                              <1> 	;       to write 16 bytes in current block, 'sys write' increases
 22911                              <1> 	;  	the next block number just as 512 byte writing is done.
 22912                              <1> 	;       This wrong is done in 'bwrite'. So, in Retro UNIX 8086 v1, 
 22913                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 22914                              <1> 	;       enough to keep byte position/offset of the disk), this
 22915                              <1> 	;	defect will not be corrected, user/program must request
 22916                              <1> 	;	512 byte write per every 'sys write' call to block devices
 22917                              <1> 	;       for achieving correct result. In future version(s), 
 22918                              <1> 	;	this defect will be corrected by using different 
 22919                              <1> 	;       user (u) structure.  26/07/2013 - Erdogan Tan 	
 22920                              <1> 
 22921                              <1>        		; jsr r0,tstdeve / test the device for an error
 22922                              <1> 	;push	ecx ; **
 22923                              <1> 	;26/04/2013
 22924                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 22925 000060E1 2C03                <1> 	sub	al, 3
 22926                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 22927 000060E3 A2[BA740000]        <1> 	mov	[u.brwdev], al
 22928                              <1> 	; 09/06/2015
 22929 000060E8 0FB6D8              <1> 	movzx	ebx, al
 22930 000060EB 8B8B[5E6B0000]      <1> 	mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 22931                              <1> bwrite_0:
 22932 000060F1 51                  <1> 	push	ecx ; ** ; 09/06/2015
 22933                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 22934                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 22935 000060F2 8B1D[68740000]      <1> 	mov	ebx, [u.fofp]
 22936 000060F8 8B03                <1> 	mov	eax, [ebx]       
 22937 000060FA C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 22938                              <1> 		; mov *u.fofp,r1 / put the block number in r1
 22939 000060FD 39C8                <1> 	cmp	eax, ecx
 22940                              <1> 		; cmp r1,(r0)+ / does block number exceed maximum allowable #
 22941                              <1>        	                     ; / block number allowed
 22942                              <1> 	;jnb	error	     ; 18/04/2013
 22943                              <1> 		; bhis error10 / yes, error
 22944 000060FF 720F                <1>      	jb	short bwrite_1
 22945 00006101 C705[A7740000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error	
 22946 00006109 0000                <1>
 22947 0000610B E93DDFFFFF          <1> 	jmp	error
 22948                              <1> bwrite_1:
 22949                              <1> 	; inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 22950                              <1> 		; inc *u.fofp / no, increment block number
 22951                              <1> 	; 09/06/2015 - 10/07/2015
 22952 00006110 66833D[B7740000]00  <1> 	cmp	word [u.pcount], 0
 22953 00006118 7705                <1> 	ja	short bwrite_2
 22954 0000611A E841F9FFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 22955                              <1> bwrite_2:
 22956 0000611F BF[BA740000]        <1> 	mov	edi, u.brwdev  ; block device number for direct I/O
 22957 00006124 E8C4000000          <1>        	call	bwslot ; 26/04/2013 (wslot -> bwslot)	 				
 22958                              <1> 		; jsr r0,wslot / get an I/O buffer to write into
 22959                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 22960 00006129 E815000000          <1>         call	dioreg
 22961                              <1> 		; jsr r0,dioreg / do the necessary bookkeeping
 22962                              <1> 	; esi =  destination address (in the buffer)
 22963                              <1> 	; edi =  [u.pbase], start address of transfer in user's memory space
 22964                              <1> 	; ecx =  transfer count (in bytes)
 22965                              <1> ; 1: / r2 points to the users data; r5 points to the I/O buffers data area
 22966 0000612E 87F7                <1> 	xchg 	esi, edi ; 14/07/2015
 22967 00006130 F3A4                <1> 	rep	movsb
 22968                              <1> 		; movb (r2)+,(r5)+ / ; r3, has the byte count
 22969                              <1>        		; dec r3 / area to the I/O buffer
 22970                              <1>        		; bne 1b
 22971 00006132 E8FE000000          <1> 	call	dskwr
 22972                              <1> 		; jsr r0,dskwr / write it out on the device
 22973 00006137 59                  <1> 	pop	ecx ; **
 22974 00006138 833D[7C740000]00    <1>         cmp     dword [u.count], 0
 22975                              <1> 		; tst u.count / done
 22976 0000613F 77B0                <1> 	ja	short bwrite_0 ; 09/06/2015
 22977                              <1> 		; beq 1f / yes, 1f
 22978                              <1> 		; tst -(r0) / no, point r0 to the argument of the call
 22979                              <1>        		; br bwrite / go back and write next block
 22980                              <1> ; 1:
 22981 00006141 58                  <1> 	pop	eax ; ****
 22982                              <1>        		; mov (sp)+,r0
 22983 00006142 C3                  <1> 	retn		; 09/06/2015
 22984                              <1>         ;jmp     ret_ 
 22985                              <1> 		; jmp ret / return to routine that called writei
 22986                              <1> ;error10:
 22987                              <1> ;       jmp     error  ; / see 'error' routine
 22988                              <1> 
 22989                              <1> dioreg:
 22990                              <1> 	; 14/07/2015
 22991                              <1> 	; 10/07/2015 (UNIX v1 bugfix - [u.fofp]: byte pos., not block)
 22992                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 22993                              <1> 	; 14/03/2013 (Retro UNIX 8086 v1)
 22994                              <1> 	;	
 22995                              <1> 	; bookkeeping on block transfers of data
 22996                              <1> 	;
 22997                              <1> 	; * returns value of u.pbase before it gets updated, in EDI
 22998                              <1> 	; * returns byte count (to transfer) in ECX (<=512)
 22999                              <1> 	; 10/07/2015
 23000                              <1> 	; * returns byte offset from beginning of current sector buffer
 23001                              <1> 	; (beginning of data) in ESI
 23002                              <1> 	;
 23003 00006143 8B0D[7C740000]      <1> 	mov	ecx, [u.count]
 23004                              <1> 		; mov u.count,r3 / move char count to r3
 23005 00006149 81F900020000        <1>        	cmp 	ecx, 512
 23006                              <1> 		; cmp r3,$512. / more than 512. char?
 23007 0000614F 7605                <1> 	jna	short dioreg_0
 23008                              <1> 		; blos 1f / no, branch
 23009 00006151 B900020000          <1> 	mov	ecx, 512
 23010                              <1> 		; mov $512.,r3 / yes, just take 512.
 23011                              <1> dioreg_0:
 23012                              <1> 	; 09/06/2015
 23013 00006156 663B0D[B7740000]    <1> 	cmp	cx, [u.pcount]
 23014 0000615D 7607                <1> 	jna	short dioreg_1
 23015 0000615F 668B0D[B7740000]    <1> 	mov	cx, [u.pcount]
 23016                              <1> dioreg_1:
 23017                              <1> ; 1:
 23018 00006166 8B15[78740000]      <1> 	mov	edx, [u.base] ; 09/06/2015 (eax -> edx)
 23019                              <1> 	        ; mov u.base,r2 / put users base in r2
 23020 0000616C 010D[80740000]      <1> 	add	[u.nread], ecx
 23021                              <1> 		; add r3,u.nread / add the number to be read to u.nread
 23022 00006172 290D[7C740000]      <1> 	sub	[u.count], ecx
 23023                              <1> 		; sub r3,u.count / update count
 23024 00006178 010D[78740000]      <1> 	add	[u.base], ecx
 23025                              <1> 		; add r3,u.base / update base
 23026                              <1> 	; 10/07/2015
 23027                              <1> 	; Retro UNIX 386 v1 - modification !
 23028                              <1> 	; (File pointer points to byte position, not block/sector no.)
 23029                              <1> 	; (It will point to next byte position instead of next block no.)
 23030 0000617E 8B35[68740000]      <1> 	mov	esi, [u.fofp] ; u.fopf points to byte position pointer  
 23031 00006184 8B06                <1> 	mov	eax, [esi] ; esi points to current byte pos. on the disk
 23032 00006186 010E                <1> 	add	[esi], ecx ; ecx is added to set the next byte position
 23033 00006188 25FF010000          <1> 	and	eax, 1FFh  ; get offset from beginning of current block	
 23034 0000618D 89DE                <1> 	mov	esi, ebx   ; beginning of data in sector/block buffer
 23035 0000618F 01C6                <1> 	add	esi, eax   ; esi contains start address of the transfer
 23036                              <1> 	; 09/06/2015 - 10/07/2015
 23037 00006191 66290D[B7740000]    <1> 	sub	[u.pcount], cx
 23038 00006198 81E2FF0F0000        <1> 	and	edx, PAGE_OFF ; 0FFFh
 23039 0000619E 8B3D[B3740000]      <1> 	mov	edi, [u.pbase]
 23040 000061A4 81E700F0FFFF        <1> 	and	edi, ~PAGE_OFF
 23041 000061AA 01D7                <1> 	add	edi, edx
 23042 000061AC 893D[B3740000]      <1> 	mov	[u.pbase], edi
 23043 000061B2 010D[B3740000]      <1> 	add	[u.pbase], ecx ; 14/07/2015
 23044 000061B8 C3                  <1> 	retn
 23045                              <1> 		; rts r0 / return
 23046                              <1> 
 23047                              <1> dskrd:
 23048                              <1> 	; 18/08/2015
 23049                              <1> 	; 02/07/2015
 23050                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 23051                              <1> 	; 14/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 23052                              <1> 	;
 23053                              <1> 	; 'dskrd' acquires an I/O buffer, puts in the proper
 23054                              <1> 	; I/O queue entries (via bufaloc) then reads a block
 23055                              <1> 	; (number specified in r1) in the acquired buffer.)
 23056                              <1> 	; If the device is busy at the time dskrd is called,	
 23057                              <1> 	; dskrd calls idle.
 23058                              <1> 	; 
 23059                              <1> 	; INPUTS ->
 23060                              <1> 	;    r1 - block number
 23061                              <1> 	;    cdev - current device number 
 23062                              <1> 	; OUTPUTS ->
 23063                              <1> 	;    r5 - points to first data word in I/O buffer
 23064                              <1> 	;
 23065                              <1> 	; ((AX = R1)) input/output
 23066                              <1> 	; ((BX = R5)) output 
 23067                              <1> 	;
 23068                              <1>         ; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 23069                              <1> 	;
 23070 000061B9 E830010000          <1> 	call 	bufaloc
 23071                              <1> 		; jsr r0,bufaloc / shuffle off to bufaloc; 
 23072                              <1> 			       ; / get a free I/O buffer
 23073                              <1> 	;;jc	error ; 20/07/2013
 23074 000061BE 741B                <1> 	jz	short dskrd_1 ; Retro UNIX 8086 v1 modification
 23075                              <1>        		; br 1f / branch if block already in a I/O buffer
 23076                              <1> dskrd_0: ; 10/07/2015 (wslot)
 23077 000061C0 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 23078                              <1>         	; bis $2000,(r5) / set bit 10 of word 1 of 
 23079                              <1> 		               ; / I/O queue entry for buffer
 23080 000061C5 E88D000000          <1> 	call	poke
 23081                              <1> 		; jsr r0,poke / just assigned in bufaloc, 
 23082                              <1> 			    ; /	bit 10=1 says read
 23083                              <1> 	; 09/06/2015
 23084 000061CA 730F                <1> 	jnc	short dskrd_1
 23085                              <1> 	;
 23086 000061CC C705[A7740000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; disk read error !
 23087 000061D4 0000                <1>
 23088 000061D6 E972DEFFFF          <1> 	jmp	error
 23089                              <1> dskrd_1: ; 1:
 23090                              <1>        		;clr *$ps
 23091 000061DB 66F7030024          <1>        	test	word [ebx], 2400h
 23092                              <1> 		; bit $22000,(r5) / if either bits 10, or 13 are 1; 
 23093                              <1> 				; / jump to idle
 23094 000061E0 7407                <1>        	jz	short dskrd_2
 23095                              <1> 		; beq 1f
 23096                              <1>         ;;mov   ecx, [s.wait_]
 23097 000061E2 E878F2FFFF          <1>        	call	idle
 23098                              <1> 		; jsr r0,idle; s.wait+2
 23099 000061E7 EBF2                <1> 	jmp 	short dskrd_1
 23100                              <1>        		; br 1b
 23101                              <1> dskrd_2: ; 1:
 23102 000061E9 83C308              <1>         add	ebx, 8
 23103                              <1> 		; add $8,r5 / r5 points to first word of data in block 
 23104                              <1> 			  ; / just read in
 23105 000061EC C3                  <1>        	retn
 23106                              <1> 		; rts r0
 23107                              <1> 
 23108                              <1> bwslot:
 23109                              <1> 	; 10/07/2015
 23110                              <1> 	;	If the block/sector is not placed in a buffer
 23111                              <1> 	;	before 'wslot', it must be read before
 23112                              <1> 	;	it is written! (Otherwise transfer counts less
 23113                              <1> 	;	than 512 bytes will be able to destroy existing 
 23114                              <1> 	;	data on disk.)
 23115                              <1> 	;
 23116                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 23117                              <1> 	; 26/04/2013(Retro UNIX 8086 v1)
 23118                              <1> 	; Retro UNIX 8086 v1 modification !
 23119                              <1> 	; ('bwslot' will be called from 'bwrite' only!)
 23120                              <1> 	; INPUT -> eDI - points to device id (in u.brwdev)	
 23121                              <1> 	;	-> eAX = block number
 23122                              <1> 	;
 23123 000061ED E80A010000          <1> 	call	bufaloc_0
 23124 000061F2 742A                <1> 	jz	short wslot_0 ; block/sector already is in the buffer
 23125                              <1> bwslot_0:
 23126                              <1> 	; 10/07/2015
 23127 000061F4 8B35[68740000]      <1> 	mov	esi, [u.fofp]
 23128 000061FA 8B06                <1> 	mov	eax, [esi]
 23129 000061FC 25FF010000          <1> 	and	eax, 1FFh ; offset from beginning of the sector/block
 23130 00006201 750C                <1> 	jnz 	short bwslot_1 ; it is not a full sector write
 23131                              <1> 		       ; recent disk data must be placed in the buffer
 23132 00006203 813D[7C740000]0002- <1> 	cmp	dword [u.count], 512
 23133 0000620B 0000                <1>
 23134 0000620D 730F                <1> 	jnb	short wslot_0	
 23135                              <1> bwslot_1:
 23136 0000620F E8ACFFFFFF          <1> 	call	dskrd_0
 23137 00006214 83EB08              <1> 	sub	ebx, 8 ; set ebx to the buffer header address again	
 23138 00006217 EB05                <1> 	jmp 	short wslot_0
 23139                              <1> 
 23140                              <1> wslot:
 23141                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 23142                              <1> 	; 		(32 bit modifications)
 23143                              <1> 	; 14/03/2013 - 29/07/2013(Retro UNIX 8086 v1)
 23144                              <1> 	;
 23145                              <1> 	; 'wslot' calls 'bufaloc' and obtains as a result, a pointer
 23146                              <1> 	; to the I/O queue of an I/O buffer for a block structured
 23147                              <1> 	; device. It then checks the first word of I/O queue entry.	
 23148                              <1> 	; If bits 10 and/or 13 (read bit, waiting to read bit) are set,
 23149                              <1> 	; wslot calls 'idle'. When 'idle' returns, or if bits 10 
 23150                              <1> 	; and/or 13 are not set, 'wslot' sets bits 9 and 15 of the first
 23151                              <1> 	; word of the I/O queue entry (write bit, inhibit bit).
 23152                              <1> 	;
 23153                              <1> 	; INPUTS ->
 23154                              <1>  	;    r1 - block number
 23155                              <1> 	;    cdev - current (block/disk) device number
 23156                              <1>  	;
 23157                              <1> 	; OUTPUTS ->
 23158                              <1> 	;    bufp - bits 9 and 15 are set, 
 23159                              <1> 	;           the remainder of the word left unchanged
 23160                              <1> 	;    r5 - points to first data word in I/O buffer
 23161                              <1> 	;
 23162                              <1> 	; ((AX = R1)) input/output
 23163                              <1> 	; ((BX = R5)) output 
 23164                              <1> 	;
 23165                              <1>         ; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP)) 
 23166                              <1> 
 23167 00006219 E8D0000000          <1> 	call	bufaloc
 23168                              <1> 	; 10/07/2015
 23169                              <1> 		; jsr r0,bufaloc / get a free I/O buffer; pointer to first
 23170                              <1>         	; br 1f / word in buffer in r5
 23171                              <1> 	; eBX = Buffer (Header) Address (r5) (ES=CS=DS, system/kernel segment)
 23172                              <1>         ; eAX = Block/Sector number (r1)
 23173                              <1> wslot_0: ;1:
 23174 0000621E 66F7030024          <1>      	test	word [ebx], 2400h
 23175                              <1> 		; bit $22000,(r5) / check bits 10, 13 (read, waiting to read)
 23176                              <1> 				; / of I/O queue entry
 23177 00006223 7407                <1> 	jz	short wslot_1
 23178                              <1>                 ; beq 1f  / branch if 10, 13 zero (i.e., not reading, 
 23179                              <1> 		     ; / or not waiting to read)
 23180                              <1> 
 23181                              <1>         ;; mov     ecx, [s.wait_] ; 29/07/2013
 23182 00006225 E835F2FFFF          <1> 	call	idle
 23183                              <1> 		; jsr r0,idle; / if buffer is reading or writing to read,
 23184                              <1>        	                     ; / idle
 23185 0000622A EBF2                <1> 	jmp	short wslot_0
 23186                              <1> 		; br 1b / till finished
 23187                              <1> wslot_1: ;1:
 23188 0000622C 66810B0082          <1>         or      word [ebx], 8200h
 23189                              <1>        		; bis $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
 23190                              <1>                             	 ; / (write, inhibit bits)
 23191                              <1>        		; clr     *$ps / clear processor status
 23192 00006231 83C308              <1>         add	ebx, 8 ; 11/06/2015
 23193                              <1> 		; add $8,r5 / r5 points to first word in data area 
 23194                              <1> 			  ; / for this block
 23195 00006234 C3                  <1>        	retn
 23196                              <1> 		; rts r0
 23197                              <1> dskwr:
 23198                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 23199                              <1> 	; 14/03/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 23200                              <1> 	;
 23201                              <1> 	; 'dskwr' writes a block out on disk, via ppoke. The only
 23202                              <1> 	; thing dskwr does is clear bit 15 in the first word of I/O queue
 23203                              <1> 	; entry pointed by 'bufp'. 'wslot' which must have been called
 23204                              <1> 	; previously has supplied all the information required in the
 23205                              <1> 	; I/O queue entry.
 23206                              <1> 	;
 23207                              <1> 	; (Modified registers: eCX, eDX, eBX, eSI, eDI)
 23208                              <1> 	;
 23209                              <1> 	;
 23210 00006235 8B1D[1A740000]      <1> 	mov	ebx, [bufp]
 23211 0000623B 668123FF7F          <1> 	and	word [ebx], 7FFFh ; 0111111111111111b
 23212                              <1> 		; bic $100000,*bufp / clear bit 15 of I/O queue entry at
 23213                              <1>                                   ; / bottom of queue
 23214 00006240 E812000000          <1> 	call	poke
 23215                              <1> 	; 09/06/2015
 23216 00006245 730F                <1> 	jnc	short dskwr_1
 23217 00006247 C705[A7740000]1200- <1> 	mov	dword [u.error], ERR_DRV_WRITE ; disk write error !
 23218 0000624F 0000                <1>
 23219 00006251 E9F7DDFFFF          <1> 	jmp	error
 23220                              <1> dskwr_1:
 23221 00006256 C3                  <1> 	retn
 23222                              <1> 
 23223                              <1> 
 23224                              <1> ;ppoke:
 23225                              <1>        		; mov $340,*$ps
 23226                              <1>        		; jsr r0,poke
 23227                              <1>        		; clr *$ps
 23228                              <1> 		; rts r0
 23229                              <1> poke:
 23230                              <1> 	; 24/10/2015
 23231                              <1> 	; 20/08/2015
 23232                              <1> 	; 18/08/2015
 23233                              <1> 	; 02/07/2015
 23234                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 23235                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 23236                              <1> 	;
 23237                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
 23238                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
 23239                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
 23240                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
 23241                              <1> 	;
 23242                              <1> 	; Basic I/O functions for all block structured devices
 23243                              <1> 	;
 23244                              <1>         ; (Modified registers: eCX, eDX, eSI, eDI)
 23245                              <1> 	;
 23246                              <1> 	; 20/07/2013 modifications
 23247                              <1> 	;            (Retro UNIX 8086 v1 features only !)
 23248                              <1> 	; INPUTS -> 
 23249                              <1> 	;        (EBX = buffer header address)
 23250                              <1> 	; OUTPUTS ->
 23251                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
 23252                              <1> 	;	 cf=1 -> error, word [eBX] = 0FFFFh
 23253                              <1> 	;		(drive not ready or r/w error!)
 23254                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
 23255                              <1> 	;	 (dword [EBx+4] = 0FFFFFFFFh means RW/IO error)
 23256                              <1> 	;        (also it indicates invalid buffer data)
 23257                              <1> 	;
 23258 00006257 53                  <1> 	push	ebx
 23259                              <1>        		; mov r1,-(sp)
 23260                              <1>        		; mov r2,-(sp)
 23261                              <1>        		; mov r3,-(sp)
 23262 00006258 50                  <1> 	push 	eax ; Physical Block Number (r1) (mget)
 23263                              <1> 	;
 23264                              <1> 	; 09/06/2015
 23265                              <1> 	; (permit read/write after a disk  R/W error)
 23266 00006259 8A0B                <1> 	mov	cl, [ebx] ; device id (0 to 5)
 23267 0000625B B001                <1> 	mov	al, 1
 23268 0000625D D2E0                <1> 	shl	al, cl
 23269 0000625F 8405[42740000]      <1> 	test 	al, [active] ; busy ? (error)
 23270 00006265 7408                <1> 	jz	short poke_0
 23271 00006267 F6D0                <1> 	not	al
 23272 00006269 2005[42740000]      <1> 	and	[active], al ; reset busy bit for this device only
 23273                              <1> poke_0:
 23274 0000626F BE[3A740000]        <1>         mov     esi, bufp + (4*(nbuf+2)) 
 23275                              <1> 		; mov $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority
 23276                              <1> 					 ; / I/O queue pointer
 23277                              <1> poke_1: ; 1:
 23278 00006274 83EE04              <1>         sub	esi, 4
 23279 00006277 8B1E                <1> 	mov	ebx, [esi]
 23280                              <1> 		; mov -(r2),r1 / r1 points to an I/O queue entry
 23281 00006279 668B03              <1> 	mov	ax, [ebx] ; 17/07/2013
 23282 0000627C F6C406              <1>        	test	ah, 06h
 23283                              <1> 	;test	word [ebx], 600h ; 0000011000000000b
 23284                              <1> 		; bit $3000,(r1) / test bits 9 and 10 of word 1 of I/O 
 23285                              <1> 			       ; / queue entry
 23286 0000627F 745E                <1>         jz      short poke_5
 23287                              <1> 		; beq 2f / branch to 2f if both are clear
 23288                              <1> 	; 31/07/2013
 23289                              <1> 	;test	ah, 0B0h ; (*)
 23290                              <1> 	;;test	word [ebx], 0B000h ; 1011000000000000b
 23291                              <1> 		; bit $130000,(r1) / test bits 12, 13, and 15
 23292                              <1>         ;jnz     short poke_5 ; 31/07/2013 (*)
 23293                              <1> 		; bne 2f / branch if any are set
 23294                              <1> 	;movzx	ecx, byte [ebx] ; 09/06/2015 ; Device Id
 23295                              <1>     		; movb (r1),r3 / get device id
 23296 00006281 0FB6C8              <1> 	movzx	ecx, al ; 18/08/2015
 23297                              <1> 	;mov	edi, ecx ; 26/04/2013
 23298 00006284 31C0                <1> 	xor 	eax, eax ; 0
 23299                              <1> 	;cmp 	[edi+drv.error], al ; 0
 23300                              <1> 		; tstb deverr(r3) / test for errors on this device
 23301                              <1>        	;jna	short poke_2 
 23302                              <1> 		; beq 3f / branch if no errors
 23303                              <1> 	; 02/07/2015
 23304                              <1> 	;dec	eax
 23305                              <1> 	;mov	[ebx+4], ax ; 0FFFFFFFFh ; -1 
 23306                              <1>        		; mov $-1,2(r1) / destroy associativity
 23307                              <1> 	;shr	eax, 24
 23308                              <1> 	;mov	[ebx], eax ; 000000FFh, reset
 23309                              <1> 		; clrb 1(r1) / do not do I/O
 23310                              <1> 	;jmp     short poke_5
 23311                              <1>         ;       ; br 2f
 23312                              <1>                 ; rts r0
 23313                              <1> poke_2: ; 3:
 23314                              <1> 	; 02/07/2015
 23315 00006286 FEC1                <1> 	inc	cl ; 0FFh -> 0
 23316 00006288 7455                <1> 	jz	short poke_5
 23317 0000628A FEC0                <1> 	inc	al ; mov ax, 1
 23318 0000628C FEC9                <1> 	dec	cl
 23319 0000628E 7402                <1> 	jz	short poke_3
 23320                              <1> 	; 26/04/2013 Modification
 23321                              <1> 	;inc	al ; mov ax, 1
 23322                              <1> 	;or	cl, cl ; Retro UNIX 8086 v1 device id.
 23323                              <1> 	;jz	short poke_3 ; cl = 0
 23324 00006290 D2E0                <1> 	shl	al, cl ; shl ax, cl
 23325                              <1> poke_3:
 23326                              <1> 	;test	[active], ax
 23327 00006292 8405[42740000]      <1> 	test	[active], al
 23328                              <1> 		; bit $2,active / test disk busy bit
 23329 00006298 7545                <1> 	jnz     short poke_5
 23330                              <1> 		; bne 2f / branch if bit is set
 23331                              <1> 	;or	[active], ax
 23332 0000629A 0805[42740000]      <1> 	or	[active], al
 23333                              <1> 		; bis $2,active / set disk busy bit
 23334 000062A0 6650                <1> 	push	ax
 23335 000062A2 E8CB000000          <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
 23336                              <1> 	;mov    [edi+drv.error], ah
 23337 000062A7 6658                <1> 	pop	ax
 23338 000062A9 730E                <1> 	jnc	short poke_4 ; 20/07/2013
 23339                              <1> 	;cmp 	[edi+drv.error], al ; 0	
 23340                              <1> 	;jna	short poke_4
 23341                              <1> 		; tstb deverr(r3) / test for errors on this device
 23342                              <1>        		; beq 3f / branch if no errors
 23343                              <1> 	; 02/07/2015 (32 bit modification)
 23344                              <1> 	; 20/07/2013
 23345 000062AB C74304FFFFFFFF      <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
 23346                              <1>        		; mov $-1,2(r1) / destroy associativity
 23347 000062B2 66C703FF00          <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
 23348                              <1> 		; clrb 1(r1) / do not do I/O
 23349 000062B7 EB26                <1> 	jmp     short poke_5
 23350                              <1> poke_4:	; 20/07/2013
 23351                              <1> 	; 17/07/2013
 23352 000062B9 F6D0                <1> 	not 	al 
 23353 000062BB 2005[42740000]      <1> 	and	[active], al ; reset, not busy
 23354                              <1> 	; eBX = system I/O buffer header (queue entry) address
 23355                              <1> seta: ; / I/O queue bookkeeping; set read/write waiting bits.
 23356 000062C1 668B03              <1> 	mov	ax, [ebx]
 23357                              <1>        		; mov (r1),r3 / move word 1 of I/O queue entry into r3
 23358 000062C4 66250006            <1>         and	ax, 600h
 23359                              <1> 		; bic $!3000,r3 / clear all bits except 9 and 10
 23360 000062C8 668123FFF9          <1> 	and 	word [ebx], 0F9FFh
 23361                              <1>        		; bic $3000,(r1) / clear only bits 9 and 10
 23362 000062CD C0E403              <1> 	shl	ah, 3
 23363                              <1>        		; rol r3
 23364                              <1>                 ; rol r3
 23365                              <1>                 ; rol r3	
 23366 000062D0 660903              <1> 	or	[ebx], ax
 23367                              <1> 		; bis r3,(r1) / or old value of bits 9 and 10 with 
 23368                              <1> 			   ; bits 12 and 13
 23369 000062D3 E887F1FFFF          <1> 	call	idle ; 18/01/2014
 23370                              <1> 	;; sti
 23371                              <1> 	;hlt 	; wait for a hardware interrupt
 23372                              <1> 	;; cli
 23373                              <1> 	; NOTE: In fact, disk controller's 'disk I/O completed' 
 23374                              <1>         ; interrupt would be used to reset busy bits, but INT 13h
 23375                              <1> 	; returns when disk I/O is completed. So, here, as temporary
 23376                              <1> 	; method, this procedure will wait for a time according to
 23377                              <1> 	; multi tasking and time sharing concept.
 23378                              <1> 	;
 23379                              <1> 	; 24/10/2015
 23380                              <1> 	;not	ax 
 23381 000062D8 66B8FF00            <1> 	mov 	ax, 0FFh ; 24/10/2015 (temporary)
 23382 000062DC 662103              <1> 	and	[ebx], ax ; clear bits 12 and 13
 23383                              <1> poke_5: ;2:
 23384 000062DF 81FE[1A740000]      <1>         cmp     esi, bufp
 23385                              <1>                ; cmp r2,$bufp / test to see if entire I/O queue 
 23386                              <1>                             ; / has been scanned
 23387 000062E5 778D                <1> 	ja      short poke_1
 23388                              <1>                ; bhi 1b
 23389                              <1> 	; 24/03/2013
 23390                              <1>        		; mov (sp)+,r3
 23391                              <1>        		; mov (sp)+,r2
 23392                              <1>        		; mov (sp)+,r1
 23393 000062E7 58                  <1>         pop 	eax  ; Physical Block Number (r1) (mget)
 23394 000062E8 5B                  <1> 	pop 	ebx
 23395                              <1> 	; 02/07/2015 (32 bit modification)
 23396                              <1> 	; 20/07/2013
 23397                              <1> 	;cmp 	dword [ebx+4], 0FFFFFFFFh
 23398 000062E9 803BFF              <1> 	cmp	byte [ebx], 0FFh ; 20/08/2015
 23399                              <1> 	;	
 23400                              <1> 	; 'poke' returns with cf=0 if the requested buffer is read 
 23401                              <1> 	; or written succesfully; even if an error occurs while
 23402                              <1> 	; reading to or writing from other buffers. 20/07/2013
 23403                              <1> 	;
 23404                              <1> 	; 09/06/2015
 23405 000062EC F5                  <1> 	cmc
 23406 000062ED C3                  <1> 	retn
 23407                              <1>                 ; rts r0
 23408                              <1> 
 23409                              <1> bufaloc:
 23410                              <1> 	; 20/08/2015
 23411                              <1> 	; 19/08/2015
 23412                              <1> 	; 02/07/2015
 23413                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 23414                              <1> 	;	     (32 bit modifications)	
 23415                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 23416                              <1> 	;
 23417                              <1> 	; bufaloc - Block device I/O buffer allocation
 23418                              <1> 	; 
 23419                              <1> 	; INPUTS ->
 23420                              <1> 	;    r1 - block number
 23421                              <1> 	;    cdev - current (block/disk) device number
 23422                              <1> 	;    bufp+(2*n)-2 --- n = 1 ... nbuff
 23423                              <1> 	; OUTPUTS ->
 23424                              <1> 	;    r5 - pointer to buffer allocated
 23425                              <1> 	;    bufp ... bufp+12 --- (bufp), (bufp)+2
 23426                              <1> 	;
 23427                              <1> 	; ((AX = R1)) input/output
 23428                              <1> 	; ((BX = R5)) output
 23429                              <1>         ;    ((Modified registers: DX, CX, BX, SI, DI, BP))
 23430                              <1> 	;    zf=1 -> block already in a I/O buffer
 23431                              <1> 	;    zf=0 -> a new I/O buffer has been allocated
 23432                              <1> 	;    ((DL = Device ID))
 23433                              <1> 	;    (((DH = 0 or 1)))
 23434                              <1> 	;    (((CX = previous value of word ptr [bufp])))
 23435                              <1> 	;    ((CX and DH will not be used after return)))
 23436                              <1> 
 23437                              <1> 	;;push 	esi ; ***
 23438                              <1> 		; mov r2,-(sp) / save r2 on stack
 23439                              <1>        		; mov $340,*$ps / set processor priority to 7
 23440                              <1> 	; 20/07/2013
 23441                              <1> 	; 26/04/2013
 23442 000062EE 0FB61D[3E740000]    <1> 	movzx	ebx, byte [cdev] ; 0 or 1
 23443 000062F5 BF[40740000]        <1> 	mov	edi, rdev  ; offset mdev = offset rdev + 1
 23444 000062FA 01DF                <1> 	add	edi, ebx
 23445                              <1> bufaloc_0: ; 26/04/2013 !! here is called from bread or bwrite !!
 23446                              <1> 			;; eDI points to device id.
 23447 000062FC 0FB61F              <1> 	movzx	ebx, byte [edi] ; [EDI] -> rdev/mdev or brwdev
 23448                              <1> 	; 11/06/20215
 23449 000062FF 80BB[7A6B0000]F0    <1> 	cmp 	byte [ebx+drv.status], 0F0h ; Drive not ready !
 23450 00006306 720F                <1> 	jb	short bufaloc_9
 23451 00006308 C705[A7740000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 23452 00006310 0000                <1>
 23453 00006312 E936DDFFFF          <1> 	jmp	error
 23454                              <1> bufaloc_9:
 23455 00006317 89DA                <1> 	mov	edx, ebx ; dh = 0, dl = device number (0 to 5)
 23456                              <1> bufaloc_10: ; 02/07/2015
 23457 00006319 31ED                <1> 	xor 	ebp, ebp ; 0
 23458 0000631B 55                  <1> 	push	ebp ; 0
 23459 0000631C 89E5                <1>         mov     ebp, esp	
 23460                              <1> 	;
 23461                              <1> bufaloc_1: ;1:
 23462                              <1> 		; clr -(sp) / vacant buffer
 23463 0000631E BE[1A740000]        <1>         mov 	esi, bufp
 23464                              <1> 		; mov $bufp,r2 / bufp contains pointers to I/O queue 
 23465                              <1> 			     ; / entrys in buffer area
 23466                              <1> bufaloc_2: ;2:
 23467 00006323 8B1E                <1> 	mov	ebx, [esi]
 23468                              <1>        		; mov (r2)+,r5 / move pointer to word 1 of an I/O 
 23469                              <1> 			    ; queue entry into r5
 23470 00006325 66F70300F6          <1> 	test	word [ebx], 0F600h
 23471                              <1> 		; bit $173000,(r5) / lock+keep+active+outstanding
 23472 0000632A 7503                <1>         jnz	short bufaloc_3
 23473                              <1> 		; bne 3f / branch when 
 23474                              <1> 		       ; / any of bits 9,10,12,13,14,15 are set
 23475                              <1>                        ; / (i.e., buffer busy)
 23476 0000632C 897500              <1>         mov     [ebp], esi ; pointer to I/0 queue entry
 23477                              <1>                 ; mov  r2,(sp) ;/ save pointer to last non-busy buffer
 23478                              <1> 			; / found points to word 2 of I/O queue entry)
 23479                              <1> bufaloc_3: ;3:
 23480                              <1> 	;mov	dl, [edi] ; 26/04/2013
 23481                              <1> 	;
 23482 0000632F 3813                <1> 	cmp	[ebx], dl	
 23483                              <1> 		; cmpb (r5),cdev / is device in I/O queue entry same 
 23484                              <1> 			       ; / as current device
 23485 00006331 7508                <1> 	jne	short bufaloc_4
 23486                              <1>        		; bne 3f
 23487 00006333 394304              <1> 	cmp	[ebx+4], eax
 23488                              <1>        		; cmp 2(r5),r1 / is block number in I/O queue entry, 
 23489                              <1> 			     ; / same as current block number
 23490 00006336 7503                <1>        	jne	short bufaloc_4
 23491                              <1> 		; bne 3f
 23492                              <1> 	;add	esp, 4
 23493 00006338 59                  <1> 	pop	ecx
 23494                              <1>        		; tst (sp)+ / bump stack pointer
 23495 00006339 EB20                <1> 	jmp	short bufaloc_7 ; Retro Unix 8086 v1 modification
 23496                              <1> 				; jump to bufaloc_6 in original Unix v1
 23497                              <1>        		; br 1f / use this buffer
 23498                              <1> bufaloc_4: ;3:
 23499 0000633B 83C604              <1> 	add	esi, 4 ; 20/08/2015
 23500                              <1> 	;
 23501 0000633E 81FE[32740000]      <1> 	cmp	esi, bufp + (nbuf*4)
 23502                              <1> 		; cmp r2,$bufp+nbuf+nbuf
 23503 00006344 72DD                <1> 	jb	short bufaloc_2
 23504                              <1> 		; blo 2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
 23505                              <1>                        ; / buffers not checked)
 23506 00006346 5E                  <1>         pop	esi
 23507                              <1> 		; mov (sp)+,r2 / once all bufs are examined move pointer
 23508                              <1> 			     ; / to last free block
 23509 00006347 09F6                <1>        	or	esi, esi 
 23510 00006349 7507                <1> 	jnz	short bufaloc_5
 23511                              <1> 		; bne 2f / if (sp) is non zero, i.e., 
 23512                              <1> 	        ; / if a free buffer is found branch to 2f
 23513                              <1>         ;; mov  ecx, [s.wait_]
 23514 0000634B E80FF1FFFF          <1> 	call	idle
 23515                              <1> 		; jsr r0,idle; s.wait+2 / idle if no free buffers
 23516 00006350 EBC7                <1> 	jmp 	short bufaloc_10 ; 02/07/2015
 23517                              <1>        		; br 1b
 23518                              <1> bufaloc_5: ;2:
 23519                              <1> 		; tst (r0)+ / skip if warmed over buffer
 23520 00006352 FEC6                <1> 	inc	dh ; Retro UNIX 8086 v1 modification
 23521                              <1> bufaloc_6: ;1:
 23522 00006354 8B1E                <1>         mov    	ebx, [esi] 
 23523                              <1> 		; mov -(r2),r5 / put pointer to word 1 of I/O queue 
 23524                              <1> 			     ; / entry in r5
 23525                              <1> 	;; 26/04/2013
 23526                              <1>         ;mov	dl, [edi] ; byte [rdev] or byte [mdev]
 23527 00006356 8813                <1> 	mov 	[ebx], dl
 23528                              <1> 		; movb cdev,(r5) / put current device number 
 23529                              <1> 				 ; / in I/O queue entry
 23530 00006358 894304              <1> 	mov 	[ebx+4], eax
 23531                              <1> 		; mov r1,2(r5) / move block number into word 2 
 23532                              <1> 			     ; / of I/O queue entry
 23533                              <1> bufaloc_7: ;1:
 23534 0000635B 81FE[1A740000]      <1>         cmp	esi, bufp
 23535                              <1> 		; cmp r2,$bufp / bump all entrys in bufp 
 23536                              <1> 			     ; / and put latest assigned
 23537 00006361 760A                <1> 	jna	short bufaloc_8	
 23538                              <1>        		; blos 1f / buffer on the top 
 23539                              <1> 			; / (this makes if the lowest priority)
 23540 00006363 83EE04              <1> 	sub	esi, 4
 23541 00006366 8B0E                <1> 	mov	ecx, [esi]
 23542 00006368 894E04              <1> 	mov	[esi+4], ecx
 23543                              <1> 		; mov -(r2),2(r2) / job for a particular device
 23544 0000636B EBEE                <1> 	jmp 	short bufaloc_7        
 23545                              <1> 		; br 1b
 23546                              <1> bufaloc_8: ;1:
 23547 0000636D 891E                <1>         mov	[esi], ebx
 23548                              <1> 		; mov r5,(r2)
 23549                              <1> 	;;pop	esi ; ***
 23550                              <1>        		; mov (sp)+,r2 / restore r2
 23551 0000636F 08F6                <1>        	or 	dh, dh ; 0 or 1 ?
 23552                              <1> 		; Retro UNIX 8086 v1 modification
 23553                              <1> 		; zf=1 --> block already is in an I/O buffer
 23554                              <1> 		; zf=0 --> a new I/O buffer has been allocated
 23555 00006371 C3                  <1> 	retn
 23556                              <1> 		; rts r0
 23557                              <1> 
 23558                              <1> diskio:
 23559                              <1> 	; 10/07/2015
 23560                              <1> 	; 02/07/2015
 23561                              <1> 	; 16/06/2015
 23562                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 23563                              <1> 	;	     (80386 protected mode modifications)	
 23564                              <1> 	; 15/03/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 23565                              <1> 	;
 23566                              <1> 	; Retro UNIX 8086 v1 feature only !
 23567                              <1> 	;
 23568                              <1> 	; Derived from proc_chs_read procedure of TRDOS DISKIO.ASM (2011)
 23569                              <1> 	; 04/07/2009 - 20/07/2011
 23570                              <1> 	;
 23571                              <1> 	; NOTE: Reads only 1 block/sector (sector/block size is 512 bytes)
 23572                              <1> 	;
 23573                              <1>         ; INPUTS ->
 23574                              <1> 	; 	   eBX = System I/O Buffer header address
 23575                              <1> 	;
 23576                              <1>         ; OUTPUTS -> cf=0 --> done 
 23577                              <1> 	; 	     cf=1 ---> error code in AH
 23578                              <1> 	;
 23579                              <1> 	; (Modified registers: eAX, eCX, eDX)
 23580                              <1> 	
 23581                              <1> ;rw_disk_sector:
 23582                              <1> 	; 10/07/2015
 23583                              <1> 	; 02/07/2015
 23584                              <1> 	; 11/06/2015 - Retro UNIX 386 v1 - 'u8.s' 
 23585                              <1> 	; 21/02/2015 ('dsectpm.s', 'read_disk_sector')
 23586                              <1> 	; 16/02/2015 (Retro UNIX 386 v1 test - 'unix386.s')
 23587                              <1> 	; 01/12/2014 - 18/01/2015 ('dsectrm2.s')
 23588                              <1> 	;
 23589                              <1> 	;mov	dx, 0201h ; Read 1 sector/block
 23590 00006372 B602                <1> 	mov	dh, 2
 23591 00006374 668B03              <1> 	mov	ax, [ebx] 
 23592                              <1> 	;
 23593 00006377 56                  <1> 	push	esi ; ****
 23594 00006378 53                  <1> 	push	ebx ; ***
 23595                              <1> 	;
 23596 00006379 0FB6C8              <1> 	movzx	ecx, al
 23597 0000637C 89CE                <1> 	mov	esi, ecx
 23598                              <1> 	;
 23599 0000637E 38F1                <1> 	cmp	cl, dh ; 2
 23600 00006380 7202                <1> 	jb	short rwdsk0
 23601 00006382 047E                <1> 	add	al, 7Eh  ; 80h, 81h, 82h, 83h
 23602                              <1> rwdsk0:
 23603 00006384 A2[2B6B0000]        <1> 	mov	[drv], al
 23604 00006389 81C6[7A6B0000]      <1> 	add	esi, drv.status
 23605                              <1> 	; 11/06/2015
 23606 0000638F 803EF0              <1> 	cmp	byte [esi], 0F0h 
 23607 00006392 720F                <1> 	jb      short rwdsk1
 23608                              <1> 	; 'drive not ready' error
 23609 00006394 C705[A7740000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 23610 0000639C 0000                <1>
 23611 0000639E E9AADCFFFF          <1> 	jmp	error
 23612                              <1> rwdsk1:
 23613 000063A3 F6C402              <1> 	test	ah, 2
 23614                              <1> 	;test	ax, 200h ; Bit 9 of word 0 (status word)
 23615                              <1> 			   ; write bit
 23616 000063A6 7402                <1> 	jz	short rwdsk2
 23617                              <1> 	;test	ah, 4
 23618                              <1> 	;;test	ax, 400h ; Bit 10 of word 0 (status word)
 23619                              <1> 	;		 ; read bit
 23620                              <1> 	;jz	short diskio_ret
 23621 000063A8 FEC6                <1> 	inc	dh ; 03h = write
 23622                              <1> rwdsk2:
 23623 000063AA 88C2                <1> 	mov	dl, al
 23624 000063AC 83C304              <1> 	add	ebx, 4 ; sector/block address/number pointer
 23625 000063AF 8B03                <1> 	mov	eax, [ebx] ; sector/block number (LBA)
 23626 000063B1 C0E102              <1> 	shl	cl, 2
 23627 000063B4 81C1[5E6B0000]      <1> 	add	ecx, drv.size ; disk size
 23628 000063BA 3B01                <1> 	cmp	eax, [ecx] ; Last sector + 1 (number of secs.)
 23629 000063BC 720F                <1> 	jb      short rwdsk3
 23630                              <1>  	; 'out of volume' error
 23631 000063BE C705[A7740000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE 	
 23632 000063C6 0000                <1>
 23633 000063C8 E980DCFFFF          <1> 	jmp	error
 23634                              <1> rwdsk3:
 23635                              <1> 	; 11/06/2015
 23636 000063CD 83C304              <1> 	add	ebx, 4 ; buffer address
 23637 000063D0 C605[D6740000]04    <1> 	mov	byte [retry_count], 4
 23638 000063D7 F60601              <1> 	test	byte [esi], 1 ; LBA ready ?
 23639 000063DA 7432                <1>         jz      short rwdsk_chs
 23640                              <1> rwdsk_lba:
 23641                              <1> 	; LBA read/write (with private LBA function) 
 23642                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 23643 000063DC 83C607              <1>         add     esi, drv.error - drv.status ; 10/07/2015
 23644 000063DF 89C1                <1> 	mov	ecx, eax ; sector number
 23645                              <1> 	; ebx = buffer (data) address
 23646                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
 23647                              <1> rwdsk_lba_retry:
 23648                              <1> 	;mov	dl, [drv]
 23649                              <1> 		; Function 1Bh = LBA read, 1Ch = LBA write
 23650 000063E1 B419                <1> 	mov	ah, 1Ch - 3h ; LBA write function number - 3
 23651 000063E3 00F4                <1> 	add	ah, dh		
 23652 000063E5 B001                <1> 	mov	al, 1
 23653                              <1> 	;int	13h
 23654 000063E7 E8D6C3FFFF          <1> 	call	int13h
 23655 000063EC 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 23656 000063EE 730E                <1> 	jnc	short rwdsk_lba_ok
 23657 000063F0 80FC80              <1> 	cmp	ah, 80h ; time out ?
 23658 000063F3 7408                <1>         je      short rwdsk_lba_fails
 23659 000063F5 FE0D[D6740000]      <1> 	dec	byte [retry_count]
 23660 000063FB 7504                <1>         jnz     short rwdsk_lba_reset ; 10/07/2015
 23661                              <1> rwdsk_lba_fails:
 23662 000063FD F9                  <1> 	stc
 23663                              <1> rwdsk_lba_ok:
 23664 000063FE 5B                  <1> 	pop	ebx ; ***
 23665 000063FF 5E                  <1> 	pop	esi ; ****
 23666 00006400 C3                  <1> 	retn
 23667                              <1> rwdsk_lba_reset:
 23668 00006401 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 23669                              <1> 	;int	13h
 23670 00006403 E8BAC3FFFF          <1>         call	int13h
 23671 00006408 73D7                <1> 	jnc     short rwdsk_lba_retry
 23672 0000640A 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 23673 0000640C EBF0                <1> 	jmp	short rwdsk_lba_ok
 23674                              <1> 	;
 23675                              <1> 	; CHS read (convert LBA address to CHS values)	
 23676                              <1> rwdsk_chs:
 23677                              <1> 	; 10/07/2015
 23678 0000640E 81EE[7A6B0000]      <1> 	sub	esi, drv.status
 23679 00006414 89F1                <1> 	mov	ecx, esi
 23680 00006416 81C6[816B0000]      <1> 	add 	esi, drv.error
 23681                              <1> 	; 02/07/2015
 23682                              <1> 	; 16/06/2015
 23683                              <1>  	; 11/06/2015 
 23684 0000641C 53                  <1> 	push	ebx ; ** ; buffer
 23685 0000641D D1E1                <1> 	shl	ecx, 1
 23686 0000641F 51                  <1> 	push	ecx ; * 
 23687                              <1> 	;
 23688 00006420 89CB                <1> 	mov	ebx, ecx
 23689 00006422 8835[D5740000]      <1> 	mov	[rwdsk], dh ; 02/07/2015
 23690 00006428 31D2                <1> 	xor	edx, edx ; 0
 23691 0000642A 29C9                <1> 	sub	ecx, ecx 
 23692 0000642C 81C3[506B0000]      <1>         add     ebx, drv.spt
 23693 00006432 668B0B              <1> 	mov	cx, [ebx] ; sector per track
 23694                              <1> 		; EDX:EAX = LBA
 23695 00006435 F7F1                <1> 	div	ecx
 23696 00006437 88D1                <1> 	mov	cl, dl	; sector number - 1
 23697 00006439 FEC1                <1> 	inc	cl	; sector number (1 based)
 23698 0000643B 5B                  <1> 	pop	ebx ; * ; 11/06/2015
 23699 0000643C 6651                <1> 	push	cx
 23700 0000643E 81C3[426B0000]      <1>         add     ebx, drv.heads
 23701 00006444 668B0B              <1> 	mov	cx, [ebx] ; heads
 23702 00006447 31D2                <1> 	xor	edx, edx
 23703                              <1> 		; EAX = cylinders * heads + head
 23704 00006449 F7F1                <1> 	div	ecx
 23705 0000644B 6659                <1> 	pop	cx     ; sector number
 23706 0000644D 88D6                <1> 	mov	dh, dl ; head number
 23707 0000644F 8A15[2B6B0000]      <1> 	mov	dl, [drv]
 23708 00006455 88C5                <1> 	mov	ch, al ; cylinder (bits 0-7)
 23709 00006457 C0E406              <1> 	shl	ah, 6
 23710 0000645A 08E1                <1> 	or	cl, ah ; cylinder (bits 8-9)
 23711                              <1> 		       ; sector (bits 0-7)
 23712 0000645C 5B                  <1> 	pop	ebx ; ** ; buffer ; 11/06/2015
 23713                              <1> 		; CL = sector (bits 0-5)
 23714                              <1> 		;      cylinder (bits 8-9 -> bits 6-7)
 23715                              <1> 		; CH = cylinder (bits 0-7)
 23716                              <1> 		; DH = head
 23717                              <1> 		; DL = drive
 23718                              <1> 	;
 23719 0000645D C605[D6740000]04    <1> 	mov	byte [retry_count], 4
 23720                              <1> rwdsk_retry:	
 23721 00006464 8A25[D5740000]      <1> 	mov	ah, [rwdsk] ; 02h = read, 03h = write
 23722 0000646A B001                <1> 	mov	al, 1 ; sector count	
 23723                              <1> 	;int	13h
 23724 0000646C E851C3FFFF          <1> 	call	int13h
 23725 00006471 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 23726 00006473 730E                <1> 	jnc	short rwdsk_ok ; ah = 0
 23727 00006475 80FC80              <1> 	cmp	ah, 80h ; time out ?
 23728 00006478 7408                <1> 	je	short rwdsk_fails
 23729 0000647A FE0D[D6740000]      <1> 	dec	byte [retry_count]
 23730 00006480 7504                <1> 	jnz	short rwdsk_reset
 23731                              <1> rwdsk_fails:
 23732 00006482 F9                  <1> 	stc
 23733                              <1> rwdsk_ok:
 23734 00006483 5B                  <1> 	pop	ebx ; ***
 23735 00006484 5E                  <1> 	pop	esi ; ****
 23736 00006485 C3                  <1> 	retn
 23737                              <1> rwdsk_reset:
 23738                              <1> 	; 02/02/2015
 23739 00006486 28E4                <1> 	sub	ah, ah
 23740 00006488 80FA80              <1> 	cmp	dl, 80h
 23741 0000648B 7202                <1> 	jb	short rwdsk_fd_reset
 23742 0000648D B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 23743                              <1> rwdsk_fd_reset:
 23744                              <1> 	;int	13h
 23745 0000648F E82EC3FFFF          <1>         call	int13h
 23746 00006494 73CE                <1> 	jnc	short rwdsk_retry
 23747 00006496 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 23748 00006498 EBE9                <1> 	jmp 	short rwdsk_ok
 23749                              <1> 
 23750                              <1> 
 23751                              <1> ; Original UNIX v1 - drum (& disk) interrupt routine
 23752                              <1> ;	(Equivalent to IRQ 14 & IRQ 15 disk/hardware interrupts)
 23753                              <1> ;
 23754                              <1> ; This feature is not used in Retro UNIX 386 (& 8086) for now.
 23755                              <1> ; Because, current Retro UNIX 386 disk I/O -INT13H- routine is 
 23756                              <1> ; derived from IBM PC AT -infact: XT286- BIOS source code, int 13h
 23757                              <1> ; that uses hardware -transfer has been completed-  interrupt inside it. 
 23758                              <1> ; In a next Retro UNIX 386 version, these interrupts
 23759                              <1> ; (fdc_int, hdc1_int, hdc2_int) will be handled by a separate routine
 23760                              <1> ; as in original unix v1.
 23761                              <1> ; I am not removing IBM BIOS source code derivatives -compatible code-
 23762                              <1> ; for now, regarding the new/next 32 bit TRDOS project by me
 23763                              <1> ; (to keep source code files easy adaptable to 32 bit TRDOS.)
 23764                              <1> ;
 23765                              <1> ; Erdogan tan (10/07/2015) 
 23766                              <1> 
 23767                              <1> ;drum: / interrupt handler
 23768                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 23769                              <1> ;       jsr     r0,trapt; dcs; rfap; 1 / check for stray interrupt or
 23770                              <1> ;                                      / error
 23771                              <1> ;               br 3f / no, error
 23772                              <1> ;       br      2f / error
 23773                              <1> ;
 23774                              <1> ;disk:
 23775                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 23776                              <1> ;       jmp     *$0f
 23777                              <1> ;0:
 23778                              <1> ;       jsr     r0,trapt; rkcs; rkap; 2
 23779                              <1> ;      	        br 3f / no, errors
 23780                              <1> ;       mov     $115,(r2) / drive reset, errbit was set
 23781                              <1> ;       mov     $1f,0b-2 / next time jmp *$0f is executed jmp will be
 23782                              <1> ;                        / to 1f
 23783                              <1> ;       br      4f
 23784                              <1> ;1:
 23785                              <1> ;       bit     $20000,rkcs
 23786                              <1> ;       beq     4f / wait for seek complete
 23787                              <1> ;       mov     $0b,0b-2
 23788                              <1> ;       mov     rkap,r1
 23789                              <1> ;2:
 23790                              <1> ;       bit     $3000,(r1) / are bits 9 or 10 set in the 1st word of
 23791                              <1> ;                          / the disk buffer
 23792                              <1> ;       bne     3f / no, branch ignore error if outstanding
 23793                              <1> ;       inc     r1
 23794                              <1> ;       asr     (r1)
 23795                              <1> ;       asr     (r1)
 23796                              <1> ;       asr     (r1) / reissue request
 23797                              <1> ;       dec     r1
 23798                              <1> ;3:
 23799                              <1> ;       bic     $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
 23800                              <1> ;       mov     ac,-(sp)
 23801                              <1> ;       mov     mq,-(sp) / put these on the stack
 23802                              <1> ;       mov     sc,-(sp)
 23803                              <1> ;       jsr     r0,poke
 23804                              <1> ;       mov     (sp)+,sc
 23805                              <1> ;       mov     (sp)+,mq / pop them off stack
 23806                              <1> ;       mov     (sp)+,ac
 23807                              <1> ;4:
 23808                              <1> ;       jmp     retisp / u4-3
 23809                              <1> ;
 23810                              <1> ;trapt:                  / r2 points to the
 23811                              <1> ;       mov     (r0)+,r2 / device control register
 23812                              <1> ;       mov     *(r0)+,r1 / transaction pointer points to buffer
 23813                              <1> ;       tst     (sp)+
 23814                              <1> ;       tstb    (r2) / is ready bit of dcs set?
 23815                              <1> ;       bge     4b / device still active so branch
 23816                              <1> ;       bit     (r0),active / was device busy?
 23817                              <1> ;       beq     4b / no, stray interrupt
 23818                              <1> ;       bic     (r0)+,active / yes, set active to zero
 23819                              <1> ;       tst     (r2) / test the err(bit is) of dcs
 23820                              <1> ;       bge     2f / if no error jump to 2f
 23821                              <1> ;       tst     (r0)+ / skip on error
 23822                              <1> ; 2:
 23823                              <1> ;       jmp     (r0)
 23824                                  %include 'u9.s'        ; 29/06/2015
 23825                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
 23826                              <1> ; Last Modification: 21/11/2015
 23827                              <1> ; ----------------------------------------------------------------------------
 23828                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 23829                              <1> ; (v0.1 - Beginning: 11/07/2012)
 23830                              <1> ;
 23831                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 23832                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 23833                              <1> ; <Bell Laboratories (17/3/1972)>
 23834                              <1> ; <Preliminary Release of UNIX Implementation Document>
 23835                              <1> ;
 23836                              <1> ; Retro UNIX 8086 v1 - U9.ASM (01/09/2014) //// UNIX v1 -> u9.s
 23837                              <1> ;
 23838                              <1> ; ****************************************************************************
 23839                              <1> 
 23840                              <1> getch:
 23841                              <1> 	; 30/06/2015
 23842                              <1> 	; 18/02/2015 - Retro UNIX 386 v1 - feature only!
 23843 0000649A 28C0                <1> 	sub	al, al ; 0
 23844                              <1> getch_q: ; 06/08/2015
 23845 0000649C 8A25[A6700000]      <1> 	mov 	ah, [ptty] ; active (current) video page
 23846 000064A2 EB06                <1>         jmp     short getc_n
 23847                              <1> 
 23848                              <1> getc: 
 23849                              <1> 	; 12/11/2015
 23850                              <1> 	; 15/09/2015
 23851                              <1> 	; 01/07/2015
 23852                              <1> 	; 30/06/2015
 23853                              <1> 	; 18/02/2015 (Retro UNIX 386 v1 - Beginning)
 23854                              <1> 	; 13/05/2013 - 04/07/2014 (Retro UNIX 8086 v1)
 23855                              <1> 	;
 23856                              <1> 	; Retro UNIX 8086 v1 modification !
 23857                              <1> 	; 
 23858                              <1> 	; 'getc' gets (next) character 
 23859                              <1> 	;	 from requested TTY (keyboard) buffer 
 23860                              <1> 	; INPUTS ->
 23861                              <1> 	;     [u.ttyn] = tty number (0 to 7) (8 is COM1, 9 is COM2)	
 23862                              <1> 	;     AL=0 -> Get (next) character from requested TTY buffer
 23863                              <1> 	;	(Keyboard buffer will point to 
 23864                              <1> 	;			next character at next call)
 23865                              <1> 	;     AL=1 -> Test a key is available in requested TTY buffer
 23866                              <1> 	;	(Keyboard buffer will point to 
 23867                              <1> 	;			current character at next call)
 23868                              <1> 	; OUTPUTS ->
 23869                              <1> 	;     (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 23870                              <1> 	;     			 ZF=0 -> AX has (current) character
 23871                              <1> 	;      AL = ascii code
 23872                              <1> 	;      AH = scan code	(AH = line status for COM1 or COM2)	 			
 23873                              <1> 	; 		        (cf=1 -> error code/flags in AH)
 23874                              <1> 	; Original UNIX V1 'getc': 
 23875                              <1> 	;		get a character off character list
 23876                              <1> 	;
 23877                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))	
 23878                              <1> 	;
 23879                              <1> 	; 30/06/20045 (32 bit modifications)
 23880                              <1> 	; 16/07/2013
 23881                              <1> 	; mov 	[getctty], ah
 23882                              <1> 	;
 23883                              <1> 
 23884 000064A4 8A25[A6740000]      <1> 	mov	ah, [u.ttyn] 	; 28/07/2013
 23885                              <1> getc_n:
 23886                              <1> 	; 30/06/2015
 23887 000064AA 08E4                <1> 	or	ah, ah
 23888 000064AC 740D                <1> 	jz	short getc0 
 23889 000064AE D0E4                <1> 	shl	ah, 1
 23890 000064B0 0FB6DC              <1> 	movzx	ebx, ah
 23891 000064B3 81C3[A8700000]      <1> 	add	ebx, ttychr
 23892 000064B9 EB05                <1> 	jmp	short getc1
 23893                              <1> getc0:
 23894 000064BB BB[A8700000]        <1> 	mov	ebx, ttychr
 23895                              <1> getc1:
 23896 000064C0 668B0B              <1> 	mov	cx, [ebx] 	; ascii & scan code
 23897                              <1> 				; (by kb_int)	
 23898 000064C3 6609C9              <1> 	or	cx, cx
 23899 000064C6 7508                <1> 	jnz	short getc2
 23900 000064C8 20C0                <1> 	and 	al, al
 23901 000064CA 7416                <1> 	jz	short getc_s
 23902 000064CC 6631C0              <1> 	xor	ax, ax
 23903 000064CF C3                  <1> 	retn
 23904                              <1> getc2:	
 23905 000064D0 20C0                <1> 	and	al, al
 23906 000064D2 6689C8              <1> 	mov	ax, cx
 23907 000064D5 66B90000            <1> 	mov	cx, 0
 23908 000064D9 7506                <1> 	jnz	short getc3
 23909                              <1> getc_sn:
 23910 000064DB 66890B              <1> 	mov	[ebx], cx ; 0, reset
 23911 000064DE 6639C8              <1> 	cmp	ax, cx  ; zf = 0
 23912                              <1> getc3:
 23913 000064E1 C3                  <1> 	retn
 23914                              <1> getc_s:
 23915                              <1> 	; 12/11/2015
 23916                              <1> 	; 15/09/2015
 23917                              <1> 	; 01/07/2015
 23918                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 23919                              <1> 	; 16/07/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 23920                              <1> 	;
 23921                              <1> 	; tty  of the current process is not 
 23922                              <1> 	; current tty (ptty); so, current process only 
 23923                              <1> 	; can use keyboard input when its tty becomes 
 23924                              <1> 	; current tty (ptty).
 23925                              <1> 	; 'sleep' is for preventing an endless lock
 23926                              <1> 	; during this tty input request.
 23927                              <1> 	; (Because, the user is not looking at the video page
 23928                              <1> 	; of the process to undersand there is a keyboard
 23929                              <1> 	; input request.)
 23930                              <1> 	;
 23931                              <1> 	;((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 23932                              <1> 	;
 23933                              <1> 	; 05/10/2013
 23934                              <1> 	; ah = byte ptr [u.ttyn] ; (tty number)
 23935                              <1> 	;
 23936                              <1> 	; 10/10/2013
 23937                              <1> gcw0:
 23938 000064E2 B10A                <1> 	mov	cl, 10 ; ch = 0
 23939                              <1> gcw1:	
 23940                              <1> 	; 12/11/2015
 23941 000064E4 E866DCFFFF          <1> 	call intract ; jumps to 'sysexit' if [u.quit] = FFFFh
 23942                              <1> 	; 10/10/2013
 23943 000064E9 E871EFFFFF          <1> 	call	idle
 23944 000064EE 668B03              <1> 	mov	ax, [ebx] 	; ascii & scan code
 23945                              <1> 				; (by kb_int)
 23946 000064F1 6609C0              <1> 	or	ax, ax
 23947                              <1> ;	jnz	short gcw3
 23948 000064F4 7519                <1> 	jnz	short gcw2 ; 15/09/2015
 23949                              <1> 	; 30/06/2015
 23950 000064F6 FEC9                <1> 	dec	cl
 23951 000064F8 75EA                <1> 	jnz	short gcw1
 23952                              <1> 	;
 23953 000064FA 8A25[A6740000]      <1> 	mov	ah, [u.ttyn] 	; 20/10/2013
 23954                              <1> ;	; 10/12/2013
 23955                              <1> ;	cmp 	ah, [ptty]
 23956                              <1> ;	jne	short gcw2
 23957                              <1> ;	; 14/02/2014
 23958                              <1> ;	cmp	byte [u.uno], 1
 23959                              <1> ;	jna	short gcw0		
 23960                              <1> ;gcw2:
 23961 00006500 E8EEEFFFFF          <1> 	call	sleep
 23962                              <1> 	;
 23963                              <1> 	; 20/09/2013
 23964 00006505 8A25[A6740000]      <1> 	mov	ah, [u.ttyn]
 23965 0000650B 30C0                <1> 	xor 	al, al
 23966 0000650D EB9B                <1> 	jmp	short getc_n
 23967                              <1> ;gcw3:
 23968                              <1> gcw2: 	; 15/09/2015
 23969                              <1> 	; 10/10/2013
 23970 0000650F 30C9                <1> 	xor	cl, cl
 23971 00006511 EBC8                <1> 	jmp	short getc_sn
 23972                              <1> 
 23973                              <1> sndc:   ; <Send character>
 23974                              <1> 	;
 23975                              <1> 	; 21/11/2015
 23976                              <1> 	; 18/11/2015
 23977                              <1> 	; 17/11/2015
 23978                              <1> 	; 16/11/2015
 23979                              <1> 	; 11/11/2015
 23980                              <1> 	; 10/11/2015
 23981                              <1> 	; 09/11/2015
 23982                              <1> 	; 08/11/2015
 23983                              <1> 	; 07/11/2015
 23984                              <1> 	; 06/11/2015 (serial4.asm, 'sendchr')	
 23985                              <1> 	; 29/10/2015
 23986                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 23987                              <1> 	; 14/05/2013 - 28/07/2014 (Retro UNIX 8086 v1)
 23988                              <1> 	;
 23989                              <1> 	; Retro UNIX 8086 v1 feature only !
 23990                              <1> 	;
 23991                              <1> 	; ah = [u.ttyn]
 23992                              <1> 	;
 23993                              <1> 	; 30/06/2015
 23994 00006513 80EC08              <1> 	sub	ah, 8 ; ; 0 = tty8 or 1 = tty9
 23995                              <1> 	; 07/11/2015
 23996 00006516 0FB6DC              <1> 	movzx	ebx, ah ; serial port index (0 or 1)
 23997                              <1> sndc0:
 23998                              <1> 	; 07/11/2015
 23999 00006519 E82EF0FFFF          <1> 	call	isintr ; quit (ctrl+break) check
 24000 0000651E 7405                <1> 	jz	short sndc1
 24001 00006520 E82ADCFFFF          <1> 	call	intract ; quit (ctrl+break) check
 24002                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 24003                              <1> sndc1:
 24004                              <1> 	; 16/11/2015
 24005 00006525 6689C1              <1> 	mov	cx, ax	; *** al = character (to be sent)
 24006                              <1> sndcx:
 24007 00006528 8A83[EA700000]      <1> 	mov	al, [ebx+schar] ; last sent character
 24008 0000652E 8AA3[E8700000]      <1> 	mov	ah, [ebx+rchar] ; last received character
 24009                              <1> 	;
 24010                              <1> 	; 17/11/2015
 24011                              <1> 	; check 'request for response' status
 24012 00006534 80BB[E4700000]00    <1> 	cmp	byte [ebx+req_resp], 0
 24013 0000653B 7411                <1> 	jz	short query
 24014                              <1> 	; 18/11/2015
 24015 0000653D C683[E4700000]00    <1> 	mov	byte [ebx+req_resp], 0
 24016                              <1> response:
 24017 00006544 FE05[E7700000]      <1> 	inc 	byte [comqr] ; query or response status
 24018 0000654A B0FF                <1> 	mov	al, 0FFh	 
 24019 0000654C EB14                <1> 	jmp	short sndc3
 24020                              <1> query:
 24021 0000654E 08C0                <1> 	or 	al, al  ; 0 = query (also end of text)
 24022 00006550 750E                <1> 	jnz 	short sndc2 ; normal character
 24023                              <1> 	;cmp 	ah, 0FFh     ; is it responded by terminal ?
 24024                              <1> 	;je	short sndc2  ; yes, already responded
 24025                              <1> 	; 16/11/2015
 24026                              <1> 	; query: request for response (again)
 24027 00006552 8883[E8700000]      <1> 	mov	[ebx+rchar], al ; 0 ; reset
 24028 00006558 FE05[E7700000]      <1> 	inc 	byte [comqr] ; query or response status
 24029 0000655E EB02                <1> 	jmp	short sndc3
 24030                              <1> sndc2:
 24031 00006560 88C8                <1> 	mov	al, cl 	; *** character (to be sent)
 24032                              <1> sndc3:
 24033 00006562 8883[EA700000]      <1> 	mov	[ebx+schar], al ; current character (to be sent)
 24034 00006568 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 24035                              <1> 	; 30/06/2015
 24036 0000656A E883D5FFFF          <1> 	call	sp_status ; get serial port status
 24037                              <1> 	; AL = Line status, AH = Modem status
 24038                              <1> 	; 07/11/2015
 24039 0000656F A880                <1> 	test	al, 80h
 24040 00006571 7504                <1> 	jnz	short sndc4
 24041 00006573 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 24042 00006575 751D                <1> 	jnz	short sndc5
 24043                              <1> sndc4: 	; Check line status again
 24044                              <1> 	; 16/11/2015
 24045 00006577 6651                <1> 	push	cx
 24046 00006579 B906000000          <1> 	mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 24047 0000657E E866B0FFFF          <1> 	call	WAITF
 24048 00006583 6659                <1> 	pop	cx
 24049                              <1> 	;
 24050 00006585 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 24051 00006587 E866D5FFFF          <1> 	call	sp_status ; get serial port status
 24052                              <1> 	; 16/11/2015
 24053                              <1> 	; 09/11/2015
 24054                              <1> 	; 08/11/2015
 24055 0000658C A880                <1> 	test	al, 80h	; time out error
 24056 0000658E 756C                <1>         jnz     short sndc7
 24057 00006590 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 24058 00006592 7468                <1>         jz	short sndc7
 24059                              <1> sndc5:  
 24060 00006594 8A83[EA700000]      <1> 	mov	al, [ebx+schar] ; character (to be sent)
 24061 0000659A 66BAF803            <1> 	mov	dx, 3F8h   ; data port (COM2)
 24062 0000659E 28DE                <1> 	sub	dh, bl
 24063 000065A0 EE                  <1> 	out	dx, al	   ; send on serial port
 24064                              <1> 	; 10/11/2015
 24065                              <1> 	; delay for 3*30 (3*(15..80)) micro seconds
 24066                              <1> 	; (to improve text flow to the terminal)
 24067                              <1> 	; ('diskette.inc': 'WAITF')
 24068                              <1> 	; Uses port 61h, bit 4 to have CPU speed independent waiting.
 24069                              <1> 	; (refresh periods = 1 per 30 microseconds on most machines)
 24070 000065A1 6651                <1> 	push	cx 
 24071 000065A3 B906000000          <1> 	mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 24072 000065A8 E83CB0FFFF          <1> 	call	WAITF
 24073 000065AD 6659                <1> 	pop	cx
 24074                              <1>     	;
 24075 000065AF E898EFFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 24076 000065B4 7405                <1> 	jz	short sndc6
 24077 000065B6 E894DBFFFF          <1> 	call	intract ; quit (ctrl+break) check
 24078                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 24079                              <1> 	;21/11/2015
 24080                              <1> sndc6:
 24081                              <1> 	; 18/11/2015
 24082                              <1> 	; 07/11/2015
 24083 000065BB 88D8                <1> 	mov	al, bl ; al = 0 (tty8) or 1 (tty9)
 24084 000065BD E830D5FFFF          <1> 	call	sp_status ; get serial port status
 24085                              <1> 	; AL = Line status, AH = Modem status
 24086 000065C2 3C80                <1> 	cmp	al, 80h
 24087 000065C4 7336                <1> 	jnb	short sndc7		
 24088                              <1> 	;
 24089 000065C6 803D[E7700000]01    <1> 	cmp	byte [comqr], 1  ; 'query or response' ?
 24090 000065CD 7248                <1> 	jb	short sndc8 	 ; no, normal character
 24091 000065CF 883D[E7700000]      <1> 	mov 	byte [comqr], bh ; 0 ; reset
 24092                              <1> 	; 17/11/2015
 24093 000065D5 E885EEFFFF          <1> 	call	idle
 24094                              <1> 	;
 24095 000065DA 38BB[EA700000]      <1> 	cmp	[ebx+schar], bh ; 0 ; query ?
 24096 000065E0 0F877AFFFFFF        <1>         ja      sndc2       ; response (will be followed by
 24097                              <1> 			    ; a normal character)
 24098                              <1> 	; Query request must be responded by the terminal
 24099                              <1> 	; before sending a normal character !
 24100 000065E6 53                  <1> 	push	ebx
 24101 000065E7 6651                <1> 	push	cx ; *** cl = character (to be sent)
 24102 000065E9 8A25[A6740000]      <1> 	mov	ah, [u.ttyn]
 24103 000065EF E8FFEEFFFF          <1> 	call	sleep ; this process will be awakened by
 24104                              <1> 		      ; received data available interrupt
 24105 000065F4 6659                <1> 	pop	cx ; *** cl = character (to be sent)
 24106 000065F6 5B                  <1> 	pop	ebx
 24107 000065F7 E92CFFFFFF          <1>         jmp	sndcx
 24108                              <1> sndc7:
 24109                              <1> 	 ; 16/11/2015
 24110 000065FC 803D[E7700000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 24111 00006603 7213                <1> 	jb	short sndc9 	; no
 24112                              <1> 	;
 24113 00006605 88BB[E8700000]      <1> 	mov	[ebx+rchar], bh ; 0 ; reset
 24114 0000660B 88BB[EA700000]      <1> 	mov	[ebx+schar], bh ; 0 ; reset
 24115                              <1> 	;
 24116 00006611 883D[E7700000]      <1> 	mov	byte [comqr], bh ; 0 ; reset  
 24117                              <1> sndc8:
 24118 00006617 F5                  <1> 	cmc  ; jnc -> jc, jb -> jnb
 24119                              <1> sndc9:
 24120                              <1> 	; AL = Line status, AH = Modem status
 24121 00006618 C3                  <1> 	retn
 24122                              <1> 
 24123                              <1> putc:	
 24124                              <1> 	; 13/08/2015
 24125                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 24126                              <1> 	; 15/05/2013 - 27/07/2014 (Retro UNIX 8086 v1)
 24127                              <1> 	;
 24128                              <1> 	; Retro UNIX 8086 v1 modification !
 24129                              <1> 	; 
 24130                              <1> 	; 'putc' puts a character 
 24131                              <1> 	;	 onto requested (tty) video page or
 24132                              <1> 	;	 serial port
 24133                              <1> 	; INPUTS ->
 24134                              <1> 	;     AL = ascii code of the character
 24135                              <1> 	;     AH = video page (tty) number (0 to 7)
 24136                              <1> 	;			  (8 is COM1, 9 is COM2)	
 24137                              <1> 	; OUTPUTS ->
 24138                              <1> 	;    (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 24139                              <1> 	;      			ZF=0 -> AX has (current) character
 24140                              <1> 	;     cf=0 and AH = 0 -> no error
 24141                              <1> 	;     cf=1 and AH > 0 -> error (only for COM1 and COM2)		 			
 24142                              <1> 	; 
 24143                              <1> 	; Original UNIX V1 'putc': 
 24144                              <1> 	;     put a character at the end of character list
 24145                              <1> 	;
 24146                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 24147                              <1> 	;
 24148 00006619 80FC07              <1> 	cmp	ah, 7
 24149 0000661C 0F87F1FEFFFF        <1>         ja      sndc
 24150                              <1> 	; 30/06/2015
 24151 00006622 0FB6DC              <1> 	movzx	ebx, ah
 24152                              <1> 	; 13/08/2015
 24153 00006625 B407                <1> 	mov	ah, 07h ; black background, light gray character color
 24154 00006627 E9AEAEFFFF          <1> 	jmp	write_tty ; 'video.inc'
 24155                              <1> 
 24156                              <1> get_cpos:
 24157                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 24158                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 24159                              <1> 	;
 24160                              <1> 	; INPUT -> bl = video page number
 24161                              <1> 	; RETURN -> dx = cursor position
 24162                              <1> 
 24163 0000662C 53                  <1> 	push	ebx
 24164 0000662D 83E30F              <1> 	and	ebx, 0Fh ; 07h ; tty0 to tty7
 24165 00006630 D0E3                <1> 	shl	bl, 1
 24166 00006632 81C3[96700000]      <1> 	add	ebx, cursor_posn
 24167 00006638 668B13              <1> 	mov	dx, [ebx]
 24168 0000663B 5B                  <1> 	pop	ebx
 24169 0000663C C3                  <1> 	retn
 24170                              <1> 
 24171                              <1> read_ac_current:
 24172                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 24173                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 24174                              <1> 	;
 24175                              <1> 	; INPUT -> bl = video page number
 24176                              <1> 	; RETURN -> ax = character (al) and attribute (ah)
 24177                              <1> 
 24178 0000663D E819B0FFFF          <1> 	call 	find_position ; 'video.inc'
 24179                              <1> 	; dx = status port
 24180                              <1> 	; esi = cursor location/address
 24181 00006642 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
 24182 00006648 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
 24183 0000664B C3                  <1> 	retn
 24184                              <1> 
 24185                              <1> syssleep:
 24186                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
 24187                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
 24188                              <1> 	;
 24189                              <1> 	; Retro UNIX 8086 v1 feature only
 24190                              <1> 	; (INPUT -> none)
 24191                              <1> 	;
 24192 0000664C 0FB61D[A1740000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 24193 00006653 8AA3[A5710000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 24194 00006659 E895EEFFFF          <1> 	call	sleep
 24195 0000665E E90ADAFFFF          <1> 	jmp	sysret
 24196                              <1> 
 24197                              <1> vp_clr:
 24198                              <1> 	; Reset/Clear Video Page
 24199                              <1> 	;
 24200                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
 24201                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
 24202                              <1> 	;
 24203                              <1> 	; Retro UNIX 8086 v1 feature only !
 24204                              <1> 	;
 24205                              <1> 	; INPUTS -> 
 24206                              <1> 	;   BL = video page number	 
 24207                              <1> 	;
 24208                              <1> 	; OUTPUT ->
 24209                              <1> 	;   none
 24210                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
 24211                              <1> 	;
 24212                              <1> 	; 04/12/2013
 24213 00006663 28C0                <1> 	sub	al, al
 24214                              <1> 	; al = 0 (clear video page)
 24215                              <1> 	; bl = video page
 24216 00006665 B407                <1> 	mov	ah, 07h
 24217                              <1> 	; ah = 7 (attribute/color)
 24218 00006667 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
 24219 0000666A 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
 24220 0000666E E814B0FFFF          <1> 	call	scroll_up
 24221                              <1> 	; bl = video page
 24222 00006673 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
 24223 00006676 E983AFFFFF          <1> 	jmp 	set_cpos
 24224                              <1> 
 24225                              <1> sysmsg:
 24226                              <1> 	; 11/11/2015
 24227                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
 24228                              <1> 	; Print user-application message on user's console tty
 24229                              <1> 	;
 24230                              <1> 	; Input -> EBX = Message address
 24231                              <1> 	;	   ECX = Message length (max. 255)
 24232                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
 24233                              <1> 	;
 24234 0000667B 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
 24235 00006681 0F87E6D9FFFF        <1> 	ja	sysret ; nothing to do with big message size
 24236 00006687 08C9                <1> 	or	cl, cl
 24237 00006689 0F84DED9FFFF        <1> 	jz	sysret
 24238 0000668F 20D2                <1> 	and	dl, dl
 24239 00006691 7502                <1> 	jnz	short sysmsg0
 24240 00006693 B207                <1> 	mov	dl, 07h ; default color
 24241                              <1> 		; (black background, light gray character) 
 24242                              <1> sysmsg0:
 24243 00006695 891D[78740000]      <1> 	mov	[u.base], ebx
 24244 0000669B 8815[A7700000]      <1> 	mov	[ccolor], dl ; color attributes
 24245 000066A1 89E5                <1> 	mov	ebp, esp
 24246 000066A3 31DB                <1> 	xor	ebx, ebx ; 0
 24247 000066A5 891D[80740000]      <1> 	mov	[u.nread], ebx ; 0
 24248                              <1> 	;
 24249 000066AB 381D[B9740000]      <1> 	cmp	[u.kcall], bl ; 0
 24250 000066B1 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
 24251                              <1> 	;
 24252 000066B3 890D[7C740000]      <1> 	mov	[u.count], ecx
 24253 000066B9 41                  <1> 	inc	ecx ; + 00h ; ASCIZZ
 24254 000066BA 29CC                <1> 	sub	esp, ecx
 24255 000066BC 89E7                <1> 	mov	edi, esp
 24256 000066BE 89E6                <1> 	mov	esi, esp
 24257 000066C0 66891D[B7740000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
 24258                              <1> 	; 11/11/2015
 24259 000066C7 8A25[88740000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
 24260                              <1> 	; 0 = none
 24261 000066CD FECC                <1> 	dec	ah
 24262 000066CF 790C                <1> 	jns	short sysmsg1 
 24263 000066D1 8A1D[A1740000]      <1> 	mov	bl, [u.uno] ; process number	
 24264 000066D7 8AA3[A5710000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
 24265                              <1> sysmsg1:
 24266 000066DD 8825[A6740000]      <1> 	mov	[u.ttyn], ah
 24267                              <1> sysmsg2:
 24268 000066E3 E895F5FFFF          <1> 	call	cpass
 24269 000066E8 7416                <1> 	jz	short sysmsg5
 24270 000066EA AA                  <1> 	stosb
 24271 000066EB 20C0                <1> 	and	al, al
 24272 000066ED 75F4                <1> 	jnz	short sysmsg2
 24273                              <1> sysmsg3:
 24274 000066EF 80FC07              <1> 	cmp	ah, 7 ; tty number
 24275 000066F2 7711                <1> 	ja	short sysmsg6 ; serial port
 24276 000066F4 E83E000000          <1> 	call	print_cmsg
 24277                              <1> sysmsg4:
 24278 000066F9 89EC                <1> 	mov	esp, ebp	
 24279 000066FB E96DD9FFFF          <1> 	jmp	sysret
 24280                              <1> sysmsg5:
 24281 00006700 C60700              <1> 	mov	byte [edi], 0
 24282 00006703 EBEA                <1> 	jmp	short sysmsg3
 24283                              <1> sysmsg6:
 24284 00006705 8A06                <1> 	mov	al, [esi]
 24285 00006707 E807FEFFFF          <1> 	call	sndc
 24286 0000670C 72EB                <1> 	jc	short sysmsg4
 24287 0000670E 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
 24288 00006711 76E6                <1> 	jna	short sysmsg4
 24289 00006713 46                  <1> 	inc 	esi
 24290 00006714 8A25[A6740000]      <1> 	mov	ah, [u.ttyn]
 24291 0000671A EBE9                <1> 	jmp	short sysmsg6
 24292                              <1> 
 24293                              <1> sysmsgk: ; Temporary (01/07/2015)
 24294                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
 24295                              <1> 	; (ECX -character count- will not be considered)
 24296 0000671C 8B35[78740000]      <1> 	mov	esi, [u.base]
 24297 00006722 8A25[A6700000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
 24298 00006728 8825[A6740000]      <1> 	mov	[u.ttyn], ah
 24299 0000672E C605[B9740000]00    <1> 	mov	byte [u.kcall], 0
 24300 00006735 EBB8                <1> 	jmp	short sysmsg3
 24301                              <1> 	
 24302                              <1> 
 24303                              <1> print_cmsg: 
 24304                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
 24305                              <1> 	;
 24306                              <1> 	; print message (on user's console tty) 
 24307                              <1> 	;	with requested color
 24308                              <1> 	;
 24309                              <1> 	; INPUTS:
 24310                              <1> 	;	esi = message address
 24311                              <1> 	;	[u.ttyn] = tty number (0 to 7)
 24312                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
 24313                              <1> 	;
 24314 00006737 AC                  <1> 	lodsb
 24315                              <1> pcmsg1:
 24316 00006738 56                  <1> 	push 	esi
 24317 00006739 0FB61D[A6740000]    <1>         movzx   ebx, byte [u.ttyn]
 24318 00006740 8A25[A7700000]      <1> 	mov	ah, [ccolor]
 24319 00006746 E88FADFFFF          <1> 	call 	write_tty
 24320 0000674B 5E                  <1> 	pop	esi
 24321 0000674C AC                  <1> 	lodsb
 24322 0000674D 20C0                <1> 	and 	al, al  ; 0
 24323 0000674F 75E7                <1> 	jnz 	short pcmsg1
 24324 00006751 C3                  <1> 	retn
 24325                              <1> 
 24326                              <1> sysgeterr:
 24327                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
 24328                              <1> 	; Get last error number or page fault count
 24329                              <1> 	; (for debugging)
 24330                              <1> 	;
 24331                              <1> 	; Input -> EBX = return type
 24332                              <1> 	;	   0 = last error code (which is in 'u.error')	
 24333                              <1> 	;	   FFFFFFFFh = page fault count for running process
 24334                              <1> 	;	   FFFFFFFEh = total page fault count
 24335                              <1> 	;	   1 .. FFFFFFFDh = undefined 
 24336                              <1> 	;
 24337                              <1> 	; Output -> EAX = last error number or page fault count
 24338                              <1> 	;	   (depending on EBX input)
 24339                              <1> 	; 	
 24340 00006752 21DB                <1> 	and 	ebx, ebx
 24341 00006754 750B                <1> 	jnz	short glerr_2
 24342                              <1> glerr_0:
 24343 00006756 A1[A7740000]        <1> 	mov	eax, [u.error]
 24344                              <1> glerr_1:
 24345 0000675B A3[58740000]        <1> 	mov	[u.r0], eax
 24346 00006760 C3                  <1>  	retn
 24347                              <1> glerr_2:
 24348 00006761 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
 24349 00006762 74FD                <1> 	jz	short glerr_2 ; page fault count for process
 24350 00006764 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
 24351 00006765 75EF                <1> 	jnz	short glerr_0
 24352 00006767 A1[38850000]        <1> 	mov	eax, [PF_Count] ; total page fault count
 24353 0000676C EBED                <1>         jmp     short glerr_1
 24354                              <1> glerr_3:
 24355 0000676E A1[BB740000]        <1> 	mov 	eax, [u.pfcount]
 24356 00006773 EBE6                <1> 	jmp	short glerr_1
 24357                                  
 24358                                  ; 07/03/2015
 24359                                  ; Temporary Code
 24360                                  display_disks:
 24361 00006775 803D[2E6B0000]00        	cmp 	byte [fd0_type], 0
 24362 0000677C 7605                    	jna 	short ddsks1
 24363 0000677E E87D000000              	call	pdskm
 24364                                  ddsks1:
 24365 00006783 803D[2F6B0000]00        	cmp	byte [fd1_type], 0
 24366 0000678A 760C                    	jna	short ddsks2
 24367 0000678C C605[596D0000]31        	mov	byte [dskx], '1'
 24368 00006793 E868000000              	call	pdskm
 24369                                  ddsks2:
 24370 00006798 803D[306B0000]00        	cmp	byte [hd0_type], 0
 24371 0000679F 7654                    	jna	short ddsk6
 24372 000067A1 66C705[576D0000]68-     	mov	word [dsktype], 'hd'
 24373 000067A9 64                 
 24374 000067AA C605[596D0000]30        	mov	byte [dskx], '0'
 24375 000067B1 E84A000000              	call	pdskm
 24376                                  ddsks3:
 24377 000067B6 803D[316B0000]00        	cmp	byte [hd1_type], 0
 24378 000067BD 7636                    	jna	short ddsk6
 24379 000067BF C605[596D0000]31        	mov	byte [dskx], '1'
 24380 000067C6 E835000000              	call	pdskm
 24381                                  ddsks4:
 24382 000067CB 803D[326B0000]00        	cmp	byte [hd2_type], 0
 24383 000067D2 7621                    	jna	short ddsk6
 24384 000067D4 C605[596D0000]32        	mov	byte [dskx], '2'
 24385 000067DB E820000000              	call	pdskm
 24386                                  ddsks5:
 24387 000067E0 803D[336B0000]00        	cmp	byte [hd3_type], 0
 24388 000067E7 760C                    	jna	short ddsk6
 24389 000067E9 C605[596D0000]33        	mov	byte [dskx], '3'
 24390 000067F0 E80B000000              	call	pdskm
 24391                                  ddsk6:
 24392 000067F5 BE[686D0000]            	mov	esi, nextline
 24393 000067FA E806000000              	call	pdskml
 24394                                  pdskm_ok:
 24395 000067FF C3                      	retn
 24396                                  pdskm:
 24397 00006800 BE[556D0000]            	mov	esi, dsk_ready_msg
 24398                                  pdskml:	
 24399 00006805 AC                      	lodsb
 24400 00006806 08C0                    	or	al, al
 24401 00006808 74F5                    	jz	short pdskm_ok
 24402 0000680A 56                      	push	esi
 24403 0000680B 31DB                    	xor	ebx, ebx ; 0
 24404                                  			; Video page 0 (bl=0)
 24405 0000680D B407                    	mov	ah, 07h ; Black background, 
 24406                                  			; light gray forecolor
 24407 0000680F E8C6ACFFFF              	call	write_tty
 24408 00006814 5E                      	pop	esi
 24409 00006815 EBEE                    	jmp	short pdskml
 24410                                  
 24411 00006817 90<rept>                align 16
 24412                                  
 24413                                  gdt:	; Global Descriptor Table
 24414                                  	; (30/07/2015, conforming cs)
 24415                                  	; (26/03/2015)
 24416                                  	; (24/03/2015, tss)
 24417                                  	; (19/03/2015)
 24418                                  	; (29/12/2013)
 24419                                  	;
 24420 00006820 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
 24421                                  	; 18/08/2014
 24422                                  			; 8h kernel code segment, base = 00000000h		
 24423 00006828 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
 24424                                  			; 10h kernel data segment, base = 00000000h	
 24425 00006830 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
 24426                                  			; 1Bh user code segment, base address = 400000h ; CORE
 24427 00006838 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
 24428                                  			; 23h user data segment, base address = 400000h ; CORE
 24429 00006840 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
 24430                                  			; Task State Segment
 24431 00006848 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
 24432                                  			       ;  no IO permission in ring 3)
 24433                                  gdt_tss0:
 24434 0000684A 0000                    	dw 0  ; TSS base address, bits 0-15 
 24435                                  gdt_tss1:
 24436 0000684C 00                      	db 0  ; TSS base address, bits 16-23 
 24437                                  	      		; 49h	
 24438 0000684D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
 24439 0000684E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
 24440                                  gdt_tss2:
 24441 0000684F 00                      	db 0  ; TSS base address, bits 24-31 
 24442                                  
 24443                                  gdt_end:
 24444                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 24445                                  					;; Type= 1 (code)/C=0/R=1/A=0
 24446                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 24447                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 24448                                  
 24449                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 24450                                  					;; Type= 0 (data)/E=0/W=1/A=0
 24451                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 24452                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 24453                                  		; W= Writeable, A= Accessed
 24454                                  	
 24455                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
 24456                                  					;; Type= 1 (code)/C=0/R=1/A=0
 24457                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 24458                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 24459                                  
 24460                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
 24461                                  					;; Type= 0 (data)/E=0/W=1/A=0
 24462                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 24463                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 24464                                  	
 24465                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
 24466                                  
 24467                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
 24468                                  		;	 = 100000h * 1000h (G=1) = 4GB
 24469                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
 24470                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
 24471                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
 24472                                  		; AVL= Available to programmers	
 24473                                  
 24474                                  gdtd:
 24475 00006850 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
 24476 00006852 [20680000]                      dd gdt			; Address of the GDT
 24477                                  
 24478                                  	; 20/08/2014
 24479                                  idtd:
 24480 00006856 FF01                            dw idt_end - idt - 1    ; Limit (size)
 24481 00006858 [106E0000]                      dd idt			; Address of the IDT
 24482                                  
 24483                                  Align 4
 24484                                  
 24485                                  	; 21/08/2014
 24486                                  ilist:
 24487                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
 24488                                  	;
 24489                                  	; Exception list
 24490                                  	; 25/08/2014	
 24491 0000685C [F1080000]              	dd	exc0	; 0h,  Divide-by-zero Error
 24492 00006860 [F8080000]              	dd	exc1	
 24493 00006864 [FF080000]              	dd 	exc2	
 24494 00006868 [06090000]              	dd	exc3	
 24495 0000686C [0A090000]              	dd	exc4	
 24496 00006870 [0E090000]              	dd	exc5	
 24497 00006874 [12090000]              	dd 	exc6	; 06h,  Invalid Opcode
 24498 00006878 [16090000]              	dd	exc7	
 24499 0000687C [1A090000]              	dd	exc8	
 24500 00006880 [1E090000]              	dd	exc9	
 24501 00006884 [22090000]              	dd 	exc10	
 24502 00006888 [26090000]              	dd	exc11
 24503 0000688C [2A090000]              	dd	exc12
 24504 00006890 [2E090000]              	dd	exc13	; 0Dh, General Protection Fault
 24505 00006894 [32090000]              	dd 	exc14	; 0Eh, Page Fault
 24506 00006898 [36090000]              	dd	exc15
 24507 0000689C [3A090000]              	dd	exc16
 24508 000068A0 [3E090000]              	dd	exc17
 24509 000068A4 [42090000]              	dd 	exc18
 24510 000068A8 [46090000]              	dd	exc19
 24511 000068AC [4A090000]              	dd 	exc20
 24512 000068B0 [4E090000]              	dd	exc21
 24513 000068B4 [52090000]              	dd	exc22
 24514 000068B8 [56090000]              	dd	exc23
 24515 000068BC [5A090000]              	dd 	exc24
 24516 000068C0 [5E090000]              	dd	exc25
 24517 000068C4 [62090000]              	dd	exc26
 24518 000068C8 [66090000]              	dd	exc27
 24519 000068CC [6A090000]              	dd 	exc28
 24520 000068D0 [6E090000]              	dd	exc29
 24521 000068D4 [72090000]              	dd 	exc30
 24522 000068D8 [76090000]              	dd	exc31
 24523                                  	; Interrupt list
 24524 000068DC [27070000]              	dd	timer_int	; INT 20h
 24525                                  		;dd	irq0	
 24526 000068E0 [300C0000]              	dd	keyb_int	; 27/08/2014
 24527                                  		;dd	irq1
 24528 000068E4 [47080000]              	dd	irq2
 24529                                  		; COM2 int
 24530 000068E8 [4B080000]              	dd	irq3
 24531                                  		; COM1 int
 24532 000068EC [56080000]              	dd	irq4
 24533 000068F0 [61080000]              	dd	irq5
 24534                                  ;DISKETTE_INT: ;06/02/2015
 24535 000068F4 [6D270000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
 24536                                  		;dd	irq6
 24537                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
 24538                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 24539 000068F8 [DD0B0000]              	dd	default_irq7	; 25/02/2015
 24540                                  		;dd	irq7
 24541                                  ; Real Time Clock Interrupt
 24542 000068FC [800A0000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
 24543                                  		;dd	irq8	; INT 28h
 24544 00006900 [71080000]              	dd	irq9
 24545 00006904 [75080000]              	dd	irq10
 24546 00006908 [79080000]              	dd	irq11
 24547 0000690C [7D080000]              	dd	irq12
 24548 00006910 [81080000]              	dd	irq13
 24549                                  ;HDISK_INT1:  ;06/02/2015 	
 24550 00006914 [A82F0000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
 24551                                  		;dd	irq14
 24552                                  ;HDISK_INT2:  ;06/02/2015
 24553 00006918 [CF2F0000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
 24554                                  		;dd	irq15	; INT 2Fh
 24555                                  		; 14/08/2015
 24556 0000691C [513F0000]              	dd	sysent		; INT 30h (system calls)
 24557                                  	
 24558                                  	;dd	ignore_int
 24559 00006920 00000000                	dd	0
 24560                                  
 24561                                  ;;;
 24562                                  ;;; 11/03/2015
 24563                                  %include 'kybdata.inc'	; KEYBOARD (BIOS) DATA
 24564                              <1> ; Retro UNIX 386 v1 Kernel - KYBDATA.INC
 24565                              <1> ; Last Modification: 11/03/2015
 24566                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
 24567                              <1> ;
 24568                              <1> ; ///////// KEYBOARD DATA ///////////////
 24569                              <1> 
 24570                              <1> ; 05/12/2014
 24571                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
 24572                              <1> ; 03/06/86  KEYBOARD BIOS
 24573                              <1> 
 24574                              <1> ;---------------------------------------------------------------------------------
 24575                              <1> ;	KEY IDENTIFICATION SCAN TABLES
 24576                              <1> ;---------------------------------------------------------------------------------
 24577                              <1> 
 24578                              <1> ;-----	TABLES FOR ALT CASE ------------
 24579                              <1> ;-----	ALT-INPUT-TABLE 
 24580 00006924 524F50514B          <1> K30:	db	82,79,80,81,75
 24581 00006929 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
 24582                              <1> ;-----	SUPER-SHIFT-TABLE 
 24583 0000692E 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
 24584 00006934 161718191E1F        <1> 	db	22,23,24,25,30,31
 24585 0000693A 202122232425        <1> 	db	32,33,34,35,36,37
 24586 00006940 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
 24587 00006946 3132                <1> 	db	49,50
 24588                              <1> 
 24589                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
 24590                              <1> ;-----	KEY_TABLE 
 24591 00006948 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
 24592 00006949 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
 24593 0000694E 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
 24594                              <1> _K6L    equ     $-_K6
 24595                              <1> 
 24596                              <1> ;-----	MASK_TABLE
 24597 00006950 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
 24598 00006951 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
 24599 00006956 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
 24600                              <1> 
 24601                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
 24602 00006958 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
 24603 0000695E 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
 24604 00006964 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
 24605 0000696A 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
 24606 00006970 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
 24607 00006976 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
 24608 0000697C 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
 24609 00006982 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
 24610 00006988 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
 24611 0000698E 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
 24612                              <1> 	;				;----- FUNCTIONS ------		
 24613 00006992 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
 24614 00006998 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
 24615 0000699E 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
 24616 000069A4 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
 24617 000069AA 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
 24618                              <1> 
 24619                              <1> ;-----	TABLES FOR LOWER CASE ----------
 24620 000069B0 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
 24621 000069B9 39302D3D0809        <1>
 24622 000069BF 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
 24623 000069C8 705B5D0DFF61736466- <1>
 24624 000069D1 67686A6B6C3B27      <1>
 24625 000069D8 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
 24626 000069E1 6D2C2E2FFF2AFF20FF  <1>
 24627                              <1> ;-----	LC TABLE SCAN
 24628 000069EA 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
 24629 000069EF 4041424344          <1> 	db	64,65,66,67,68
 24630 000069F4 FFFF                <1> 	db	-1,-1			; NL, SL
 24631                              <1> 
 24632                              <1> ;-----	KEYPAD TABLE
 24633 000069F6 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
 24634 000069FC 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
 24635 00006A03 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
 24636                              <1> 
 24637                              <1> ;-----	TABLES FOR UPPER CASE ----------
 24638 00006A08 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
 24639 00006A11 28295F2B0800        <1>
 24640 00006A17 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
 24641 00006A20 507B7D0DFF41534446- <1>
 24642 00006A29 47484A4B4C3A22      <1>
 24643 00006A30 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
 24644 00006A39 4D3C3E3FFF2AFF20FF  <1>
 24645                              <1> ;-----	UC TABLE SCAN
 24646 00006A42 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
 24647 00006A47 595A5B5C5D          <1> 	db	89,90,91,92,93
 24648 00006A4C FFFF                <1> 	db	-1,-1			; NL, SL
 24649                              <1> 
 24650                              <1> ;-----	NUM STATE TABLE
 24651 00006A4E 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
 24652 00006A57 3233302E            <1>
 24653                              <1> 	;
 24654 00006A5B FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
 24655                              <1> 
 24656                              <1> Align	4
 24657                              <1> ;----------------------------------------
 24658                              <1> ;	VIDEO DISPLAY DATA AREA		;
 24659                              <1> ;----------------------------------------
 24660 00006A60 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
 24661 00006A61 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
 24662                              <1> 				; (29h default setting for video mode 3)
 24663                              <1> 				; Mode Select register Bits
 24664                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
 24665                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
 24666                              <1> 				;   BIT 2 - COLOR (0), BW (1)
 24667                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
 24668                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
 24669                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
 24670                              <1> 				;   BIT 6, 7 - Not Used
 24671                              <1> 
 24672                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
 24673                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
 24674                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
 24675                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
 24676                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
 24677                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
 24678                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
 24679                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
 24680                              <1> ; Mode & 37h = Video signal OFF
 24681                              <1> 			
 24682                              <1> 
 24683                              <1> ; 26/08/2014
 24684                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
 24685                              <1> ; Derived from IBM "pc-at" 
 24686                              <1> ; rombios source code (06/10/1985)
 24687                              <1> ; 'dseg.inc'
 24688                              <1> 
 24689                              <1> ;---------------------------------------;
 24690                              <1> ;	SYSTEM DATA AREA		;
 24691                              <1> ;----------------------------------------
 24692 00006A62 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
 24693                              <1> 
 24694                              <1> ;----------------------------------------
 24695                              <1> ;	KEYBOARD DATA AREAS		;
 24696                              <1> ;----------------------------------------
 24697                              <1> 
 24698 00006A63 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
 24699 00006A64 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
 24700 00006A65 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
 24701 00006A66 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
 24702 00006A67 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
 24703 00006A68 [786A0000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
 24704 00006A6C [986A0000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
 24705 00006A70 [786A0000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
 24706 00006A74 [786A0000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
 24707                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
 24708 00006A78 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
 24709                              <1> 
 24710                              <1> ; /// End Of KEYBOARD DATA ///
 24711                                  %include 'vidata.inc'	; VIDEO (BIOS) DATA
 24712                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.INC
 24713                              <1> ; Last Modification: 11/03/2015
 24714                              <1> ;		    (Data section for 'VIDEO.INC')	
 24715                              <1> ;
 24716                              <1> ; ///////// VIDEO DATA ///////////////
 24717                              <1> 
 24718                              <1> video_params:
 24719                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
 24720                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
 24721                              <1> 	; VIDEO MODE 3
 24722 00006A98 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
 24723 00006A9F 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
 24724 00006AA4 00000000            <1> 	db	0,0,0,0
 24725                              <1> 
 24726                              <1> ; /// End Of VIDEO DATA ///
 24727                                  %include 'diskdata.inc'	; DISK (BIOS) DATA (initialized)
 24728                              <1> ; Retro UNIX 386 v1 Kernel - DISKDATA.INC
 24729                              <1> ; Last Modification: 11/03/2015
 24730                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
 24731                              <1> ;
 24732                              <1> ; *****************************************************************************
 24733                              <1> 
 24734                              <1> ;----------------------------------------
 24735                              <1> ;	80286 INTERRUPT LOCATIONS	:
 24736                              <1> ;	REFERENCED BY POST & BIOS	:
 24737                              <1> ;----------------------------------------
 24738                              <1> 
 24739 00006AA8 [0B6B0000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
 24740                              <1> 
 24741                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
 24742                              <1> ;----------------------------------------------------------------
 24743                              <1> ; DISK_BASE							:
 24744                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
 24745                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
 24746                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
 24747                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
 24748                              <1> ;----------------------------------------------------------------
 24749                              <1> 
 24750                              <1> ;DISK_BASE:	
 24751                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24752                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24753                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24754                              <1> ;	DB	2		; 512 BYTES/SECTOR
 24755                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
 24756                              <1> ;	db	18		; (EOT for 1.44MB diskette)
 24757                              <1> ;	DB	01BH		; GAP LENGTH
 24758                              <1> ;	DB	0FFH		; DTL
 24759                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
 24760                              <1> ;	db	06ch		; (for 1.44MB dsikette)
 24761                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
 24762                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24763                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24764                              <1> 
 24765                              <1> ;----------------------------------------
 24766                              <1> ;	ROM BIOS DATA AREAS		:
 24767                              <1> ;----------------------------------------
 24768                              <1> 
 24769                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 24770                              <1> 
 24771                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
 24772                              <1> 
 24773                              <1> ;----------------------------------------
 24774                              <1> ;	DISKETTE DATA AREAS		:
 24775                              <1> ;----------------------------------------
 24776                              <1> 
 24777                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
 24778                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
 24779                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
 24780                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
 24781                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
 24782                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
 24783                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
 24784                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
 24785                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
 24786                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
 24787                              <1> 
 24788                              <1> ;----------------------------------------
 24789                              <1> ;	POST AND BIOS WORK DATA AREA	:
 24790                              <1> ;----------------------------------------
 24791                              <1> 
 24792                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
 24793                              <1> 
 24794                              <1> ;----------------------------------------
 24795                              <1> ;	TIMER DATA AREA 		:
 24796                              <1> ;----------------------------------------
 24797                              <1> 
 24798                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
 24799                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
 24800                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
 24801                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
 24802                              <1> 
 24803                              <1> ;----------------------------------------
 24804                              <1> ;	ADDITIONAL MEDIA DATA		:
 24805                              <1> ;----------------------------------------
 24806                              <1> 
 24807                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 24808                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 24809                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 24810                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 24811                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 24812                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 24813                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 24814                              <1> 
 24815                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 24816                              <1> 
 24817                              <1> ;--------------------------------------------------------
 24818                              <1> ;	DRIVE TYPE TABLE				:
 24819                              <1> ;--------------------------------------------------------
 24820                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
 24821                              <1> DR_TYPE:
 24822 00006AAC 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
 24823                              <1>                 ;DW      MD_TBL1
 24824 00006AAD [CA6A0000]          <1> 		dd	MD_TBL1
 24825 00006AB1 82                  <1> 		DB	02+BIT7ON
 24826                              <1> 		;DW      MD_TBL2
 24827 00006AB2 [D76A0000]          <1>                 dd      MD_TBL2
 24828 00006AB6 02                  <1> DR_DEFAULT:	DB	02
 24829                              <1>                 ;DW      MD_TBL3
 24830 00006AB7 [E46A0000]          <1> 		dd      MD_TBL3
 24831 00006ABB 03                  <1> 		DB	03
 24832                              <1>                 ;DW      MD_TBL4
 24833 00006ABC [F16A0000]          <1> 		dd      MD_TBL4
 24834 00006AC0 84                  <1> 		DB	04+BIT7ON
 24835                              <1>                 ;DW      MD_TBL5
 24836 00006AC1 [FE6A0000]          <1> 		dd      MD_TBL5
 24837 00006AC5 04                  <1> 		DB	04
 24838                              <1>                 ;DW      MD_TBL6
 24839 00006AC6 [0B6B0000]          <1> 		dd      MD_TBL6
 24840                              <1> DR_TYPE_E       equ $                   ; END OF TABLE
 24841                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
 24842                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
 24843                              <1> ;--------------------------------------------------------
 24844                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
 24845                              <1> ;--------------------------------------------------------
 24846                              <1> ;--------------------------------------------------------
 24847                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
 24848                              <1> ;--------------------------------------------------------
 24849                              <1> MD_TBL1:        
 24850 00006ACA DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24851 00006ACB 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24852 00006ACC 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24853 00006ACD 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24854 00006ACE 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24855 00006ACF 2A                  <1> 	DB	02AH		; GAP LENGTH
 24856 00006AD0 FF                  <1> 	DB	0FFH		; DTL
 24857 00006AD1 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24858 00006AD2 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24859 00006AD3 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24860 00006AD4 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24861 00006AD5 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 24862 00006AD6 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24863                              <1> ;--------------------------------------------------------
 24864                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
 24865                              <1> ;--------------------------------------------------------
 24866                              <1> MD_TBL2:        
 24867 00006AD7 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24868 00006AD8 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24869 00006AD9 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24870 00006ADA 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24871 00006ADB 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24872 00006ADC 2A                  <1> 	DB	02AH		; GAP LENGTH
 24873 00006ADD FF                  <1> 	DB	0FFH		; DTL
 24874 00006ADE 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24875 00006ADF F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24876 00006AE0 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24877 00006AE1 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24878 00006AE2 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 24879 00006AE3 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
 24880                              <1> ;--------------------------------------------------------
 24881                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
 24882                              <1> ;--------------------------------------------------------
 24883                              <1> MD_TBL3:
 24884 00006AE4 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24885 00006AE5 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24886 00006AE6 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24887 00006AE7 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24888 00006AE8 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
 24889 00006AE9 1B                  <1> 	DB	01BH		; GAP LENGTH
 24890 00006AEA FF                  <1> 	DB	0FFH		; DTL
 24891 00006AEB 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
 24892 00006AEC F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24893 00006AED 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24894 00006AEE 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24895 00006AEF 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24896 00006AF0 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 24897                              <1> ;--------------------------------------------------------
 24898                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
 24899                              <1> ;--------------------------------------------------------
 24900                              <1> MD_TBL4:
 24901 00006AF1 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24902 00006AF2 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24903 00006AF3 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24904 00006AF4 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24905 00006AF5 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24906 00006AF6 2A                  <1> 	DB	02AH		; GAP LENGTH
 24907 00006AF7 FF                  <1> 	DB	0FFH		; DTL
 24908 00006AF8 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24909 00006AF9 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24910 00006AFA 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24911 00006AFB 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24912 00006AFC 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24913 00006AFD 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24914                              <1> ;--------------------------------------------------------
 24915                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
 24916                              <1> ;--------------------------------------------------------
 24917                              <1> MD_TBL5:
 24918 00006AFE DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24919 00006AFF 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24920 00006B00 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24921 00006B01 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24922 00006B02 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24923 00006B03 2A                  <1> 	DB	02AH		; GAP LENGTH
 24924 00006B04 FF                  <1> 	DB	0FFH		; DTL
 24925 00006B05 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24926 00006B06 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24927 00006B07 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24928 00006B08 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24929 00006B09 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24930 00006B0A 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24931                              <1> ;--------------------------------------------------------
 24932                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
 24933                              <1> ;--------------------------------------------------------
 24934                              <1> MD_TBL6:
 24935 00006B0B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24936 00006B0C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24937 00006B0D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24938 00006B0E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24939 00006B0F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
 24940 00006B10 1B                  <1> 	DB	01BH		; GAP LENGTH
 24941 00006B11 FF                  <1> 	DB	0FFH		; DTL
 24942 00006B12 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
 24943 00006B13 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24944 00006B14 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24945 00006B15 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24946 00006B16 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24947 00006B17 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 24948                              <1> 
 24949                              <1> 
 24950                              <1> ; << diskette.inc >>
 24951                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 24952                              <1> ;
 24953                              <1> ;----------------------------------------
 24954                              <1> ;	ROM BIOS DATA AREAS		:
 24955                              <1> ;----------------------------------------
 24956                              <1> 
 24957                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 24958                              <1> 
 24959                              <1> ;----------------------------------------
 24960                              <1> ;	FIXED DISK DATA AREAS		:
 24961                              <1> ;----------------------------------------
 24962                              <1> 
 24963                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
 24964                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
 24965                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
 24966                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
 24967                              <1> 
 24968                              <1> ;----------------------------------------
 24969                              <1> ;	ADDITIONAL MEDIA DATA		:
 24970                              <1> ;----------------------------------------
 24971                              <1> 
 24972                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 24973                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
 24974                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
 24975                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
 24976                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
 24977                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 24978                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 24979                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 24980                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 24981                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 24982                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 24983                              <1> 
 24984                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 24985                              <1> ;
 24986                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 24987                              <1> 
 24988                              <1> ERR_TBL:
 24989 00006B18 E0                  <1> 	db	NO_ERR
 24990 00006B19 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
 24991 00006B1D 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
 24992                              <1> 
 24993                              <1> ; 17/12/2014 (mov ax, [cfd])
 24994                              <1> ; 11/12/2014
 24995 00006B21 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
 24996                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
 24997 00006B22 01                  <1> pfd:		db 1			; previous floppy drive (for GET_PARM)
 24998                              <1> 					; (initial value of 'pfd 
 24999                              <1> 					; must be different then 'cfd' value
 25000                              <1> 					; to force updating/initializing
 25001                              <1> 					; current drive parameters) 
 25002 00006B23 90                  <1> align 2
 25003                              <1> 
 25004 00006B24 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
 25005                              <1> 			      ; (170h)
 25006 00006B26 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
 25007                              <1> 
 25008                              <1> ; 05/01/2015 
 25009 00006B28 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
 25010                              <1> 
 25011                              <1> ; *****************************************************************************
 25012                                  ;;;
 25013                                  
 25014 00006B29 90                      Align 2
 25015                                  
 25016                                  ; 12/11/2014 (Retro UNIX 386 v1)
 25017 00006B2A 00                      boot_drv:    db 0 ; boot drive number (physical)
 25018                                  ; 24/11/2014
 25019 00006B2B 00                      drv:	     db 0 
 25020 00006B2C 00                      last_drv:    db 0 ; last hdd
 25021 00006B2D 00                      hdc:         db 0  ; number of hard disk drives
 25022                                  		     ; (present/detected)
 25023                                  ;
 25024                                  ; 24/11/2014 (Retro UNIX 386 v1)
 25025                                  ; Physical drive type & flags
 25026 00006B2E 00                      fd0_type:    db 0  ; floppy drive type
 25027 00006B2F 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
 25028                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
 25029                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
 25030                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
 25031                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
 25032 00006B30 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
 25033 00006B31 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
 25034 00006B32 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
 25035 00006B33 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
 25036                                  		     ; bit 0 - Fixed disk access subset supported
 25037                                  		     ; bit 1 - Drive locking and ejecting
 25038                                  		     ; bit 2 - Enhanced disk drive support
 25039                                  		     ; bit 3 = Reserved (64 bit EDD support)
 25040                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
 25041                                  		     ; will interpret it as 'LBA ready'!)		
 25042                                  
 25043                                  ; 11/03/2015 - 10/07/2015
 25044 00006B34 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
 25045 00006B3D 0000000000         
 25046 00006B42 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
 25047 00006B4B 0000000000         
 25048 00006B50 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
 25049 00006B59 0000000000         
 25050 00006B5E 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
 25051 00006B67 000000000000000000-
 25052 00006B70 000000000000000000-
 25053 00006B79 00                 
 25054 00006B7A 00000000000000          drv.status:    db 0,0,0,0,0,0,0
 25055 00006B81 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
 25056                                  ;
 25057                                  
 25058                                  ; 27/08/2014
 25059                                  scr_row:
 25060 00006B88 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
 25061                                  scr_col:
 25062 00006B8C 00000000                	dd 0
 25063                                  
 25064                                  ;; 14/08/2015
 25065                                  ;;msgPM:
 25066                                  ;;      db "Protected mode and paging are ENABLED ... ", 0
 25067                                  msgKVER:
 25068 00006B90 526574726F20554E49-     	db "Retro UNIX 386 v1 - Kernel v0.2.0.17 [04/02/2016]", 0
 25069 00006B99 582033383620763120-
 25070 00006BA2 2D204B65726E656C20-
 25071 00006BAB 76302E322E302E3137-
 25072 00006BB4 205B30342F30322F32-
 25073 00006BBD 3031365D00         
 25074                                  
 25075                                  Align 2
 25076                                  
 25077                                  ; 20/08/2014
 25078                                    ; /* This is the default interrupt "handler" :-) */ 
 25079                                    ; Linux v0.12 (head.s)
 25080                                  int_msg:
 25081 00006BC2 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
 25082 00006BCB 6E7465727275707420-
 25083 00006BD4 212000             
 25084                                  
 25085 00006BD7 90                      Align 2  
 25086                                  
 25087                                  ; 21/08/2014
 25088                                  timer_msg:
 25089 00006BD8 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
 25090 00006BE1 542032306829202120-
 25091 00006BEA 54696D657220496E74-
 25092 00006BF3 657272757074203A20 
 25093                                  tcountstr:
 25094 00006BFC 303030303020            	db "00000 "
 25095 00006C02 00                      	db 0
 25096                                  
 25097 00006C03 90                      Align 2
 25098                                  	; 21/08/2014
 25099                                  exc_msg:
 25100 00006C04 435055206578636570-     	db "CPU exception ! "
 25101 00006C0D 74696F6E202120     
 25102                                  excnstr: 		; 25/08/2014
 25103 00006C14 3F3F68202045495020-     	db "??h", "  EIP : "
 25104 00006C1D 3A20               
 25105                                  EIPstr: ; 29/08/2014
 25106 00006C1F 00<rept>                	times 12 db 0
 25107                                  rtc_msg:
 25108 00006C2B 5265616C2054696D65-     	db "Real Time Clock - "
 25109 00006C34 20436C6F636B202D20 
 25110                                  datestr:
 25111 00006C3D 30302F30302F303030-     	db "00/00/0000"
 25112 00006C46 30                 
 25113 00006C47 20                      	db " "
 25114                                  daystr:
 25115 00006C48 44415920                	db "DAY "
 25116                                  timestr:	
 25117 00006C4C 30303A30303A3030                db "00:00:00"
 25118 00006C54 20                      	db " "
 25119 00006C55 00                      	db 0 
 25120                                  
 25121                                  daytmp:
 25122                                  	; 28/02/2015
 25123 00006C56 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
 25124 00006C5F 4F4E20545545205745-
 25125 00006C68 442054485520465249-
 25126 00006C71 2053415420         
 25127                                  
 25128 00006C76 FF                      ptime_seconds: db 0FFh
 25129                                  
 25130                                  	; 23/02/2015
 25131                                  	; 25/08/2014
 25132                                  ;scounter:
 25133                                  ;	db 5
 25134                                  ;	db 19
 25135                                  
 25136                                  ; 05/11/2014
 25137                                  msg_out_of_memory:
 25138 00006C77 070D0A                  	db 	07h, 0Dh, 0Ah
 25139 00006C7A 496E73756666696369-             db      'Insufficient memory ! (Minimum 2 MB memory is needed.)'
 25140 00006C83 656E74206D656D6F72-
 25141 00006C8C 79202120284D696E69-
 25142 00006C95 6D756D2032204D4220-
 25143 00006C9E 6D656D6F7279206973-
 25144 00006CA7 206E65656465642E29 
 25145 00006CB0 0D0A00                   	db	0Dh, 0Ah, 0
 25146                                  	;
 25147                                  setup_error_msg:
 25148 00006CB3 0D0A                    	db 0Dh, 0Ah
 25149 00006CB5 4469736B2053657475-     	db 'Disk Setup Error!' 
 25150 00006CBE 70204572726F7221   
 25151 00006CC6 0D0A00                  	db 0Dh, 0Ah,0
 25152                                  
 25153                                  ; 02/09/2014 (Retro UNIX 386 v1)
 25154                                  ;crt_ulc : db 0 ; upper left column (for scroll) 
 25155                                  ;	  db 0 ; upper left row (for scroll)	
 25156                                  
 25157                                  ;crt_lrc : db 79 ; lower right column (for scroll) 
 25158                                  ;	  db 24 ; lower right row (for scroll)
 25159                                  
 25160                                  
 25161                                  ; 06/11/2014 (Temporary Data)
 25162                                  ; Memory Information message
 25163                                  ; 14/08/2015
 25164                                  msg_memory_info:
 25165 00006CC9 07                      	db	07h
 25166 00006CCA 0D0A                    	db	0Dh, 0Ah
 25167                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
 25168 00006CCC 546F74616C206D656D-     	db	"Total memory : "
 25169 00006CD5 6F7279203A20       
 25170                                  mem_total_b_str: ; 10 digits
 25171 00006CDB 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
 25172 00006CE4 302062797465730D0A 
 25173 00006CED 202020202020202020-     	db	"               ", 20h, 20h, 20h
 25174 00006CF6 202020202020202020 
 25175                                  mem_total_p_str: ; 7 digits
 25176 00006CFF 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
 25177 00006D08 616765730D0A       
 25178 00006D0E 0D0A                    	db 	0Dh, 0Ah
 25179 00006D10 46726565206D656D6F-     	db	"Free memory  : "
 25180 00006D19 727920203A20       
 25181                                  free_mem_b_str:  ; 10 digits
 25182 00006D1F 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
 25183 00006D28 3F2062797465730D0A 
 25184 00006D31 202020202020202020-     	db	"               ", 20h, 20h, 20h
 25185 00006D3A 202020202020202020 
 25186                                  free_mem_p_str:  ; 7 digits
 25187 00006D43 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
 25188 00006D4C 616765730D0A       
 25189 00006D52 0D0A00                  	db	0Dh, 0Ah, 0
 25190                                  
 25191                                  dsk_ready_msg:
 25192 00006D55 0D0A                    	db 	0Dh, 0Ah
 25193                                  dsktype:
 25194 00006D57 6664                    	db	'fd'
 25195                                  dskx:
 25196 00006D59 30                      	db	'0'
 25197 00006D5A 20                      	db	20h
 25198 00006D5B 697320524541445920-     	db 	'is READY ...'
 25199 00006D64 2E2E2E             
 25200 00006D67 00                      	db 	0
 25201                                  nextline:
 25202 00006D68 0D0A00                  	db 	0Dh, 0Ah, 0
 25203                                  
 25204                                  ; KERNEL - SYSINIT Messages
 25205                                  ; 24/08/2015
 25206                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
 25207                                  ; 14/07/2013
 25208                                  ;kernel_init_err_msg:
 25209                                  ;	db 0Dh, 0Ah
 25210                                  ;	db 07h
 25211                                  ;	db 'Kernel initialization ERROR !'
 25212                                  ;	db 0Dh, 0Ah, 0 
 25213                                  ; 24/08/2015
 25214                                  ;;; (temporary kernel init message has been removed
 25215                                  ;;;  from 'sys_init' code)
 25216                                  ;kernel_init_ok_msg: 
 25217                                  ;	db 0Dh, 0Ah
 25218                                  ;	db 07h
 25219                                  ;	db 'Welcome to Retro UNIX 386 v1 Operating System !'
 25220                                  ;	db 0Dh, 0Ah
 25221                                  ;       db 'by Erdogan Tan - 04/02/2016 (v0.2.0.17)'
 25222                                  ;	db 0Dh, 0Ah, 0
 25223                                  panic_msg:
 25224 00006D6B 0D0A07                  	db 0Dh, 0Ah, 07h
 25225 00006D6E 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
 25226 00006D77 726E656C2050616E69-
 25227 00006D80 632021             
 25228 00006D83 0D0A00                  	db 0Dh, 0Ah, 0
 25229                                  etc_init_err_msg:
 25230 00006D86 0D0A                    	db 0Dh, 0Ah
 25231 00006D88 07                      	db 07h
 25232 00006D89 4552524F523A202F65-     	db 'ERROR: /etc/init !?'
 25233 00006D92 74632F696E69742021-
 25234 00006D9B 3F                 
 25235 00006D9C 0D0A00                  	db 0Dh, 0Ah, 0
 25236                                  
 25237                                  ; 10/05/2015
 25238                                  badsys_msg:
 25239 00006D9F 0D0A                    	db 0Dh, 0Ah
 25240 00006DA1 07                      	db 07h
 25241 00006DA2 496E76616C69642053-     	db 'Invalid System Call !'
 25242 00006DAB 797374656D2043616C-
 25243 00006DB4 6C2021             
 25244 00006DB7 0D0A                    	db 0Dh, 0Ah
 25245 00006DB9 4541583A20              	db 'EAX: '
 25246                                  bsys_msg_eax:
 25247 00006DBE 303030303030303068      	db '00000000h'
 25248 00006DC7 0D0A                    	db 0Dh, 0Ah
 25249 00006DC9 4549503A20              	db 'EIP: '
 25250                                  bsys_msg_eip:
 25251 00006DCE 303030303030303068      	db '00000000h' 
 25252 00006DD7 0D0A00                  	db 0Dh, 0Ah, 0
 25253                                  
 25254                                  BSYS_M_SIZE equ $ - badsys_msg
 25255                                  
 25256                                  
 25257                                  align 2
 25258                                  
 25259                                  ; EPOCH Variables
 25260                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
 25261                                  ; 09/04/2013 epoch variables
 25262                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
 25263                                  ;
 25264 00006DDA B207                    year: 	dw 1970
 25265 00006DDC 0100                    month: 	dw 1
 25266 00006DDE 0100                    day: 	dw 1
 25267 00006DE0 0000                    hour: 	dw 0
 25268 00006DE2 0000                    minute: dw 0
 25269 00006DE4 0000                    second: dw 0
 25270                                  
 25271                                  DMonth:
 25272 00006DE6 0000                    	dw 0
 25273 00006DE8 1F00                    	dw 31
 25274 00006DEA 3B00                    	dw 59
 25275 00006DEC 5A00                    	dw 90
 25276 00006DEE 7800                    	dw 120
 25277 00006DF0 9700                    	dw 151
 25278 00006DF2 B500                    	dw 181
 25279 00006DF4 D400                    	dw 212
 25280 00006DF6 F300                    	dw 243
 25281 00006DF8 1101                    	dw 273
 25282 00006DFA 3001                    	dw 304
 25283 00006DFC 4E01                    	dw 334
 25284                                  
 25285                                  ; 04/11/2014 (Retro UNIX 386 v1)
 25286 00006DFE 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
 25287                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
 25288 00006E00 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
 25289                                  		   ;   between 16 MB and 4 GB.
 25290                                  
 25291 00006E02 90<rept>                align 16
 25292                                  
 25293                                  bss_start:
 25294                                  
 25295                                  ABSOLUTE bss_start
 25296                                  
 25297                                  	; 11/03/2015
 25298                                  	; Interrupt Descriptor Table (20/08/2014)
 25299                                  idt:
 25300 00006E10 <res 00000200>          	resb	64*8 ; INT 0 to INT 3Fh
 25301                                  idt_end:
 25302                                  
 25303                                  ;alignb 4
 25304                                  
 25305                                  task_state_segment:
 25306                                  	; 24/03/2015
 25307 00007010 <res 00000002>          tss.link:   resw 1
 25308 00007012 <res 00000002>          	    resw 1
 25309                                  ; tss offset 4	
 25310 00007014 <res 00000004>          tss.esp0:   resd 1
 25311 00007018 <res 00000002>          tss.ss0:    resw 1
 25312 0000701A <res 00000002>          	    resw 1	
 25313 0000701C <res 00000004>          tss.esp1:   resd 1
 25314 00007020 <res 00000002>          tss.ss1:    resw 1
 25315 00007022 <res 00000002>          	    resw 1 	
 25316 00007024 <res 00000004>          tss.esp2:   resd 1
 25317 00007028 <res 00000002>          tss.ss2:    resw 1
 25318 0000702A <res 00000002>          	    resw 1
 25319                                  ; tss offset 28
 25320 0000702C <res 00000004>          tss.CR3:    resd 1
 25321 00007030 <res 00000004>          tss.eip:    resd 1
 25322 00007034 <res 00000004>          tss.eflags: resd 1
 25323                                  ; tss offset 40
 25324 00007038 <res 00000004>          tss.eax:    resd 1		 		
 25325 0000703C <res 00000004>          tss.ecx:    resd 1
 25326 00007040 <res 00000004>          tss.edx:    resd 1
 25327 00007044 <res 00000004>          tss.ebx:    resd 1
 25328 00007048 <res 00000004>          tss.esp:    resd 1
 25329 0000704C <res 00000004>          tss.ebp:    resd 1
 25330 00007050 <res 00000004>          tss.esi:    resd 1
 25331 00007054 <res 00000004>          tss.edi:    resd 1
 25332                                  ; tss offset 72
 25333 00007058 <res 00000002>          tss.ES:     resw 1
 25334 0000705A <res 00000002>          	    resw 1	
 25335 0000705C <res 00000002>          tss.CS:	    resw 1
 25336 0000705E <res 00000002>          	    resw 1
 25337 00007060 <res 00000002>          tss.SS:	    resw 1
 25338 00007062 <res 00000002>          	    resw 1
 25339 00007064 <res 00000002>          tss.DS:	    resw 1
 25340 00007066 <res 00000002>          	    resw 1
 25341 00007068 <res 00000002>          tss.FS:	    resw 1
 25342 0000706A <res 00000002>          	    resw 1
 25343 0000706C <res 00000002>          tss.GS:	    resw 1
 25344 0000706E <res 00000002>          	    resw 1		
 25345 00007070 <res 00000002>          tss.LDTR:   resw 1
 25346 00007072 <res 00000002>          	    resw 1
 25347                                  ; tss offset 100		
 25348 00007074 <res 00000002>          	    resw 1		
 25349 00007076 <res 00000002>          tss.IOPB:   resw 1
 25350                                  ; tss offset 104 
 25351                                  tss_end:
 25352                                  
 25353 00007078 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
 25354                                  		  ;   (Physical address = Virtual address)	 	
 25355 0000707C <res 00000004>          memory_size: resd 1 ; memory size in pages
 25356 00007080 <res 00000004>          free_pages:  resd 1 ; number of free pages		
 25357 00007084 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
 25358                                  		  ;   first free page search
 25359 00007088 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
 25360                                  		  ;   next free page search will be
 25361                                  		  ; stopped after it. (end of M.A.T.)
 25362 0000708C <res 00000004>          first_page:  resd 1 ;   offset value in M.A.T. which
 25363                                  		  ; first free page search
 25364                                  		  ;   will be started on it. (for user)
 25365 00007090 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
 25366                                  
 25367                                  ;;;
 25368                                  ; 02/09/2014 (Retro UNIX 386 v1)
 25369                                  ; 04/12/2013 (Retro UNIX 8086 v1)
 25370 00007094 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
 25371                                  			  ; NOTE: active page only
 25372 00007096 <res 00000010>          cursor_posn: resw 8 	  ; cursor positions for video pages
 25373                                  active_page: 
 25374 000070A6 <res 00000001>          ptty: 	     resb 1 	  ; current tty
 25375                                  ; 01/07/2015
 25376 000070A7 <res 00000001>          ccolor:	     resb 1	  ; current color attributes ('sysmsg')	
 25377                                  ; 26/10/2015
 25378                                  ; 07/09/2014
 25379 000070A8 <res 00000014>          ttychr:      resw ntty+2  ; Character buffer (multiscreen)
 25380                                  
 25381                                  ; 21/08/2014
 25382 000070BC <res 00000004>          tcount:	     resd 1
 25383                                  
 25384                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
 25385 000070C0 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
 25386                                  
 25387                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
 25388                                  ; (open mode locks for pseudo TTYs)
 25389                                  ; [ major tty locks (return error in any conflicts) ]
 25390 000070C4 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
 25391                                  
 25392                                  ; 15/04/2015 (Retro UNIX 386 v1)
 25393                                  ; 22/09/2013 (Retro UNIX 8086 v1)
 25394 000070D8 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
 25395                                  ; 15/04/2015 (Retro UNIX 386 v1)
 25396                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
 25397                                  ;; 0 means serial port is not available 
 25398                                  ;;comprm: ; 25/06/2014
 25399 000070E2 <res 00000001>          com1p:       resb 1  ;;0E3h
 25400 000070E3 <res 00000001>          com2p:       resb 1  ;;0E3h
 25401                                  
 25402                                  ; 17/11/2015
 25403                                  ; request for response (from the terminal)	
 25404 000070E4 <res 00000002>          req_resp:     resw 1 			
 25405                                  ; 07/11/2015
 25406 000070E6 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
 25407                                  		    ; (0= COM1, 1= COM2)
 25408                                  ; 09/11/2015
 25409 000070E7 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
 25410                                  ; 07/11/2015
 25411 000070E8 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
 25412 000070EA <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
 25413                                  
 25414                                  ; 23/10/2015
 25415                                  ; SERIAL PORTS - COMMUNICATION MODES
 25416                                  ; (Retro UNIX 386 v1 feature only!)
 25417                                  ; 0 - command mode (default/initial mode)
 25418                                  ; 1 - terminal mode (Retro UNIX 386 v1 terminal, ascii chars)
 25419                                  ;;; communication modes for futre versions:  
 25420                                  ; // 2 - keyboard mode (ascii+scancode input)
 25421                                  ; // 3 - mouse mode
 25422                                  ; // 4 - device control (output) mode
 25423                                  ; VALID COMMANDS for current version:
 25424                                  ; 	'LOGIN'
 25425                                  ;  Login request: db 0FFh, 'LOGIN', 0 
 25426                                  ;	 ("Retro UNIX 386 v1 terminal requests login")
 25427                                  ;  Login response: db 0FFh, 'login', 0
 25428                                  ;	 ("login request accepted, wait for login prompt") 
 25429                                  ; When a login requests is received and acknowledged (by
 25430                                  ; serial port interrupt handler (communication procedure),
 25431                                  ; Retro UNIX 386 v1 operating system will start terminal mode
 25432                                  ; (login procedure) by changing comm. mode to 1 (terminal mode)
 25433                                  ; and then running 'etc/getty' for tty8 (COM1) or tty9 (COM2)
 25434                                  ; 
 25435                                  ; 'sys connect' system call is used to change communication mode
 25436                                  ; except 'LOGIN' command which is used to start terminal mode
 25437                                  ; by using (COM port) terminal.
 25438                                  
 25439                                  ;com1own:     resb 1 ; COM1 owner (u.uno)
 25440                                  ;com2own:     resb 1 ; COM2 owner (u.uno)
 25441                                  ;com1mode:    resb 1 ; communication mode for COM1
 25442                                  ;com1com:     resb 1 ; communication command for COM1
 25443                                  ;com2mode:    resb 1 ; communication mode for COM1
 25444                                  ;com2com      resb 1 ; communication command for COM1
 25445                                  ;com1cbufp:   resb 8 ; COM1 command buffer char pointer	
 25446                                  ;com2cbufp:   resb 8 ; COM2 command buffer char pointer	
 25447                                  ;com1cbuf:    resb 8 ; COM2 command buffer
 25448                                  ;com2cbuf:    resb 8 ; COM2 command buffer
 25449                                  
 25450                                  ; 22/08/2014 (RTC)
 25451                                  ; (Packed BCD)
 25452 000070EC <res 00000001>          time_seconds: resb 1
 25453 000070ED <res 00000001>          time_minutes: resb 1
 25454 000070EE <res 00000001>          time_hours:   resb 1
 25455 000070EF <res 00000001>          date_wday:    resb 1
 25456 000070F0 <res 00000001>          date_day:     resb 1
 25457 000070F1 <res 00000001>          date_month:   resb 1			
 25458 000070F2 <res 00000001>          date_year:    resb 1
 25459 000070F3 <res 00000001>          date_century: resb 1
 25460                                  
 25461                                  %include 'diskbss.inc'	; UNINITIALIZED DISK (BIOS) DATA
 25462                              <1> ; Retro UNIX 386 v1 Kernel - DISKBSS.INC
 25463                              <1> ; Last Modification: 10/07/2015
 25464                              <1> ;	(Unnitialized Disk Parameters Data section for 'DISKIO.INC') 
 25465                              <1> ;
 25466                              <1> ; *****************************************************************************
 25467                              <1> 
 25468                              <1> alignb 2
 25469                              <1> 
 25470                              <1> ;----------------------------------------
 25471                              <1> ;	TIMER DATA AREA 		:
 25472                              <1> ;----------------------------------------
 25473                              <1> 
 25474                              <1> TIMER_LH:	; 16/02/205
 25475 000070F4 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
 25476 000070F6 <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
 25477 000070F8 <res 00000001>      <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
 25478                              <1> 
 25479                              <1> ;----------------------------------------
 25480                              <1> ;	DISKETTE DATA AREAS		:
 25481                              <1> ;----------------------------------------
 25482                              <1> 
 25483 000070F9 <res 00000001>      <1> SEEK_STATUS:	resb	1
 25484 000070FA <res 00000001>      <1> MOTOR_STATUS:	resb	1
 25485 000070FB <res 00000001>      <1> MOTOR_COUNT:	resb	1
 25486 000070FC <res 00000001>      <1> DSKETTE_STATUS:	resb	1
 25487 000070FD <res 00000007>      <1> NEC_STATUS:	resb	7
 25488                              <1> 
 25489                              <1> ;----------------------------------------
 25490                              <1> ;	ADDITIONAL MEDIA DATA		:
 25491                              <1> ;----------------------------------------
 25492                              <1> 
 25493 00007104 <res 00000001>      <1> LASTRATE:	resb 	1
 25494 00007105 <res 00000001>      <1> HF_STATUS:	resb 	1
 25495 00007106 <res 00000001>      <1> HF_ERROR:	resb 	1
 25496 00007107 <res 00000001>      <1> HF_INT_FLAG:	resb 	1
 25497 00007108 <res 00000001>      <1> HF_CNTRL:	resb 	1
 25498 00007109 <res 00000004>      <1> DSK_STATE:	resb 	4
 25499 0000710D <res 00000002>      <1> DSK_TRK:	resb 	2
 25500                              <1> 
 25501                              <1> ;----------------------------------------
 25502                              <1> ;	FIXED DISK DATA AREAS		:
 25503                              <1> ;----------------------------------------
 25504                              <1> 
 25505 0000710F <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
 25506 00007110 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
 25507 00007111 <res 00000001>      <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
 25508                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
 25509                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
 25510                              <1> ;port2_off	resb	1		; Hard idsk controller 2 - port offset
 25511                              <1> 
 25512 00007112 <res 00000002>      <1> alignb 4
 25513                              <1> 
 25514                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 25515                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 25516                              <1> HF_TBL_VEC: ; 22/12/2014	
 25517 00007114 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 25518 00007118 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 25519 0000711C <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
 25520 00007120 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
 25521                              <1> 
 25522                              <1> ; 03/01/2015
 25523 00007124 <res 00000001>      <1> LBAMode:     	resb	1
 25524                              <1> 
 25525                              <1> ; *****************************************************************************
 25526                                  
 25527                                  ;;; Real Mode Data (10/07/2015 - BSS)
 25528                                  
 25529                                  ;alignb 2
 25530                                  
 25531                                  %include 'ux.s' ; 12/04/2015 (unix system/user/process data)
 25532                              <1> ; Retro UNIX 386 v1 Kernel - ux.s
 25533                              <1> ; Last Modification: 13/11/2015
 25534                              <1> ;
 25535                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 25536                              <1> ; (Modified from 
 25537                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 25538                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 25539                              <1> ; ----------------------------------------------------------------------------
 25540                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 25541                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 25542                              <1> ; <Bell Laboratories (17/3/1972)>
 25543                              <1> ; <Preliminary Release of UNIX Implementation Document>
 25544                              <1> ; (Section E10 (17/3/1972) - ux.s)
 25545                              <1> ; ****************************************************************************
 25546                              <1> 
 25547 00007125 <res 00000001>      <1> alignb 2
 25548                              <1> 
 25549                              <1> inode:
 25550                              <1> 	; 11/03/2013. 
 25551                              <1> 	;Derived from UNIX v1 source code 'inode' structure (ux).
 25552                              <1> 	;i.
 25553                              <1> 
 25554 00007126 <res 00000002>      <1> 	i.flgs:	 resw 1
 25555 00007128 <res 00000001>      <1> 	i.nlks:	 resb 1
 25556 00007129 <res 00000001>      <1> 	i.uid:	 resb 1
 25557 0000712A <res 00000002>      <1>         i.size:  resw 1 ; size
 25558 0000712C <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
 25559 0000713C <res 00000004>      <1> 	i.ctim:	 resd 1
 25560 00007140 <res 00000004>      <1> 	i.mtim:	 resd 1
 25561 00007144 <res 00000002>      <1> 	i.rsvd:  resw 1 ; Reserved (ZERO/Undefined word for UNIX v1.)
 25562                              <1> 
 25563                              <1> I_SIZE	equ $ - inode 
 25564                              <1> 
 25565                              <1> process:
 25566                              <1> 	; 06/05/2015
 25567                              <1> 	; 11/03/2013 - 05/02/2014
 25568                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
 25569                              <1> 	;p.
 25570                              <1> 	
 25571 00007146 <res 00000020>      <1>         p.pid:   resw nproc
 25572 00007166 <res 00000020>      <1>         p.ppid:  resw nproc
 25573 00007186 <res 00000020>      <1>         p.break: resw nproc
 25574 000071A6 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
 25575 000071B6 <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
 25576 000071C6 <res 00000010>      <1> 	p.link:	 resb nproc
 25577 000071D6 <res 00000010>      <1> 	p.stat:	 resb nproc
 25578                              <1> 
 25579                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 fetaure only !) 
 25580 000071E6 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
 25581                              <1> 			    ; 'user' structure	
 25582                              <1> 
 25583                              <1> 
 25584                              <1> P_SIZE	equ $ - process
 25585                              <1> 
 25586                              <1> 
 25587                              <1> ; fsp table (original UNIX v1)
 25588                              <1> ;
 25589                              <1> ;Entry
 25590                              <1> ;          15                                      0
 25591                              <1> ;  1     |---|---------------------------------------|
 25592                              <1> ;        |r/w|       i-number of open file           |
 25593                              <1> ;        |---|---------------------------------------| 
 25594                              <1> ;        |               device number               |
 25595                              <1> ;        |-------------------------------------------|
 25596                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
 25597                              <1> ;        |-------------------------------------------| 
 25598                              <1> ;        |  flag that says    | number of processes  |
 25599                              <1> ;        |   file deleted     | that have file open  |
 25600                              <1> ;        |-------------------------------------------| 
 25601                              <1> ;  2     |                                           |
 25602                              <1> ;        |-------------------------------------------| 
 25603                              <1> ;        |                                           |
 25604                              <1> ;        |-------------------------------------------|
 25605                              <1> ;        |                                           |
 25606                              <1> ;        |-------------------------------------------|
 25607                              <1> ;        |                                           |
 25608                              <1> ;        |-------------------------------------------| 
 25609                              <1> ;  3     |                                           | 
 25610                              <1> ;        |                                           |  
 25611                              <1> ;
 25612                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
 25613                              <1> 
 25614                              <1> 
 25615                              <1> ; 15/04/2015
 25616 00007226 <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
 25617 0000741A <res 00000020>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
 25618 0000743A <res 00000002>      <1> ii:	 resw 1
 25619 0000743C <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
 25620 0000743E <res 00000002>      <1> cdev:    resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
 25621                              <1> ; 18/05/2015
 25622                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
 25623                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
 25624                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
 25625                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
 25626                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
 25627                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
 25628                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
 25629                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
 25630                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
 25631                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
 25632                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
 25633 00007440 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
 25634                              <1> 	        ; as above, for physical drives numbers in following table
 25635 00007441 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
 25636                              <1> ; 15/04/2015
 25637 00007442 <res 00000001>      <1> active:	 resb 1 
 25638 00007443 <res 00000001>      <1> 	 resb 1 ; 09/06/2015
 25639 00007444 <res 00000002>      <1> mnti:	 resw 1
 25640 00007446 <res 00000002>      <1> mpid:	 resw 1
 25641 00007448 <res 00000002>      <1> rootdir: resw 1
 25642                              <1> ; 14/02/2014
 25643                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
 25644                              <1> ;		      Single level run queue
 25645                              <1> ;		      (in order to solve sleep/wakeup lock)
 25646 0000744A <res 00000002>      <1> runq:	 resw 1
 25647 0000744C <res 00000001>      <1> imod:	 resb 1
 25648 0000744D <res 00000001>      <1> smod:	 resb 1
 25649 0000744E <res 00000001>      <1> mmod:	 resb 1
 25650 0000744F <res 00000001>      <1> sysflg:	 resb 1
 25651                              <1> 
 25652                              <1> alignb 4
 25653                              <1> 
 25654                              <1> user:
 25655                              <1> 	; 18/10/2015
 25656                              <1> 	; 12/10/2015
 25657                              <1> 	; 21/09/2015
 25658                              <1> 	; 24/07/2015
 25659                              <1> 	; 16/06/2015
 25660                              <1> 	; 09/06/2015
 25661                              <1> 	; 11/05/2015
 25662                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 25663                              <1> 	; 10/10/2013
 25664                              <1> 	; 11/03/2013. 
 25665                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
 25666                              <1> 	;u.
 25667                              <1> 
 25668 00007450 <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
 25669 00007454 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
 25670 00007458 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
 25671 0000745C <res 00000002>      <1> 	u.cdir:	  resw 1
 25672 0000745E <res 0000000A>      <1> 	u.fp:	  resb 10
 25673 00007468 <res 00000004>      <1> 	u.fofp:	  resd 1
 25674 0000746C <res 00000004>      <1> 	u.dirp:	  resd 1
 25675 00007470 <res 00000004>      <1> 	u.namep:  resd 1
 25676 00007474 <res 00000004>      <1> 	u.off:	  resd 1
 25677 00007478 <res 00000004>      <1> 	u.base:	  resd 1
 25678 0000747C <res 00000004>      <1> 	u.count:  resd 1
 25679 00007480 <res 00000004>      <1> 	u.nread:  resd 1
 25680 00007484 <res 00000004>      <1> 	u.break:  resd 1 ; break
 25681 00007488 <res 00000002>      <1> 	u.ttyp:	  resw 1 
 25682 0000748A <res 0000000A>      <1> 	u.dirbuf: resb 10
 25683                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
 25684 00007494 <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
 25685 00007495 <res 00000001>      <1> 	u.pri:	  resb 1 ; 
 25686 00007496 <res 00000002>      <1> 	u.intr:	  resw 1
 25687 00007498 <res 00000002>      <1> 	u.quit:	  resw 1
 25688                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
 25689 0000749A <res 00000002>      <1> 	u.ilgins: resw 1
 25690 0000749C <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
 25691 0000749E <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
 25692 0000749F <res 00000001>      <1> 	u.ruid:	  resb 1
 25693 000074A0 <res 00000001>      <1> 	u.bsys:	  resb 1
 25694 000074A1 <res 00000001>      <1> 	u.uno:	  resb 1
 25695 000074A2 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
 25696                              <1> 	; tty number (rtty, rcvt, wtty)
 25697 000074A6 <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
 25698                              <1> 	; last error number
 25699 000074A7 <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
 25700                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
 25701 000074AB <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
 25702 000074AF <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
 25703 000074B3 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
 25704 000074B7 <res 00000002>      <1> 	u.pcount: resw 1 ; 20/05/2015 (byte -transfer- count for page)
 25705                              <1> 	;u.pncount: resw 1 
 25706                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
 25707                              <1> 	;u.pnbase:  resd 1 
 25708                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
 25709                              <1> 			 ; 09/06/2015
 25710 000074B9 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
 25711 000074BA <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
 25712                              <1> 			 ; 24/07/2015 - 24/06/2015
 25713                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
 25714                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
 25715                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
 25716                              <1>  			 ; 24/06/2015	  	
 25717                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
 25718                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
 25719                              <1> 			 ; 21/09/2015 (debugging - page fault analyze)
 25720 000074BB <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
 25721                              <1> 
 25722 000074BF <res 00000001>      <1> alignb 4
 25723                              <1> 
 25724                              <1> U_SIZE	equ $ - user
 25725                              <1> 
 25726                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
 25727 000074C0 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
 25728 000074C4 <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
 25729 000074C8 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
 25730 000074CC <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
 25731 000074CE <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
 25732 000074D0 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
 25733                              <1> 
 25734                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
 25735                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
 25736 000074D4 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
 25737 000074D5 <res 00000001>      <1> rwdsk:	 resb 1 ;; Read/Write function number (diskio) - 16/06/2015
 25738 000074D6 <res 00000001>      <1> retry_count: resb 1 ; Disk I/O retry count - 11/06/2015
 25739 000074D7 <res 00000001>      <1> 	 resb 1 ;; Reserved (16/06/2015) 
 25740                              <1> 
 25741                              <1> ;alignb 4
 25742                              <1> 
 25743                              <1> ; 22/08/2015
 25744 000074D8 <res 00000C30>      <1> buffer: resb nbuf * 520
 25745                              <1> 
 25746 00008108 <res 00000008>      <1> sb0:	resd 2
 25747                              <1> ;s:
 25748                              <1> ; (root disk) super block buffer
 25749                              <1> systm:
 25750                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
 25751                              <1> 	; 11/03/2013. 
 25752                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
 25753                              <1> 	;s.
 25754                              <1> 
 25755 00008110 <res 00000002>      <1> 	resw 1
 25756 00008112 <res 00000168>      <1> 	resb 360 ; 2880 sectors ; original UNIX v1 value: 128
 25757 0000827A <res 00000002>      <1> 	resw 1
 25758 0000827C <res 00000020>      <1> 	resb 32	 ; 256+40 inodes ; original UNIX v1 value: 64
 25759 0000829C <res 00000004>      <1> 	s.time:	 resd 1
 25760 000082A0 <res 00000004>      <1> 	s.syst:	 resd 1
 25761 000082A4 <res 00000004>      <1>         s.wait_: resd 1 ; wait
 25762 000082A8 <res 00000004>      <1> 	s.idlet: resd 1
 25763 000082AC <res 00000004>      <1> 	s.chrgt: resd 1
 25764 000082B0 <res 00000002>      <1> 	s.drerr: resw 1
 25765                              <1> 
 25766                              <1> S_SIZE	equ $ - systm
 25767                              <1> 
 25768 000082B2 <res 0000005E>      <1> 	resb 512-S_SIZE ; 03/06/2015	 
 25769                              <1> 
 25770 00008310 <res 00000008>      <1> sb1:	resd 2
 25771                              <1> ; (mounted disk) super block buffer
 25772                              <1> mount:	
 25773 00008318 <res 00000200>      <1> 	resb 512  ; 03/06/2015
 25774                              <1> 
 25775                              <1> ;/ ux -- unix
 25776                              <1> ;
 25777                              <1> ;systm:
 25778                              <1> ;
 25779                              <1> ;	.=.+2
 25780                              <1> ;	.=.+128.
 25781                              <1> ;	.=.+2
 25782                              <1> ;	.=.+64.
 25783                              <1> ;	s.time: .=.+4
 25784                              <1> ;	s.syst: .=.+4
 25785                              <1> ;	s.wait: .=.+4
 25786                              <1> ;	s.idlet:.=.+4
 25787                              <1> ;	s.chrgt:.=.+4
 25788                              <1> ;	s.drerr:.=.+2
 25789                              <1> ;inode:
 25790                              <1> ;	i.flgs: .=.+2
 25791                              <1> ;	i.nlks: .=.+1
 25792                              <1> ;	i.uid:  .=.+1
 25793                              <1> ;	i.size: .=.+2
 25794                              <1> ;	i.dskp: .=.+16.
 25795                              <1> ;	i.ctim: .=.+4
 25796                              <1> ;	i.mtim: .=.+4
 25797                              <1> ;	. = inode+32.
 25798                              <1> ;mount:	.=.+1024.
 25799                              <1> ;proc:
 25800                              <1> ;	p.pid:  .=.+[2*nproc]
 25801                              <1> ;	p.dska: .=.+[2*nproc]
 25802                              <1> ;	p.ppid: .=.+[2*nproc]
 25803                              <1> ;	p.break:.=.+[2*nproc]
 25804                              <1> ;	p.link: .=.+nproc
 25805                              <1> ;	p.stat: .=.+nproc
 25806                              <1> ;tty:
 25807                              <1> ;	. = .+[ntty*8.]
 25808                              <1> ;fsp:	.=.+[nfiles*8.]
 25809                              <1> ;bufp:	.=.+[nbuf*2]+6
 25810                              <1> ;sb0:	.=.+8
 25811                              <1> ;sb1:	.=.+8
 25812                              <1> ;swp:	.=.+8
 25813                              <1> ;ii:	.=.+2
 25814                              <1> ;idev:	.=.+2
 25815                              <1> ;cdev:	.=.+2
 25816                              <1> ;deverr: .=.+12.
 25817                              <1> ;active: .=.+2
 25818                              <1> ;rfap:	.=.+2
 25819                              <1> ;rkap:	.=.+2
 25820                              <1> ;tcap:	.=.+2
 25821                              <1> ;tcstate:.=.+2
 25822                              <1> ;tcerrc: .=.+2
 25823                              <1> ;mnti:	.=.+2
 25824                              <1> ;mntd:	.=.+2
 25825                              <1> ;mpid:	.=.+2
 25826                              <1> ;clockp: .=.+2
 25827                              <1> ;rootdir:.=.+2
 25828                              <1> ;toutt:	.=.+16.
 25829                              <1> ;touts: .=.+32.
 25830                              <1> ;runq:	.=.+6
 25831                              <1> ;
 25832                              <1> ;wlist:	.=.+40.
 25833                              <1> ;cc:	.=.+30.
 25834                              <1> ;cf:	.=.+31.
 25835                              <1> ;cl:	.=.+31.
 25836                              <1> ;clist:	.=.+510.
 25837                              <1> ;imod:	.=.+1
 25838                              <1> ;smod:	.=.+1
 25839                              <1> ;mmod:	.=.+1
 25840                              <1> ;uquant: .=.+1
 25841                              <1> ;sysflg: .=.+1
 25842                              <1> ;pptiflg:.=.+1
 25843                              <1> ;ttyoch: .=.+1
 25844                              <1> ; .even
 25845                              <1> ; .=.+100.; sstack:
 25846                              <1> ;buffer: .=.+[ntty*140.]
 25847                              <1> ;	.=.+[nbuf*520.]
 25848                              <1> ;
 25849                              <1> ; . = core-64.
 25850                              <1> ;user:
 25851                              <1> ;	u.sp:    .=.+2
 25852                              <1> ;	u.usp:   .=.+2
 25853                              <1> ;	u.r0:    .=.+2
 25854                              <1> ;	u.cdir:  .=.+2
 25855                              <1> ;	u.fp:    .=.+10.
 25856                              <1> ;	u.fofp:  .=.+2
 25857                              <1> ;	u.dirp:  .=.+2
 25858                              <1> ;	u.namep: .=.+2
 25859                              <1> ;	u.off:   .=.+2
 25860                              <1> ;	u.base:  .=.+2
 25861                              <1> ;	u.count: .=.+2
 25862                              <1> ;	u.nread: .=.+2
 25863                              <1> ;	u.break: .=.+2
 25864                              <1> ;	u.ttyp:  .=.+2
 25865                              <1> ;	u.dirbuf:.=.+10.
 25866                              <1> ;	u.pri:   .=.+2
 25867                              <1> ;	u.intr:  .=.+2
 25868                              <1> ;	u.quit:  .=.+2
 25869                              <1> ;	u.emt:   .=.+2
 25870                              <1> ;	u.ilgins:.=.+2
 25871                              <1> ;	u.cdev:  .=.+2
 25872                              <1> ;	u.uid:   .=.+1
 25873                              <1> ;	u.ruid:  .=.+1
 25874                              <1> ;	u.bsys:  .=.+1
 25875                              <1> ;	u.uno:   .=.+1
 25876                              <1> ;. = core
 25877                                  
 25878                                  ;; Memory (swap) Data (11/03/2015)
 25879                                  ; 09/03/2015
 25880 00008518 <res 00000002>          swpq_count: resw 1 ; count of pages on the swap que
 25881 0000851A <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
 25882 0000851E <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 25883 00008522 <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 25884 00008526 <res 00000004>          swpd_next:  resd 1 ; next free page block
 25885 0000852A <res 00000004>          swpd_last:  resd 1 ; last swap page block	
 25886                                  
 25887 0000852E <res 00000002>          alignb 4
 25888                                  
 25889                                  ; 10/07/2015
 25890                                  ; 28/08/2014
 25891 00008530 <res 00000004>          error_code:	resd 1
 25892                                  ; 29/08/2014
 25893 00008534 <res 00000004>          FaultOffset: 	resd 1
 25894                                  ; 21/09/2015
 25895 00008538 <res 00000004>          PF_Count:	resd 1	; total page fault count
 25896                                  		       	; (for debugging - page fault analyze)
 25897                                  		 	; 'page _fault_handler' (memory.inc)
 25898                                  			; 'sysgeterr' (u9.s)
 25899                                  ;; 21/08/2015
 25900                                  ;;buffer: resb (nbuf*520) ;; sysdefs.inc, ux.s
 25901                                  
 25902                                  bss_end:
 25903                                  
 25904                                  ; 27/12/2013
 25905                                  _end:  ; end of kernel code (and read only data, just before bss)
