     1                                  ; ****************************************************************************
     2                                  ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 02/02/2016
     5                                  ; ----------------------------------------------------------------------------
     6                                  ; Beginning: 04/01/2016
     7                                  ; ----------------------------------------------------------------------------
     8                                  ; Assembler: NASM version 2.11 (trdos386.s)
     9                                  ; ----------------------------------------------------------------------------
    10                                  ; Turkish Rational DOS
    11                                  ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                                  ;
    13                                  ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                                  ; unix386.s (03/01/2016)
    15                                  ;
    16                                  ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    17                                  ; TRDOS2.ASM (09/11/2011)
    18                                  ; 
    19                                  ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    20                                  ; ****************************************************************************
    21                                  
    22                                  KLOAD	equ 10000h ; Kernel loading address
    23                                  	; NOTE: Retro UNIX 8086 v1 /boot code loads kernel at 1000h:0000h 
    24                                  KCODE	equ 08h	; Code segment descriptor (ring 0)
    25                                  KDATA	equ 10h	; Data segment descriptor (ring 0)
    26                                  ; 19/03/2015
    27                                  UCODE	equ 1Bh ; 18h + 3h  (ring 3)
    28                                  UDATA	equ 23h ; 20h + 3h  (ring 3)
    29                                  ; 24/03/2015
    30                                  TSS	equ 28h	; Task state segment descriptor (ring 0)
    31                                  ; 19/03/2015
    32                                  CORE	equ 400000h  ; Start of USER's virtual/linear address space 
    33                                  		     ; (at the end of the 1st 4MB)
    34                                  ECORE	equ 0FFC00000h ; End of USER's virtual address space (4GB - 4MB)
    35                                  		     ; ULIMIT = (ECORE/4096) - 1 = 0FFBFFh (in GDT)
    36                                  
    37                                  ; 27/12/2013
    38                                  KEND    equ KLOAD + 65536 ; (28/12/2013) (end of kernel space)
    39                                  
    40                                  ; IBM PC/AT BIOS ----- 10/06/85 (postequ.inc)
    41                                  ;--------- CMOS TABLE LOCATION ADDRESS'S -------------------------------------
    42                                  CMOS_SECONDS	EQU	00H		; SECONDS (BCD)
    43                                  CMOS_SEC_ALARM	EQU	01H		; SECONDS ALARM (BCD)
    44                                  CMOS_MINUTES	EQU	02H		; MINUTES (BCD)
    45                                  CMOS_MIN_ALARM	EQU	03H		; MINUTES ALARM (BCD) 	
    46                                  CMOS_HOURS	EQU	04H		; HOURS (BCD
    47                                  CMOS_HR_ALARM	EQU	005H		; HOURS ALARM   (BCD)
    48                                  CMOS_DAY_WEEK	EQU	06H		; DAY OF THE WEEK  (BCD)
    49                                  CMOS_DAY_MONTH	EQU	07H		; DAY OF THE MONTH (BCD) 
    50                                  CMOS_MONTH	EQU	08H		; MONTH (BCD)
    51                                  CMOS_YEAR	EQU	09H		; YEAR (TWO DIGITS) (BCD)
    52                                  CMOS_CENTURY	EQU	32H		; DATE CENTURY BYTE (BCD)
    53                                  CMOS_REG_A	EQU	0AH		; STATUS REGISTER A
    54                                  CMOS_REG_B	EQU	00BH		; STATUS REGISTER B  ALARM
    55                                  CMOS_REG_C	EQU	00CH		; STATUS REGISTER C  FLAGS
    56                                  CMOS_REG_D	EQU	0DH		; STATUS REGISTER D  BATTERY
    57                                  CMOS_SHUT_DOWN	EQU	0FH		; SHUTDOWN STATUS COMMAND BYTE
    58                                  ;----------------------------------------
    59                                  ;	CMOS EQUATES FOR THIS SYSTEM	;
    60                                  ;-----------------------------------------------------------------------------
    61                                  CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
    62                                  CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
    63                                  NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
    64                                  					; HIGH BIT OF CMOS LOCATION ADDRESS
    65                                  
    66                                  ; Memory Allocation Table Address
    67                                  ; 05/11/2014
    68                                  ; 31/10/2014
    69                                  MEM_ALLOC_TBL	equ	100000h		; Memory Allocation Table at the end of
    70                                  					; the 1st 1 MB memory space.
    71                                  					; (This address must be aligned
    72                                  					;  on 128 KB boundary, if it will be
    73                                  					;  changed later.)
    74                                  					; ((lower 17 bits of 32 bit M.A.T.
    75                                  					;   address must be ZERO)).
    76                                  					; ((((Reason: 32 bit allocation 
    77                                  					;     instructions, dword steps)))
    78                                  					; (((byte >> 12 --> page >> 5)))  
    79                                  ;04/11/2014	
    80                                  PDE_A_PRESENT	equ	1		; Present flag for PDE
    81                                  PDE_A_WRITE	equ 	2		; Writable (write permission) flag
    82                                  PDE_A_USER	equ	4		; User (non-system/kernel) page flag
    83                                  ;
    84                                  PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
    85                                  PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
    86                                  PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
    87                                  PTE_A_ACCESS    equ	32		; Accessed flag (bit 5) ; 09/03/2015
    88                                  
    89                                  ; 17/02/2015 (unix386.s)
    90                                  ; 10/12/2014 - 30/12/2014 (0B000h -> 9000h) (dsectrm2.s)
    91                                  DPT_SEGM equ 09000h  ; FDPT segment (EDD v1.1, EDD v3)
    92                                  ;
    93                                  HD0_DPT	 equ 0	    ; Disk parameter table address for hd0
    94                                  HD1_DPT	 equ 32	    ; Disk parameter table address for hd1
    95                                  HD2_DPT	 equ 64	    ; Disk parameter table address for hd2
    96                                  HD3_DPT	 equ 96	    ; Disk parameter table address for hd3
    97                                  
    98                                  
    99                                  ; FDPT (Phoenix, Enhanced Disk Drive Specification v1.1, v3.0)
   100                                  ;      (HDPT: Programmer's Guide to the AMIBIOS, 1993)
   101                                  ;
   102                                  FDPT_CYLS	equ 0 ; 1 word, number of cylinders
   103                                  FDPT_HDS	equ 2 ; 1 byte, number of heads
   104                                  FDPT_TT		equ 3 ; 1 byte, A0h = translated FDPT with logical values
   105                                  		      ; otherwise it is standard FDPT with physical values 	
   106                                  FDPT_PCMP	equ 5 ; 1 word, starting write precompensation cylinder
   107                                  		      ; (obsolete for IDE/ATA drives)
   108                                  FDPT_CB		equ 8 ; 1 byte, drive control byte
   109                                  			; Bits 7-6 : Enable or disable retries (00h = enable)
   110                                  			; Bit 5	: 1 = Defect map is located at last cyl. + 1
   111                                  			; Bit 4 : Reserved. Always 0
   112                                  			; Bit 3 : Set to 1 if more than 8 heads
   113                                  			; Bit 2-0 : Reserved. Alsways 0
   114                                  FDPT_LZ		equ 12 ; 1 word, landing zone (obsolete for IDE/ATA drives)
   115                                  FDPT_SPT	equ 14 ; 1 byte, sectors per track
   116                                  
   117                                  ; Floppy Drive Parameters Table (Programmer's Guide to the AMIBIOS, 1993)
   118                                  ; (11 bytes long) will be used by diskette handler/bios
   119                                  ; which is derived from IBM PC-AT BIOS (DISKETTE.ASM, 21/04/1986).
   120                                  
   121                                  ; 01/02/2016
   122                                  Logical_DOSDisks equ 90000h + 100h ; 26* 256 = 6656 bytes
   123                                  Directory_Buffer equ 80000h ; max = 64K Bytes
   124                                  FAT_Buffer	 equ 91C00h ; 1536 bytes (3 sectors)				 	  		 	  
   125                                  
   126                                  [BITS 16]       ; We need 16-bit intructions for Real mode
   127                                  
   128                                  [ORG 0] 
   129                                  	; 12/11/2014
   130                                  	; Save boot drive number (that is default root drive)
   131 00000000 8816[AA75]              	mov	[boot_drv], dl ; physical drv number
   132                                  
   133                                  	; Determine installed memory
   134                                  	; 31/10/2014
   135                                  	;
   136 00000004 B801E8                  	mov	ax, 0E801h ; Get memory size 
   137 00000007 CD15                    	int	15h	   ; for large configurations
   138 00000009 7308                    	jnc	short chk_ms
   139 0000000B B488                    	mov	ah, 88h    ; Get extended memory size 
   140 0000000D CD15                    	int	15h
   141                                  	;	   
   142                                  	;mov	al, 17h	; Extended memory (1K blocks) low byte
   143                                  	;out	70h, al ; select CMOS register
   144                                  	;in	al, 71h ; read data (1 byte)
   145                                  	;mov	cl, al
   146                                  	;mov	al, 18h ; Extended memory (1K blocks) high byte
   147                                  	;out	70h, al ; select CMOS register
   148                                  	;in	al, 71h ; read data (1 byte)
   149                                  	;mov	ch, al
   150                                   	;      
   151 0000000F 89C1                    	mov	cx, ax
   152 00000011 31D2                    	xor	dx, dx
   153                                  chk_ms:
   154 00000013 890E[A675]              	mov	[mem_1m_1k], cx
   155 00000017 8916[A875]              	mov	[mem_16m_64k], dx
   156                                  	; 05/11/2014
   157                                  	;and	dx, dx
   158                                  	;jz	short L2
   159 0000001B 81F90004                        cmp     cx, 1024
   160 0000001F 7315                    	jnb	short L0
   161                                  		 ; insufficient memory_error	
   162                                  		 ; Minimum 2 MB memory is needed... 
   163                                  	; 05/11/2014
   164                                  	; (real mode error printing)
   165 00000021 FB                      	sti
   166 00000022 BE[3774]                	mov	si, msg_out_of_memory
   167 00000025 BB0700                  	mov	bx, 7
   168 00000028 B40E                    	mov	ah, 0Eh	; write tty
   169                                  oom_1:
   170 0000002A AC                      	lodsb
   171 0000002B 08C0                    	or	al, al
   172 0000002D 7404                    	jz	short oom_2
   173 0000002F CD10                    	int	10h
   174 00000031 EBF7                    	jmp	short oom_1
   175                                  oom_2:
   176 00000033 F4                              hlt
   177 00000034 EBFD                    	jmp	short oom_2
   178                                  
   179                                  L0:
   180                                  %include 'diskinit.s' ; 07/03/2015
   181                              <1> ; ****************************************************************************
   182                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskinit.s
   183                              <1> ; ----------------------------------------------------------------------------
   184                              <1> ; Last Update: 24/01/2016
   185                              <1> ; ----------------------------------------------------------------------------
   186                              <1> ; Beginning: 24/01/2016
   187                              <1> ; ----------------------------------------------------------------------------
   188                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
   189                              <1> ; ----------------------------------------------------------------------------
   190                              <1> ; Turkish Rational DOS
   191                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
   192                              <1> ;
   193                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
   194                              <1> ; diskinit.inc (10/07/2015)
   195                              <1> ;
   196                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
   197                              <1> ; ****************************************************************************
   198                              <1> 
   199                              <1> ; Retro UNIX 386 v1 Kernel - DISKINIT.INC
   200                              <1> ; Last Modification: 10/07/2015
   201                              <1> 
   202                              <1> ; DISK I/O SYSTEM INITIALIZATION - Erdogan Tan (Retro UNIX 386 v1 project)
   203                              <1> 
   204                              <1> ; ///////// DISK I/O SYSTEM STRUCTURE INITIALIZATION ///////////////
   205                              <1> 
   206                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
   207                              <1> ;L0:
   208                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
   209                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
   210 00000036 BA7F00              <1> 	mov	dx, 7Fh
   211                              <1> L1:	
   212 00000039 FEC2                <1> 	inc	dl
   213 0000003B B441                <1> 	mov	ah, 41h ; Check extensions present
   214                              <1> 			; Phoenix EDD v1.1 - EDD v3
   215 0000003D BBAA55              <1> 	mov	bx, 55AAh
   216 00000040 CD13                <1> 	int 	13h
   217 00000042 721A                <1> 	jc	short L2
   218                              <1> 
   219 00000044 81FB55AA            <1> 	cmp	bx, 0AA55h
   220 00000048 7514                <1> 	jne	short L2
   221 0000004A FE06[AD75]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
   222 0000004E 8816[AC75]          <1>         mov     [last_drv], dl  ; last hard disk number
   223 00000052 BB[3075]            <1> 	mov	bx, hd0_type - 80h
   224 00000055 01D3                <1> 	add	bx, dx	 
   225 00000057 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
   226                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
   227                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
   228                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
   229                              <1>                          ;            (EDD) ready (DPTE ready)
   230                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
   231                              <1>                          ;            (EDD-3)
   232                              <1> 			 ; Bit 4 to 15 - 0, Reserved
   233 00000059 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
   234 0000005C 72DB                <1> 	jb	short L1
   235                              <1> L2:
   236                              <1> 	; 23/11/2014
   237                              <1> 	; 19/11/2014
   238 0000005E 30D2                <1> 	xor	dl, dl  ; 0
   239 00000060 66BE[AE750000]      <1> 	mov	esi, fd0_type
   240                              <1> L3:
   241                              <1> 	; 14/01/2015
   242 00000066 8816[AB75]          <1> 	mov	[drv], dl
   243                              <1> 	;
   244 0000006A B408                <1> 	mov 	ah, 08h ; Return drive parameters
   245 0000006C CD13                <1> 	int	13h	
   246 0000006E 7215                <1> 	jc	short L4
   247                              <1> 		; BL = drive type (for floppy drives)
   248                              <1> 		; DL = number of floppy drives
   249                              <1> 		;		
   250                              <1> 		; ES:DI = Address of DPT from BIOS
   251                              <1> 		;
   252 00000070 67881E              <1> 	mov	[esi], bl ;  Drive type
   253                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
   254                              <1> 	; 14/01/2015
   255 00000073 E8BE02              <1> 	call	set_disk_parms
   256                              <1> 	; 10/12/2014
   257 00000076 6681FE[AE750000]    <1> 	cmp	esi, fd0_type
   258 0000007D 7706                <1> 	ja	short L4
   259 0000007F 6646                <1> 	inc	esi ; fd1_type
   260 00000081 B201                <1> 	mov	dl, 1
   261 00000083 EBE1                <1> 	jmp	short L3
   262                              <1> L4:
   263                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
   264 00000085 B27F                <1> 	mov	dl, 7Fh
   265                              <1> 	; 24/12/2014 (Temporary)
   266 00000087 803E[AD75]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
   267 0000008C 0F879000            <1>         ja      L10       ; yes, all fixed disk operations
   268                              <1> 			  ; will be performed according to
   269                              <1> 			  ; present EDD specification
   270                              <1> L6:
   271 00000090 FEC2                <1> 	inc 	dl
   272 00000092 8816[AB75]          <1>         mov     [drv], dl
   273 00000096 8816[AC75]          <1>         mov     [last_drv], dl ; 14/01/2015
   274 0000009A B408                <1> 	mov 	ah, 08h ; Return drive parameters
   275 0000009C CD13                <1> 	int	13h	; (conventional function)
   276 0000009E 0F829901            <1>         jc      L13	; fixed disk drive not ready
   277 000000A2 8816[AD75]          <1>         mov     [hdc], dl ; number of drives
   278                              <1> 	;; 14/01/2013
   279                              <1> 	;;push	cx
   280 000000A6 E88B02              <1> 	call	set_disk_parms
   281                              <1> 	;;pop	cx
   282                              <1> 	;
   283                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   284 000000A9 8A16[AB75]          <1>         mov     dl, [drv]
   285 000000AD BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   286 000000B0 80FA80              <1> 	cmp	dl, 80h
   287 000000B3 7603                <1> 	jna	short L7
   288 000000B5 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   289                              <1> L7:	
   290 000000B8 31C0                <1> 	xor	ax, ax
   291 000000BA 8ED8                <1> 	mov	ds, ax
   292 000000BC 8B37                <1>         mov     si, [bx]
   293 000000BE 8B4702              <1>         mov     ax, [bx+2] 
   294 000000C1 8ED8                <1> 	mov	ds, ax
   295 000000C3 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   296 000000C6 0F856D01            <1>         jne     L12 ; invalid FDPT
   297 000000CA BF0000              <1> 	mov	di, HD0_DPT
   298 000000CD 80FA80              <1> 	cmp	dl, 80h
   299 000000D0 7603                <1> 	jna	short L8
   300 000000D2 BF2000              <1> 	mov	di, HD1_DPT 
   301                              <1> L8:
   302                              <1> 	; 30/12/2014
   303 000000D5 B80090              <1> 	mov	ax, DPT_SEGM
   304 000000D8 8EC0                <1> 	mov	es, ax
   305                              <1> 	; 24/12/2014
   306 000000DA B90800              <1> 	mov	cx, 8
   307 000000DD F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   308 000000DF 8CC8                <1> 	mov	ax, cs
   309 000000E1 8ED8                <1> 	mov	ds, ax
   310                              <1> 	; 02/02/2015
   311 000000E3 8A0E[AB75]          <1>         mov     cl, [drv]
   312 000000E7 88CB                <1> 	mov	bl, cl
   313 000000E9 B8F001              <1> 	mov	ax, 1F0h
   314 000000EC 80E301              <1> 	and	bl, 1
   315 000000EF 7406                <1> 	jz	short L9
   316 000000F1 C0E304              <1> 	shl	bl, 4
   317 000000F4 2D8000              <1> 	sub	ax, 1F0h-170h
   318                              <1> L9:
   319 000000F7 AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   320 000000F8 050602              <1> 	add	ax, 206h
   321 000000FB AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   322 000000FC 88D8                <1> 	mov	al, bl
   323 000000FE 04A0                <1> 	add	al, 0A0h
   324 00000100 AA                  <1> 	stosb	; Device/Head Register upper nibble
   325                              <1> 	;
   326 00000101 FE06[AB75]          <1> 	inc	byte [drv]
   327 00000105 BB[3075]            <1> 	mov	bx, hd0_type - 80h
   328 00000108 01CB                <1> 	add	bx, cx
   329 0000010A 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   330 0000010D A0[AD75]            <1> 	mov	al, [hdc]
   331 00000110 FEC8                <1> 	dec	al
   332 00000112 0F842501            <1>         jz      L13
   333 00000116 80FA80              <1> 	cmp	dl, 80h
   334 00000119 0F8673FF            <1>         jna     L6
   335 0000011D E91B01              <1>         jmp     L13
   336                              <1> L10:
   337 00000120 FEC2                <1> 	inc 	dl
   338                              <1> 	; 25/12/2014
   339 00000122 8816[AB75]          <1> 	mov	[drv], dl
   340 00000126 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   341 00000128 CD13                <1> 	int	13h	; (conventional function)
   342 0000012A 0F820D01            <1>         jc      L13
   343                              <1> 	; 14/01/2015
   344 0000012E 8A16[AB75]          <1> 	mov	dl, [drv]
   345 00000132 52                  <1> 	push	dx
   346 00000133 51                  <1> 	push	cx
   347 00000134 E8FD01              <1> 	call	set_disk_parms
   348 00000137 59                  <1> 	pop	cx
   349 00000138 5A                  <1> 	pop	dx
   350                              <1> 	;
   351 00000139 66BE[30920000]      <1> 	mov	esi, _end ; 30 byte temporary buffer address 	
   352                              <1> 			 ; at the '_end' of kernel.
   353 0000013F 67C7061E00          <1> 	mov	word [esi], 30
   354 00000144 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   355 00000146 CD13                <1> 	int	13h
   356 00000148 0F82EF00            <1>         jc      L13
   357                              <1> 	; 14/01/2015
   358 0000014C 6629DB              <1> 	sub	ebx, ebx
   359 0000014F 88D3                <1> 	mov	bl, dl
   360 00000151 80EB80              <1> 	sub	bl, 80h
   361 00000154 6681C3[B0750000]    <1> 	add	ebx, hd0_type
   362 0000015B 678A03              <1> 	mov 	al, [ebx]
   363 0000015E 0C80                <1> 	or	al, 80h
   364 00000160 678803              <1> 	mov 	[ebx], al	
   365 00000163 6681EB[AE750000]    <1> 	sub	ebx, hd0_type - 2 ; 15/01/2015
   366 0000016A 6681C3[FA750000]    <1> 	add	ebx, drv.status
   367 00000171 678803              <1> 	mov	[ebx], al
   368 00000174 66678B4610          <1> 	mov	eax, [esi+16]
   369                              <1> 	; 28/02/2015
   370 00000179 6621C0              <1> 	and 	eax, eax
   371 0000017C 7416                <1> 	jz	short L10_A0h 
   372                              <1> 			; 'CHS only' disks on EDD system 
   373                              <1> 			;  are reported with ZERO disk size
   374 0000017E 6681EB[FA750000]    <1> 	sub	ebx, drv.status
   375 00000185 66C1E302            <1> 	shl	ebx, 2
   376 00000189 6681C3[DE750000]    <1> 	add	ebx, drv.size ; disk size (in sectors)
   377 00000190 66678903            <1> 	mov	[ebx], eax
   378                              <1> L10_A0h: ; Jump here to fix a ZERO (LBA) disk size problem 
   379                              <1> 	 ; for CHS disks (28/02/2015)
   380                              <1> 	; 30/12/2014
   381 00000194 BF0000              <1> 	mov	di, HD0_DPT
   382 00000197 88D0                <1> 	mov	al, dl
   383 00000199 83E003              <1> 	and 	ax, 3
   384 0000019C C0E005              <1> 	shl	al, 5 ; *32
   385 0000019F 01C7                <1> 	add 	di, ax
   386 000001A1 B80090              <1> 	mov	ax, DPT_SEGM
   387 000001A4 8EC0                <1> 	mov	es, ax
   388                              <1> 	;
   389 000001A6 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   390 000001A8 88CC                <1> 	mov	ah, cl	
   391 000001AA C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   392 000001AD 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   393 000001AE AB                  <1> 	stosw		
   394 000001AF 88F0                <1> 	mov	al, dh	; max. head number
   395 000001B1 FEC0                <1> 	inc	al
   396 000001B3 AA                  <1> 	stosb		; logical heads (limits 256)
   397 000001B4 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   398 000001B6 AA                  <1> 	stosb
   399 000001B7 8A440C              <1> 	mov	al, [si+12]
   400 000001BA AA                  <1> 	stosb		 ; physical sectors per track
   401 000001BB 31C0                <1>  	xor	ax, ax
   402                              <1> 	;dec	ax	 ; 02/01/2015 
   403 000001BD AB                  <1> 	stosw		 ; precompensation (obsolete)
   404                              <1> 	;xor	al, al	 ; 02/01/2015	
   405 000001BE AA                  <1> 	stosb		 ; reserved
   406 000001BF B008                <1> 	mov	al, 8	 ; drive control byte
   407                              <1> 		         ; (do not disable retries, 
   408                              <1> 			 ; more than 8 heads)
   409 000001C1 AA                  <1> 	stosb
   410 000001C2 8B4404              <1> 	mov	ax, [si+4]
   411 000001C5 AB                  <1> 	stosw		 ; physical number of cylinders	
   412                              <1> 	;push	ax	 ; 02/01/2015
   413 000001C6 8A4408              <1> 	mov	al, [si+8]
   414 000001C9 AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   415 000001CA 29C0                <1> 	sub 	ax, ax
   416                              <1> 	;pop	ax	 ; 02/01/2015	
   417 000001CC AB                  <1> 	stosw		 ; landing zone (obsolete)
   418 000001CD 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   419 000001CF 243F                <1> 	and 	al, 3Fh	
   420 000001D1 AA                  <1> 	stosb
   421                              <1> 	;sub	al, al	 ; checksum
   422                              <1> 	;stosb
   423                              <1> 	;
   424 000001D2 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   425 000001D5 AD                  <1> 	lodsw
   426 000001D6 50                  <1> 	push	ax	 ; (BIOS) DPTE offset
   427 000001D7 AD                  <1> 	lodsw
   428 000001D8 50                  <1> 	push	ax	 ; (BIOS) DPTE segment
   429                              <1> 	;
   430                              <1> 	; checksum calculation
   431 000001D9 89FE                <1> 	mov	si, di
   432 000001DB 06                  <1> 	push	es
   433 000001DC 1F                  <1> 	pop	ds
   434                              <1> 	;mov	cx, 16
   435 000001DD B90F00              <1> 	mov 	cx, 15
   436 000001E0 29CE                <1> 	sub	si, cx
   437 000001E2 30E4                <1> 	xor	ah, ah
   438                              <1> 	;del	cl
   439                              <1> L11:		
   440 000001E4 AC                  <1> 	lodsb
   441 000001E5 00C4                <1> 	add	ah, al
   442 000001E7 E2FB                <1> 	loop	L11
   443                              <1> 	;
   444 000001E9 88E0                <1> 	mov	al, ah
   445 000001EB F6D8                <1> 	neg	al	; -x+x = 0
   446 000001ED AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   447                              <1> 	;
   448 000001EE 1F                  <1> 	pop	ds	; (BIOS) DPTE segment
   449 000001EF 5E                  <1> 	pop	si	; (BIOS) DPTE offset	
   450                              <1> 	;
   451                              <1> 	; 23/02/2015
   452 000001F0 57                  <1> 	push	di
   453                              <1> 	; ES:DI points to DPTE (FDPTE) location
   454                              <1> 	;mov	cx, 8
   455 000001F1 B108                <1> 	mov	cl, 8
   456 000001F3 F3A5                <1> 	rep	movsw	
   457                              <1> 	;
   458                              <1> 	; 23/02/2015
   459                              <1> 	; (P)ATA drive and LBA validation
   460                              <1> 	; (invalidating SATA drives and setting
   461                              <1> 	; CHS type I/O for old type fixed disks)
   462 000001F5 5B                  <1> 	pop	bx
   463 000001F6 8CC8                <1> 	mov	ax, cs
   464 000001F8 8ED8                <1> 	mov	ds, ax
   465 000001FA 268B07              <1> 	mov	ax, [es:bx]
   466 000001FD 3DF001              <1> 	cmp	ax, 1F0h
   467 00000200 7418                <1> 	je	short L11a
   468 00000202 3D7001              <1> 	cmp	ax, 170h
   469 00000205 7413                <1> 	je	short L11a
   470                              <1> 	; invalidation 
   471                              <1> 	; (because base port address is not 1F0h or 170h)
   472 00000207 30FF                <1> 	xor	bh, bh
   473 00000209 88D3                <1> 	mov	bl, dl
   474 0000020B 80EB80              <1> 	sub	bl, 80h
   475 0000020E C687[B075]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   476 00000213 808F[FC75]F0        <1>         or      byte [bx+drv.status+2], 0F0h ; (failure sign)
   477 00000218 EB14                <1> 	jmp	short L11b
   478                              <1> L11a:	
   479                              <1> 	; LBA validation
   480 0000021A 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   481 0000021E A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   482 00000220 750C                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   483                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   484 00000222 28FF                <1> 	sub	bh, bh
   485 00000224 88D3                <1> 	mov	bl, dl
   486 00000226 80EB80              <1> 	sub	bl, 80h ; 26/02/2015
   487 00000229 80A7[FC75]FE        <1>         and     byte [bx+drv.status+2], 0FEh ; clear bit 0
   488                              <1> 				; bit 0 = LBA ready bit
   489                              <1> 	; 'diskio' procedure will check this bit !
   490                              <1> L11b:
   491 0000022E 3A16[AC75]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   492 00000232 7307                <1>         jnb     short L13
   493 00000234 E9E9FE              <1>         jmp     L10
   494                              <1> L12:
   495                              <1> 	; Restore data registers
   496 00000237 8CC8                <1> 	mov	ax, cs
   497 00000239 8ED8                <1> 	mov	ds, ax	
   498                              <1> L13:
   499                              <1> 	; 13/12/2014
   500 0000023B 0E                  <1> 	push	cs
   501 0000023C 07                  <1> 	pop	es
   502                              <1> L14:
   503 0000023D B411                <1> 	mov 	ah, 11h
   504 0000023F CD16                <1> 	int 	16h
   505 00000241 7406                <1> 	jz 	short L15 ; no keys in keyboard buffer
   506 00000243 B010                <1> 	mov	al, 10h
   507 00000245 CD16                <1> 	int 	16h
   508 00000247 EBF4                <1> 	jmp 	short L14
   509                              <1> L15:
   510                              <1> ; //////
   511                              <1> 	; 24/11/2014
   512                              <1> 	; 19/11/2014
   513                              <1> 	; 14/11/2014
   514                              <1> 	; Temporary code for disk searching code check
   515                              <1> 	;
   516                              <1> 	; This code will show existing (usable) drives and also
   517                              <1> 	; will show EDD interface support status for hard disks		
   518                              <1> 	; (If status bit 7 is 1, Identify Device info is ready,
   519                              <1> 	; no need to get it again in protected mode...) 
   520                              <1> 	;	
   521                              <1> 	; 13/11/2014
   522 00000249 BB0700              <1> 	mov	bx, 7
   523 0000024C B40E                <1> 	mov	ah, 0Eh
   524 0000024E A0[AE75]            <1> 	mov	al, [fd0_type]
   525 00000251 20C0                <1> 	and	al, al
   526 00000253 743D                <1> 	jz	short L15a
   527 00000255 88C2                <1> 	mov	dl, al
   528 00000257 B046                <1> 	mov	al, 'F'
   529 00000259 CD10                <1> 	int 	10h
   530 0000025B B044                <1> 	mov	al, 'D'
   531 0000025D CD10                <1> 	int 	10h
   532 0000025F B030                <1> 	mov	al, '0'
   533 00000261 CD10                <1> 	int 	10h
   534 00000263 B020                <1> 	mov	al, ' '
   535 00000265 CD10                <1> 	int	10h
   536 00000267 E8B300              <1> 	call	L15c
   537 0000026A B020                <1> 	mov	al, ' '
   538 0000026C CD10                <1> 	int	10h
   539                              <1> 	;
   540 0000026E A0[AF75]            <1> 	mov	al, [fd1_type]
   541 00000271 20C0                <1> 	and	al, al
   542 00000273 741D                <1> 	jz	short L15a
   543 00000275 88C2                <1> 	mov	dl, al
   544 00000277 B046                <1> 	mov	al, 'F'
   545 00000279 CD10                <1> 	int 	10h
   546 0000027B B044                <1> 	mov	al, 'D'
   547 0000027D CD10                <1> 	int 	10h
   548 0000027F B031                <1> 	mov	al, '1'
   549 00000281 CD10                <1> 	int 	10h
   550 00000283 B020                <1> 	mov	al, ' '
   551 00000285 CD10                <1> 	int	10h
   552 00000287 E89300              <1> 	call	L15c
   553 0000028A B020                <1> 	mov	al, ' '
   554 0000028C CD10                <1> 	int	10h
   555 0000028E B020                <1> 	mov	al, ' '
   556 00000290 CD10                <1> 	int	10h
   557                              <1> L15a:
   558 00000292 A0[B075]            <1> 	mov	al, [hd0_type]
   559 00000295 20C0                <1> 	and	al, al
   560 00000297 7479                <1> 	jz	short L15b
   561 00000299 88C2                <1> 	mov	dl, al
   562 0000029B B048                <1> 	mov	al, 'H'
   563 0000029D CD10                <1> 	int 	10h
   564 0000029F B044                <1> 	mov	al, 'D'
   565 000002A1 CD10                <1> 	int 	10h
   566 000002A3 B030                <1> 	mov	al, '0'
   567 000002A5 CD10                <1> 	int 	10h
   568 000002A7 B020                <1> 	mov	al, ' '
   569 000002A9 CD10                <1> 	int 	10h
   570 000002AB E86F00              <1> 	call	L15c
   571 000002AE B020                <1> 	mov	al, ' '
   572 000002B0 CD10                <1> 	int	10h
   573                              <1> 	;
   574 000002B2 A0[B175]            <1> 	mov	al, [hd1_type]
   575 000002B5 20C0                <1> 	and	al, al
   576 000002B7 7459                <1> 	jz	short L15b
   577 000002B9 88C2                <1> 	mov	dl, al
   578 000002BB B048                <1> 	mov	al, 'H'
   579 000002BD CD10                <1> 	int 	10h
   580 000002BF B044                <1> 	mov	al, 'D'
   581 000002C1 CD10                <1> 	int 	10h
   582 000002C3 B031                <1> 	mov	al, '1'
   583 000002C5 CD10                <1> 	int 	10h
   584 000002C7 B020                <1> 	mov	al, ' '
   585 000002C9 CD10                <1> 	int 	10h
   586 000002CB E84F00              <1> 	call	L15c
   587 000002CE B020                <1> 	mov	al, ' '
   588 000002D0 CD10                <1> 	int	10h
   589                              <1> 	;
   590 000002D2 A0[B275]            <1> 	mov	al, [hd2_type]
   591 000002D5 20C0                <1> 	and	al, al
   592 000002D7 7439                <1> 	jz	short L15b
   593 000002D9 88C2                <1> 	mov	dl, al
   594 000002DB B048                <1> 	mov	al, 'H'
   595 000002DD CD10                <1> 	int 	10h
   596 000002DF B044                <1> 	mov	al, 'D'
   597 000002E1 CD10                <1> 	int 	10h
   598 000002E3 B032                <1> 	mov	al, '2'
   599 000002E5 CD10                <1> 	int 	10h
   600 000002E7 B020                <1> 	mov	al, ' '
   601 000002E9 CD10                <1> 	int 	10h
   602 000002EB E82F00              <1> 	call	L15c
   603 000002EE B020                <1> 	mov	al, ' '
   604 000002F0 CD10                <1> 	int	10h
   605                              <1> 	;
   606 000002F2 A0[B375]            <1> 	mov	al, [hd3_type]
   607 000002F5 20C0                <1> 	and	al, al
   608 000002F7 7419                <1> 	jz	short L15b
   609 000002F9 88C2                <1> 	mov	dl, al
   610 000002FB B048                <1> 	mov	al, 'H'
   611 000002FD CD10                <1> 	int 	10h
   612 000002FF B044                <1> 	mov	al, 'D'
   613 00000301 CD10                <1> 	int 	10h
   614 00000303 B033                <1> 	mov	al, '3'
   615 00000305 CD10                <1> 	int 	10h
   616 00000307 B020                <1> 	mov	al, ' '
   617 00000309 CD10                <1> 	int 	10h
   618 0000030B E80F00              <1> 	call	L15c
   619 0000030E B020                <1> 	mov	al, ' '
   620 00000310 CD10                <1> 	int	10h
   621                              <1> 	;
   622                              <1> L15b:
   623 00000312 B00D                <1> 	mov	al, 0Dh
   624 00000314 CD10                <1> 	int 	10h	
   625 00000316 B00A                <1> 	mov	al, 0Ah
   626 00000318 CD10                <1> 	int 	10h
   627                              <1> 	;;xor	ah, ah
   628                              <1> 	;;int 	16h	
   629                              <1> 	;
   630 0000031A E99A00              <1>         jmp     L16  ; jmp short L16
   631                              <1>         ;
   632                              <1> L15c:
   633 0000031D 88D6                <1> 	mov	dh, dl
   634 0000031F C0EE04              <1> 	shr	dh, 4
   635 00000322 80C630              <1> 	add	dh, 30h
   636 00000325 80E20F              <1> 	and	dl, 15
   637 00000328 80C230              <1> 	add	dl, 30h
   638 0000032B 88F0                <1> 	mov	al, dh
   639 0000032D CD10                <1> 	int	10h
   640 0000032F 88D0                <1> 	mov	al, dl
   641 00000331 CD10                <1> 	int	10h
   642 00000333 C3                  <1> 	retn
   643                              <1> 	;
   644                              <1> 	; end of temporary code for disk searching code check
   645                              <1> 
   646                              <1> ; //////
   647                              <1> 
   648                              <1> set_disk_parms:
   649                              <1> 	; 10/07/2015
   650                              <1> 	; 14/01/2015
   651                              <1> 	;push	ebx
   652 00000334 6629DB              <1> 	sub	ebx, ebx
   653 00000337 8A1E[AB75]          <1> 	mov	bl, [drv]
   654 0000033B 80FB80              <1> 	cmp	bl, 80h
   655 0000033E 7203                <1> 	jb	short sdp0
   656 00000340 80EB7E              <1> 	sub	bl, 7Eh
   657                              <1> sdp0:	
   658 00000343 6681C3[FA750000]    <1> 	add	ebx, drv.status
   659 0000034A 67C60380            <1>   	mov	byte [ebx], 80h ; 'Present' flag
   660                              <1> 	;
   661 0000034E 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   662 00000350 88CC                <1> 	mov	ah, cl ; 
   663 00000352 C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   664 00000355 6681EB[FA750000]    <1> 	sub	ebx, drv.status
   665 0000035C D0E3                <1> 	shl	bl, 1
   666 0000035E 6681C3[B4750000]    <1> 	add	ebx, drv.cylinders
   667 00000365 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   668 00000366 678903              <1> 	mov	[ebx], ax
   669 00000369 50                  <1> 	push	ax ; ** cylinders
   670 0000036A 6681EB[B4750000]    <1> 	sub	ebx, drv.cylinders
   671 00000371 6681C3[C2750000]    <1> 	add	ebx, drv.heads
   672 00000378 30E4                <1> 	xor	ah, ah
   673 0000037A 88F0                <1> 	mov	al, dh ; heads
   674 0000037C 40                  <1> 	inc	ax
   675 0000037D 678903              <1> 	mov	[ebx], ax
   676 00000380 6681EB[C2750000]    <1>         sub     ebx, drv.heads
   677 00000387 6681C3[D0750000]    <1>         add     ebx, drv.spt
   678 0000038E 30ED                <1> 	xor	ch, ch
   679 00000390 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   680 00000393 67890B              <1> 	mov	[ebx], cx
   681 00000396 6681EB[D0750000]    <1>         sub     ebx, drv.spt
   682 0000039D 66D1E3              <1> 	shl	ebx, 1
   683 000003A0 6681C3[DE750000]    <1> 	add	ebx, drv.size ; disk size (in sectors)
   684                              <1> 	; LBA size = cylinders * heads * secpertrack
   685 000003A7 F7E1                <1> 	mul	cx 
   686 000003A9 89C2                <1> 	mov	dx, ax	; heads*spt					
   687 000003AB 58                  <1> 	pop	ax ; ** cylinders
   688 000003AC 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   689 000003AD F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   690 000003AF 678903              <1> 	mov	[ebx], ax
   691 000003B2 67895302            <1> 	mov	[ebx+2], dx
   692                              <1> 	;
   693                              <1> 	;pop	ebx
   694 000003B6 C3                  <1> 	retn
   695                              <1> 
   696                              <1> ;align 2
   697                              <1> 
   698                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   699                              <1> ;heads	  :  dw 0, 0, 0, 0, 0, 0
   700                              <1> ;spt	  :  dw 0, 0, 0, 0, 0, 0
   701                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   702                              <1> 
   703                              <1> ;last_drv:
   704                              <1> ;	db  0
   705                              <1> ;drv_status:
   706                              <1> ;	db  0,0,0,0,0,0
   707                              <1> ;	db 0
   708                              <1> 
   709                              <1> 
   710                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   711                              <1> 
   712                              <1> L16:
   713                                  
   714                                  	; 10/11/2014
   715 000003B7 FA                           	cli	; Disable interrupts (clear interrupt flag)
   716                                  		; Reset Interrupt MASK Registers (Master&Slave)
   717                                  	;mov	al, 0FFh	; mask off all interrupts
   718                                  	;out	21h, al		; on master PIC (8259)
   719                                  	;jmp 	$+2  ; (delay)
   720                                  	;out	0A1h, al	; on slave PIC (8259)
   721                                  	;
   722                                  	; Disable NMI 
   723 000003B8 B080                    	mov   	al, 80h 
   724 000003BA E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   725                                  	;23/02/2015
   726 000003BC 90                      	nop			;
   727                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   728                                  				; for preventing unknown state (!?)
   729                                  	;
   730                                   	; 20/08/2014
   731                                  	; Moving the kernel 64 KB back (to physical address 0)
   732                                  	; DS = CS = 1000h
   733                                  	; 05/11/2014
   734 000003BD 31C0                    	xor	ax, ax
   735 000003BF 8EC0                    	mov	es, ax ; ES = 0
   736                                  	;
   737 000003C1 B90040                  	mov	cx, (KEND - KLOAD)/4
   738 000003C4 31F6                    	xor	si, si
   739 000003C6 31FF                    	xor	di, di
   740 000003C8 F366A5                  	rep	movsd
   741                                  	;
   742 000003CB 06                      	push	es ; 0
   743 000003CC 68[D003]                	push	L17
   744 000003CF CB                      	retf
   745                                  	;
   746                                  L17:
   747                                  	; Turn off the floppy drive motor
   748 000003D0 BAF203                          mov     dx, 3F2h
   749 000003D3 EE                              out     dx, al ; 0 ; 31/12/2013
   750                                  
   751                                  	; Enable access to memory above one megabyte
   752                                  L18:
   753 000003D4 E464                    	in	al, 64h
   754 000003D6 A802                    	test	al, 2
   755 000003D8 75FA                            jnz     short L18
   756 000003DA B0D1                    	mov	al, 0D1h	; Write output port
   757 000003DC E664                    	out	64h, al
   758                                  L19:
   759 000003DE E464                    	in	al, 64h
   760 000003E0 A802                    	test	al, 2
   761 000003E2 75FA                            jnz     short L19
   762 000003E4 B0DF                    	mov	al, 0DFh	; Enable A20 line
   763 000003E6 E660                    	out	60h, al
   764                                  ;L20:
   765                                  	;
   766                                  	; Load global descriptor table register
   767                                  
   768                                          ;mov     ax, cs
   769                                          ;mov     ds, ax
   770                                  
   771 000003E8 2E0F0116[9070]                  lgdt    [cs:gdtd]
   772                                  
   773 000003EE 0F20C0                          mov     eax, cr0
   774                                  	; or 	eax, 1
   775 000003F1 40                      	inc     ax
   776 000003F2 0F22C0                  	mov     cr0, eax
   777                                  
   778                                  	; Jump to 32 bit code
   779                                  	
   780 000003F5 66                      	db 66h 			; Prefix for 32-bit
   781 000003F6 EA                      	db 0EAh 		; Opcode for far jump
   782 000003F7 [FD030000]              	dd StartPM 		; Offset to start, 32-bit
   783                                  				; (1000h:StartPM = StartPM + 10000h)
   784 000003FB 0800                    	dw KCODE		; This is the selector for CODE32_DESCRIPTOR,
   785                                  				; assuming that StartPM resides in code32
   786                                  
   787                                  [BITS 32] 
   788                                  
   789                                  StartPM:
   790                                  	; Kernel Base Address = 0 ; 30/12/2013
   791 000003FD 66B81000                	mov ax, KDATA           ; Save data segment identifier
   792 00000401 8ED8                            mov ds, ax              ; Move a valid data segment into DS register
   793 00000403 8EC0                           	mov es, ax              ; Move data segment into ES register
   794 00000405 8EE0                           	mov fs, ax              ; Move data segment into FS register
   795 00000407 8EE8                          	mov gs, ax              ; Move data segment into GS register
   796 00000409 8ED0                            mov ss, ax              ; Move data segment into SS register
   797 0000040B BC00000900                      mov esp, 90000h         ; Move the stack pointer to 090000h
   798                                  
   799                                  clear_bss: ; Clear uninitialized data area
   800                                  	; 11/03/2015
   801 00000410 31C0                    	xor  eax, eax ; 0
   802 00000412 B9F4060000              	mov  ecx, (bss_end - bss_start)/4
   803                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   804 00000417 BF[60760000]            	mov  edi, bss_start	
   805 0000041C F3AB                    	rep  stosd  		
   806                                  
   807                                  memory_init:
   808                                  	; Initialize memory allocation table and page tables
   809                                  	; 16/11/2014
   810                                  	; 15/11/2014
   811                                  	; 07/11/2014
   812                                  	; 06/11/2014
   813                                  	; 05/11/2014
   814                                  	; 04/11/2014
   815                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   816                                  	;
   817                                  ;	xor	eax, eax
   818                                  ;	xor 	ecx, ecx
   819 0000041E B108                    	mov	cl, 8
   820 00000420 BF00001000              	mov	edi, MEM_ALLOC_TBL	
   821 00000425 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   822                                  				   ; for the first 1 MB memory
   823                                  	;
   824 00000427 668B0D[A6750000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   825                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   826 0000042E 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   827 00000432 890D[D0780000]          	mov	[free_pages], ecx
   828 00000438 668B15[A8750000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   829                                  				   ; between 16 MB and 4 GB.	
   830 0000043F 6609D2                  	or	dx, dx
   831 00000442 7413                    	jz	short mi_0
   832                                  	;
   833 00000444 6689D0                  	mov	ax, dx
   834 00000447 C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   835 0000044A 0105[D0780000]          	add	[free_pages], eax
   836 00000450 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   837 00000455 EB07                    	jmp	short mi_1
   838                                  mi_0:
   839 00000457 6689C8                  	mov	ax, cx
   840 0000045A 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   841                                  mi_1:
   842 0000045E A3[CC780000]            	mov	[memory_size], eax ; Total available memory in pages
   843                                  				   ; 1 alloc. tbl. bit = 1 memory page
   844                                  				   ; 32 allocation bits = 32 mem. pages   
   845                                  	;
   846 00000463 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   847 00000468 C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   848                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   849                                  				   ;  --> x M.A.T. pages, if y = 0
   850 0000046B 66A3[E0780000]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   851 00000471 C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   852                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   853 00000474 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   854                                  	; Set/Calculate Kernel's Page Directory Address
   855 00000476 81C300001000            	add	ebx, MEM_ALLOC_TBL
   856 0000047C 891D[C8780000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   857                                  				   ; just after the last M.A.T. page
   858                                  	;
   859 00000482 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   860 00000485 A3[D8780000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   861                                  	;			   ; (allocation status search must be 
   862                                  				   ; stopped after here)	
   863 0000048A 31C0                    	xor	eax, eax
   864 0000048C 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   865 0000048D 6651                    	push	cx
   866 0000048F C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   867                                  				   ; count of 32 allocation bits
   868 00000492 F3AB                    	rep	stosd
   869 00000494 6659                    	pop	cx
   870 00000496 40                      	inc	eax		   ; 0	
   871 00000497 80E11F                  	and	cl, 31		   ; remain bits
   872 0000049A 7412                    	jz	short mi_4
   873 0000049C 8907                    	mov	[edi], eax	   ; reset	
   874                                  mi_2:
   875 0000049E 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   876 000004A1 FEC9                    	dec	cl
   877 000004A3 7404                    	jz	short mi_3
   878 000004A5 FEC0                    	inc	al
   879 000004A7 EBF5                    	jmp	short mi_2
   880                                  mi_3:
   881 000004A9 28C0                    	sub	al, al	   	   ; 0
   882 000004AB 83C704                  	add	edi, 4		   ; 15/11/2014
   883                                  mi_4:
   884 000004AE 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   885 000004B1 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   886                                  	;	
   887 000004B3 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   888                                  	;	
   889 000004B8 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   890 000004BA 7406                    	jz	short mi_5	  ; jump if EDI points to 
   891                                  				  ;         end of first 16 MB	
   892 000004BC D1E9                    	shr	ecx, 1		  ; convert to dword count
   893 000004BE D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   894 000004C0 F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   895                                  				  ; (memory hole under 16 MB)
   896                                  mi_5:
   897 000004C2 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   898 000004C5 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   899 000004C7 9C                      	pushf			  ; 16/11/2014		
   900 000004C8 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   901 000004C9 F3AB                    	rep	stosd
   902 000004CB 40                      	inc	eax		  ; 0
   903 000004CC 9D                      	popf			  ; 16/11/2014
   904 000004CD 7305                    	jnc	short mi_6
   905 000004CF 6648                    	dec	ax		  ; eax = 0000FFFFh
   906 000004D1 AB                      	stosd
   907 000004D2 6640                    	inc	ax		  ; 0		
   908                                  mi_6:
   909 000004D4 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   910 000004D6 730A                    	jnb	short mi_7	  ; end of memory allocation table
   911                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   912 000004D8 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   913 000004DA 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   914 000004DC D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   915 000004DE D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   916 000004E0 F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   917                                  mi_7:
   918                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   919 000004E2 BA00001000              	mov	edx, MEM_ALLOC_TBL
   920                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   921                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   922 000004E7 668B0D[E0780000]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   923 000004EE 89D7                    	mov	edi, edx
   924 000004F0 C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   925                                  				  ; byte offset in M.A.T.
   926                                  				  ; (1 M.A.T. byte points to 
   927                                  				  ;	      32768 bytes)
   928                                  				  ; Note: MEM_ALLOC_TBL address 
   929                                  				  ; must be aligned on 128 KB 
   930                                  				  ; boundary!
   931 000004F3 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   932                                  	; eax = 0
   933 000004F5 290D[D0780000]          	sub	[free_pages], ecx ; 07/11/2014
   934                                  mi_8:
   935 000004FB 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   936                                  	;dec	bl
   937 000004FE FEC9                    	dec	cl
   938 00000500 7404                    	jz	short mi_9
   939 00000502 FEC0                    	inc	al
   940 00000504 EBF5                    	jmp	short mi_8
   941                                  mi_9:
   942                                  	;
   943                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   944                                  	;		(allocate pages for system page tables)
   945                                  
   946                                  	; edx = MEM_ALLOC_TBL
   947 00000506 8B0D[CC780000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   948 0000050C 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   949 00000512 C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   950                                  				 ; page table count (PDE count)
   951                                  	;
   952 00000515 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   953                                  	;
   954 00000516 41                      	inc	ecx		 ; +1 for kernel page directory	
   955                                  	;
   956 00000517 290D[D0780000]          	sub	[free_pages], ecx ; 07/11/2014
   957                                  	;
   958 0000051D 8B35[C8780000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   959 00000523 C1EE0C                  	shr	esi, 12		 ; convert to page number
   960                                  mi_10:
   961 00000526 89F0                    	mov	eax, esi	 ; allocation bit offset		 
   962 00000528 89C3                    	mov	ebx, eax
   963 0000052A C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   964 0000052D 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   965                                  				 ;   to align on dword boundary
   966 00000530 83E01F                  	and	eax, 31		 ; set allocation bit position 
   967                                  				 ;  (bit 0 to bit 31)
   968                                  	;
   969 00000533 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   970                                  	;
   971 00000535 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   972                                  	;
   973 00000538 46                      	inc	esi		 ; next page table
   974 00000539 E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   975                                  				 ; (ecx = page table count + 1)		
   976                                  	;
   977 0000053B 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
   978                                  	;
   979                                  	; Initialize Kernel Page Directory and Kernel Page Tables
   980                                  	;
   981                                  	; Initialize Kernel's Page Directory
   982 0000053C 8B3D[C8780000]          	mov	edi, [k_page_dir]
   983 00000542 89F8                    	mov	eax, edi
   984 00000544 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
   985                                  		     	      ; supervisor + read&write + present
   986 00000546 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
   987                                  mi_11:
   988 00000548 0500100000              	add	eax, 4096	; Add page size (PGSZ)
   989                                  			        ; EAX points to next page table
   990 0000054D AB                      	stosd
   991 0000054E E2F8                    	loop	mi_11
   992 00000550 29C0                    	sub	eax, eax	; Empty PDE
   993 00000552 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
   994 00000556 29D1                    	sub	ecx, edx
   995 00000558 7402                    	jz	short mi_12
   996 0000055A F3AB                    	rep	stosd 		; clear remain (empty) PDEs
   997                                  	;
   998                                  	; Initialization of Kernel's Page Directory is OK, here.
   999                                  mi_12:
  1000                                  	; Initialize Kernel's Page Tables
  1001                                  	;
  1002                                  	; (EDI points to address of page table 0)
  1003                                  	; eax = 0
  1004 0000055C 8B0D[CC780000]          	mov	ecx, [memory_size] ; memory size in pages
  1005 00000562 89CA                    	mov	edx, ecx	; (***)
  1006 00000564 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
  1007                                  			     ; supervisor + read&write + present 	
  1008                                  mi_13:
  1009 00000566 AB                      	stosd
  1010 00000567 0500100000              	add	eax, 4096	
  1011 0000056C E2F8                    	loop	mi_13	
  1012 0000056E 6681E2FF03              	and	dx, 1023	; (***)
  1013 00000573 740B                    	jz	short mi_14
  1014 00000575 66B90004                	mov	cx, 1024	
  1015 00000579 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
  1016 0000057C 31C0                    	xor	eax, eax
  1017 0000057E F3AB                    	rep	stosd		; clear remain (empty) PTEs 
  1018                                  				; of the last page table
  1019                                  mi_14:
  1020                                  	;  Initialization of Kernel's Page Tables is OK, here.
  1021                                  	;
  1022 00000580 89F8                    	mov	eax, edi	; end of the last page table page
  1023                                  			        ; (beginging of user space pages)
  1024 00000582 C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
  1025 00000585 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
  1026                                  				; aligning on dword boundary	
  1027                                  	 
  1028 00000587 A3[DC780000]            	mov	[first_page], eax
  1029 0000058C A3[D4780000]            	mov	[next_page], eax ; The first free page pointer
  1030                                  				 ; for user programs
  1031                                  				 ; (Offset in Mem. Alloc. Tbl.)	
  1032                                  	;
  1033                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
  1034                                  	;
  1035                                  	
  1036                                  	; Enable paging
  1037                                  	;
  1038 00000591 A1[C8780000]                    mov     eax, [k_page_dir]
  1039 00000596 0F22D8                  	mov	cr3, eax
  1040 00000599 0F20C0                  	mov	eax, cr0
  1041 0000059C 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
  1042 000005A1 0F22C0                  	mov	cr0, eax
  1043                                          ;jmp    KCODE:StartPMP
  1044                                  
  1045 000005A4 EA                      	db 0EAh 		; Opcode for far jump
  1046 000005A5 [AB050000]                      dd StartPMP		; 32 bit offset
  1047 000005A9 0800                    	dw KCODE		; kernel code segment descriptor
  1048                                  
  1049                                  
  1050                                  StartPMP:
  1051                                  	; 06/11//2014
  1052                                  	; Clear video page 0
  1053                                  	;
  1054                                  	; Temporary Code
  1055                                  	;
  1056 000005AB B9E8030000              	mov	ecx, 80*25/2
  1057 000005B0 BF00800B00              	mov	edi, 0B8000h
  1058                                  	; 30/01/2016
  1059                                  	;xor	eax, eax	; black background, black fore color
  1060 000005B5 B800070007              	mov	eax, 07000700h  ; black background, light gray fore color
  1061 000005BA 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                                   	; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
  1069 000005BC BE[08760000]            	mov	esi, starting_msg
  1070                                  	;; 14/08/2015 (kernel version message will appear
  1071                                  	;;	       when protected mode and paging is enabled)
  1072 000005C1 BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
  1073 000005C6 B40A                    	mov	ah, 0Ah ; Black background, light green forecolor
  1074                                  	; 20/08/2014
  1075 000005C8 E8AD010000              	call	printk
  1076                                  
  1077                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
  1078                                  	; // Set IRQ offsets
  1079                                  	;
  1080                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
  1081                                  	;
  1082                                  					;; ICW1
  1083 000005CD B011                    	mov	al, 11h			; Initialization sequence
  1084 000005CF E620                    	out	20h, al			; 	8259A-1
  1085                                  	; jmp 	$+2
  1086 000005D1 E6A0                    	out	0A0h, al		; 	8259A-2
  1087                                  					;; ICW2
  1088 000005D3 B020                    	mov	al, 20h			; Start of hardware ints (20h)
  1089 000005D5 E621                    	out	21h, al			;	for 8259A-1
  1090                                  	; jmp 	$+2
  1091 000005D7 B028                    	mov	al, 28h			; Start of hardware ints (28h)
  1092 000005D9 E6A1                    	out	0A1h, al		; 	for 8259A-2
  1093                                  					;
  1094 000005DB B004                    	mov	al, 04h			;; ICW3
  1095 000005DD E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
  1096                                  	; jmp 	$+2
  1097 000005DF B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
  1098 000005E1 E6A1                    	out	0A1h, al		;
  1099                                  					;; ICW4
  1100 000005E3 B001                    	mov	al, 01h	 		;
  1101 000005E5 E621                    	out	21h, al			; 	8086 mode, normal EOI	
  1102                                  	; jmp 	$+2
  1103 000005E7 E6A1                    	out	0A1h, al		;	for both chips.
  1104                                  
  1105                                  	;mov	al, 0FFh	; mask off all interrupts for now
  1106                                  	;out	21h, al
  1107                                  	;; jmp 	$+2
  1108                                  	;out	0A1h, al
  1109                                  
  1110                                  	; 02/04/2015
  1111                                  	; 26/03/2015 System call (INT 30h) modification
  1112                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
  1113                                  	;
  1114                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
  1115                                  	;  setup_idt:
  1116                                  	;
  1117                                          ;; 16/02/2015
  1118                                  	;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1119                                  	; 21/08/2014 (timer_int)
  1120 000005E9 BE[9C700000]            	mov	esi, ilist
  1121 000005EE 8D3D[60760000]          	lea	edi, [idt]
  1122                                  	; 26/03/2015
  1123 000005F4 B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
  1124                                  	; 02/04/2015
  1125 000005F9 BB00000800              	mov	ebx,  80000h
  1126                                  rp_sidt1:
  1127 000005FE AD                      	lodsd
  1128 000005FF 89C2                    	mov	edx, eax
  1129 00000601 66BA008E                	mov	dx, 8E00h
  1130 00000605 6689C3                  	mov	bx, ax
  1131 00000608 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
  1132                                         			        ; /* interrupt gate - dpl=0, present */
  1133 0000060A AB                      	stosd	; selector & offset bits 0-15 	
  1134 0000060B 89D0                    	mov	eax, edx
  1135 0000060D AB                      	stosd	; attributes & offset bits 16-23
  1136 0000060E E2EE                    	loop	rp_sidt1
  1137 00000610 B110                    	mov	cl, 16        ; 16 software interrupts (INT 30h to INT 3Fh)
  1138                                  rp_sidt2:
  1139 00000612 AD                      	lodsd
  1140 00000613 21C0                    	and	eax, eax
  1141 00000615 7413                    	jz	short rp_sidt3
  1142 00000617 89C2                    	mov	edx, eax
  1143 00000619 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1144 0000061D 6689C3                  	mov	bx, ax
  1145 00000620 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1146 00000622 AB                      	stosd
  1147 00000623 89D0                    	mov	eax, edx
  1148 00000625 AB                      	stosd
  1149 00000626 E2EA                    	loop	rp_sidt2
  1150 00000628 EB16                    	jmp	short sidt_OK
  1151                                  rp_sidt3:
  1152 0000062A B8[A40A0000]            	mov	eax, ignore_int
  1153 0000062F 89C2                    	mov	edx, eax
  1154 00000631 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1155 00000635 6689C3                  	mov	bx, ax
  1156 00000638 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1157                                  rp_sidt4:
  1158 0000063A AB                      	stosd
  1159 0000063B 92                      	xchg	eax, edx
  1160 0000063C AB                      	stosd
  1161 0000063D 92                      	xchg	edx, eax
  1162 0000063E E2FA                    	loop	rp_sidt4
  1163                                  sidt_OK: 
  1164 00000640 0F011D[96700000]        	lidt 	[idtd]
  1165                                  	;
  1166                                  	; TSS descriptor setup ; 24/03/2015
  1167 00000647 B8[60780000]            	mov	eax, task_state_segment
  1168 0000064C 66A3[8A700000]          	mov	[gdt_tss0], ax
  1169 00000652 C1C010                  	rol	eax, 16
  1170 00000655 A2[8C700000]            	mov	[gdt_tss1], al
  1171 0000065A 8825[8F700000]          	mov	[gdt_tss2], ah
  1172 00000660 66C705[C6780000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
  1173 00000668 00                 
  1174                                  		; 
  1175                                  		; IO Map Base address (When this address points
  1176                                  		; to end of the TSS, CPU does not use IO port 
  1177                                  		; permission bit map for RING 3 IO permissions, 
  1178                                  		; access to any IO ports in ring 3 will be forbidden.)
  1179                                   		;
  1180                                  	;mov	[tss.esp0], esp ; TSS offset 4
  1181                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
  1182 00000669 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
  1183                                  			 ; occurs (or a system call -software INT- is requested)
  1184                                  			 ; while cpu running in ring 3 (in user mode).				
  1185                                  			 ; (Kernel stack pointer and segment will be loaded
  1186                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
  1187 0000066D 0F00D8                  	ltr	ax  ; Load task register
  1188                                  	;
  1189                                  esp0_set0:
  1190                                  	; 30/07/2015
  1191 00000670 8B0D[CC780000]          	mov 	ecx, [memory_size] ; memory size in pages
  1192 00000676 C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
  1193 00000679 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
  1194                                  			  ; (kernel mode virtual address)
  1195 0000067F 7605                    	jna	short esp0_set1
  1196                                  	;
  1197                                  	; If available memory > CORE (end of the 1st 4 MB)
  1198                                  	; set stack pointer to CORE
  1199                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
  1200                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
  1201 00000681 B900004000              	mov	ecx, CORE
  1202                                  esp0_set1:
  1203 00000686 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
  1204                                  esp0_set_ok:
  1205                                  	; 30/07/2015 (**tss.esp0**) 
  1206 00000688 8925[64780000]          	mov	[tss.esp0], esp
  1207 0000068E 66C705[68780000]10-             mov     word [tss.ss0], KDATA
  1208 00000696 00                 
  1209                                  	; 14/08/2015
  1210                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
  1211                                  	;
  1212                                  	;cli	; Disable interrupts (for CPU)
  1213                                  	;    (CPU will not handle hardware interrupts, except NMI!)
  1214                                  	;
  1215 00000697 30C0                    	xor	al, al		; Enable all hardware interrupts!
  1216 00000699 E621                    	out	21h, al		; (IBM PC-AT compatibility)
  1217 0000069B EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
  1218 0000069D E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
  1219                                  				; (Even if related hardware component
  1220                                  				;  does not exist!)
  1221                                  	; Enable NMI 
  1222 0000069F B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
  1223 000006A1 E670                    	out  	70h, al
  1224                                  	; 23/02/2015
  1225 000006A3 90                      	nop
  1226 000006A4 E471                    	in	al, 71h		; read in 71h just after writing out to 70h
  1227                                  				; for preventing unknown state (!?)
  1228                                  	;
  1229                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
  1230                                  	;
  1231                                  	; 02/09/2014
  1232 000006A6 6631DB                  	xor	bx, bx
  1233 000006A9 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
  1234 000006AD E80B120000              	call	_set_cpos	; 24/01/2016
  1235                                  	;
  1236                                  	; 06/11/2014
  1237 000006B2 E8EC120000              	call	memory_info
  1238                                  	; 14/08/2015
  1239                                  	;call getch ; 28/02/2015
  1240                                  drv_init:
  1241 000006B7 FB                      	sti	; Enable Interrupts 
  1242                                  	; 06/02/2015
  1243 000006B8 8B15[B0750000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
  1244 000006BE 668B1D[AE750000]        	mov	bx, [fd0_type] ; fd0, fd1
  1245                                  	; 22/02/2015
  1246 000006C5 6621DB                  	and	bx, bx
  1247 000006C8 751B                    	jnz	short di1
  1248                                  	;
  1249 000006CA 09D2                    	or 	edx, edx
  1250 000006CC 7529                    	jnz	short di2
  1251                                  	;
  1252                                  setup_error:
  1253 000006CE BE[73740000]            	mov 	esi, setup_error_msg
  1254                                  psem:	
  1255 000006D3 AC                      	lodsb
  1256 000006D4 08C0                    	or	al, al
  1257                                  	;jz	short haltx ; 22/02/2015
  1258 000006D6 7426                    	jz	short di3
  1259 000006D8 56                      	push	esi
  1260 000006D9 31DB                    	xor	ebx, ebx ; 0
  1261                                  			; Video page 0 (bl=0)
  1262 000006DB B407                    	mov	ah, 07h ; Black background, 
  1263                                  			; light gray forecolor
  1264 000006DD E847110000              	call	WRITE_TTY
  1265 000006E2 5E                      	pop	esi
  1266 000006E3 EBEE                    	jmp	short psem
  1267                                  
  1268                                  di1:
  1269                                  	; supress 'jmp short T6'
  1270                                  	;  (activate fdc motor control code)
  1271 000006E5 66C705[FB070000]90-     	mov	word [T5], 9090h ; nop
  1272 000006ED 90                 
  1273                                  	;
  1274                                  	;mov	ax, int_0Eh	; IRQ 6 handler
  1275                                  	;mov	di, 0Eh*4	; IRQ 6 vector
  1276                                  	;stosw
  1277                                  	;mov 	ax, cs
  1278                                  	;stosw
  1279                                  	;; 16/02/2015
  1280                                          ;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1281                                  	;
  1282 000006EE E80D220000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
  1283                                  	;
  1284 000006F3 09D2                    	or	edx, edx
  1285 000006F5 7407                            jz      short di3
  1286                                  di2:
  1287 000006F7 E84A220000              	call   	DISK_SETUP	; Initialize Fixed Disks
  1288 000006FC 72D0                            jc      short setup_error
  1289                                  di3:
  1290 000006FE E874120000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
  1291                                  	;
  1292 00000703 E8AD680000              	call	display_disks ; 07/03/2015  (Temporary)
  1293                                  ;haltx:
  1294                                  	; 14/08/2015
  1295                                  	;call	getch ; 22/02/2015
  1296 00000708 FB                      	sti	; Enable interrupts (for CPU)
  1297                                  	; 29/01/2016
  1298 00000709 28E4                    	sub	ah, ah ;  read time count
  1299 0000070B E84D320000              	call	int1Ah
  1300 00000710 89CA                    	mov	edx, ecx ; 18.2 * seconds
  1301                                  md_info_msg_wait1:
  1302                                  	; 29/01/2016
  1303 00000712 B401                    	mov	ah, 1
  1304 00000714 E841050000              	call	int16h
  1305 00000719 7409                    	jz	short md_info_msg_wait2
  1306 0000071B 30E4                    	xor	ah, ah ; 0
  1307 0000071D E838050000                      call    int16h
  1308 00000722 EB14                    	jmp 	short md_info_msg_ok
  1309                                  md_info_msg_wait2:
  1310 00000724 28E4                    	sub	ah, ah  ; read time count
  1311 00000726 E832320000              	call	int1Ah
  1312 0000072B 39CA                    	cmp	edx, ecx ; ; 18.2 * seconds
  1313 0000072D 7602                    	jna	short md_info_msg_wait3
  1314 0000072F 87D1                    	xchg 	edx, ecx	
  1315                                  md_info_msg_wait3:
  1316 00000731 29D1                    	sub	ecx, edx
  1317 00000733 83F97F                  	cmp	ecx, 127 ; 7 seconds (18.2 * 7)
  1318 00000736 72DA                    	jb	short md_info_msg_wait1		
  1319                                  md_info_msg_ok:
  1320                                  	; 30/06/2015
  1321 00000738 E8CC340000              	call	sys_init
  1322                                  	;
  1323                                  	;jmp 	cpu_reset ; 22/02/2015
  1324                                  hang:  
  1325                                  	; 23/02/2015
  1326                                  	;sti			; Enable interrupts
  1327 0000073D F4                      	hlt
  1328                                  	;
  1329                                  	;nop
  1330                                  	;; 03/12/2014
  1331                                  	;; 28/08/2014
  1332                                  	;mov	ah, 11h
  1333                                  	;call	getc
  1334                                  	;jz      _c8
  1335                                  	;
  1336                                  	; 23/02/2015
  1337                                  	; 06/02/2015
  1338                                  	; 07/09/2014
  1339 0000073E 31DB                    	xor	ebx, ebx
  1340 00000740 8A1D[F8780000]          	mov	bl, [ptty]	; active_page
  1341 00000746 89DE                    	mov	esi, ebx
  1342 00000748 66D1E6                  	shl 	si, 1
  1343 0000074B 81C6[FA780000]          	add	esi, ttychr
  1344 00000751 668B06                  	mov	ax, [esi]
  1345 00000754 6621C0                  	and	ax, ax
  1346                                  	;jz	short _c8
  1347 00000757 74E4                    	jz	short hang
  1348 00000759 66C7060000              	mov	word [esi], 0
  1349 0000075E 80FB03                  	cmp	bl, 3		; Video page 3
  1350                                  	;jb	short _c8
  1351 00000761 72DA                    	jb	short hang
  1352                                  	;	
  1353                                  	; 02/09/2014
  1354 00000763 B40E                    	mov	ah, 0Eh		; Yellow character 
  1355                                  				; on black background
  1356                                  	; 07/09/2014
  1357                                  nxtl:
  1358 00000765 6653                    	push	bx
  1359                                  	;
  1360                                  	;xor	bx, bx		; bl = 0 (video page 0)
  1361                                  				; bh = 0 (video mode)
  1362                                  				; Retro UNIX 386 v1 - Video Mode 0
  1363                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
  1364 00000767 6650                    	push	ax
  1365 00000769 E8BB100000              	call 	WRITE_TTY
  1366 0000076E 6658                    	pop	ax
  1367 00000770 665B                    	pop	bx ; 07/09/2014
  1368 00000772 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
  1369                                  	;jne	short _c8
  1370 00000774 75C7                    	jne	short hang
  1371 00000776 B00A                    	mov	al, 0Ah		; next line
  1372 00000778 EBEB                    	jmp	short nxtl
  1373                                  	
  1374                                  ;_c8:
  1375                                  ;	; 25/08/2014
  1376                                  ;	cli				; Disable interrupts
  1377                                  ;	mov	al, [scounter + 1]
  1378                                  ;	and	al, al
  1379                                  ;	jnz	hang
  1380                                  ;	call	rtc_p
  1381                                  ;	jmp     hang
  1382                                  
  1383                                  
  1384                                  	; 27/08/2014
  1385                                  	; 20/08/2014
  1386                                  printk:
  1387                                          ;mov    edi, [scr_row]
  1388                                  pkl:
  1389 0000077A AC                      	lodsb
  1390 0000077B 08C0                    	or 	al, al
  1391 0000077D 7404                    	jz	short pkr
  1392 0000077F 66AB                    	stosw
  1393 00000781 EBF7                    	jmp	short pkl
  1394                                  pkr:
  1395 00000783 C3                      	retn
  1396                                  
  1397                                  ; 25/07/2015
  1398                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
  1399                                  ; 17/02/2015
  1400                                  ; 06/02/2015 (unix386.s)
  1401                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
  1402                                  ;
  1403                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
  1404                                  ;
  1405                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
  1406                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
  1407                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
  1408                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
  1409                                  ;									       :
  1410                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
  1411                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
  1412                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
  1413                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
  1414                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
  1415                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
  1416                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
  1417                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
  1418                                  ;-------------------------------------------------------------------------------
  1419                                  ;
  1420                                  
  1421                                  timer_int:	; IRQ 0
  1422                                  ;int_08h:	; Timer
  1423                                  	; 14/10/2015
  1424                                  	; Here, we are simulating system call entry (for task switch)
  1425                                  	; (If multitasking is enabled, 
  1426                                  	; 'clock' procedure may jump to 'sysrelease')
  1427 00000784 1E                      	push	ds
  1428 00000785 06                      	push	es
  1429 00000786 0FA0                    	push	fs
  1430 00000788 0FA8                    	push	gs
  1431 0000078A 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1432 0000078B 66B91000                	mov     cx, KDATA
  1433 0000078F 8ED9                            mov     ds, cx
  1434 00000791 8EC1                            mov     es, cx
  1435 00000793 8EE1                            mov     fs, cx
  1436 00000795 8EE9                            mov     gs, cx
  1437                                  	;
  1438 00000797 0F20D9                  	mov	ecx, cr3
  1439 0000079A 890D[39080000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1440                                  	;
  1441 000007A0 3B0D[C8780000]          	cmp 	ecx, [k_page_dir]
  1442 000007A6 741F                    	je	short T3
  1443                                  	;
  1444                                  	; timer interrupt has been occurred while OS is in user mode
  1445 000007A8 A3[58850000]            	mov 	[u.r0], eax
  1446 000007AD 89E1                    	mov	ecx, esp
  1447 000007AF 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1448 000007B2 890D[50850000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1449 000007B8 8925[54850000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1450                                  	;
  1451 000007BE 8B0D[C8780000]          	mov	ecx, [k_page_dir]
  1452 000007C4 0F22D9                  	mov	cr3, ecx
  1453                                  T3:
  1454 000007C7 FB                      	sti				; INTERRUPTS BACK ON
  1455 000007C8 66FF05[4C790000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
  1456 000007CF 7507                    	JNZ	short T4		; GO TO TEST_DAY
  1457 000007D1 66FF05[4E790000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
  1458                                  T4:					; TEST_DAY
  1459 000007D8 66833D[4E790000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
  1460 000007E0 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1461 000007E2 66813D[4C790000]B0-     	CMP	word [TIMER_LOW],0B0H
  1462 000007EA 00                 
  1463 000007EB 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1464                                  
  1465                                  ;-----	TIMER HAS GONE 24 HOURS
  1466                                  	;;SUB	AX,AX
  1467                                  	;MOV	[TIMER_HIGH],AX
  1468                                  	;MOV	[TIMER_LOW],AX
  1469 000007ED 29C0                    	sub	eax, eax
  1470 000007EF A3[4C790000]            	mov	[TIMER_LH], eax
  1471                                  	;	
  1472 000007F4 C605[50790000]01        	MOV	byte [TIMER_OFL],1
  1473                                  
  1474                                  ;-----	TEST FOR DISKETTE TIME OUT
  1475                                  
  1476                                  T5:
  1477                                  	; 23/12/2014
  1478 000007FB EB1D                    	jmp	short T6		; will be replaced with nop, nop
  1479                                  					; (9090h) if a floppy disk
  1480                                  					; is detected.
  1481                                  	;mov	al,[CS:MOTOR_COUNT]
  1482 000007FD A0[53790000]            	mov	al, [MOTOR_COUNT]
  1483 00000802 FEC8                    	dec	al
  1484                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1485 00000804 A2[53790000]            	mov	[MOTOR_COUNT], al
  1486                                  	;mov	[ORG_MOTOR_COUNT], al
  1487 00000809 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
  1488 0000080B B0F0                    	mov 	al,0F0h
  1489                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
  1490 0000080D 2005[52790000]          	and	[MOTOR_STATUS], al
  1491                                  	;and	[ORG_MOTOR_STATUS], al
  1492 00000813 B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
  1493                                  					; bit 2 = enable controller
  1494                                  					;	1 = normal operation
  1495                                  					;	0 = reset	
  1496                                  					; bit 0, 1 = drive select
  1497                                  					; bit 4-7 = motor running bits 
  1498 00000815 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
  1499 00000819 EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
  1500                                  T6:	
  1501                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
  1502                                  					; TIMER TICK INTERRUPT
  1503                                  	;;inc	word [wait_count] ;;27/02/2015
  1504                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
  1505                                  	;;;;cli
  1506                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
  1507 0000081A FF15[35080000]          	call	[x_timer] ; 14/05/2015
  1508                                  T7:
  1509                                  	; 14/10/2015
  1510 00000820 B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  1511 00000822 FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  1512 00000823 E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  1513                                  	;
  1514 00000825 A1[39080000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1515 0000082A 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1516                                  	;
  1517 0000082D 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1518                                  	;
  1519 0000082E 0FA9                    	pop	gs
  1520 00000830 0FA1                    	pop	fs
  1521 00000832 07                      	pop	es
  1522 00000833 1F                      	pop	ds
  1523 00000834 CF                      	iretd	; return from interrupt
  1524                                  
  1525                                  
  1526                                  ; ////////////////
  1527                                  
  1528                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
  1529                                  x_timer:
  1530 00000835 [3D080000]              	dd 	u_timer			; 14/05/2015
  1531                                  	;dd	clock
  1532                                  
  1533                                  ; 14/10/2015
  1534 00000839 00000000                cr3reg: dd 0
  1535                                  
  1536                                  	; 06/02/2015
  1537                                  	; 07/09/2014
  1538                                  	; 21/08/2014
  1539                                  u_timer:
  1540                                  ;timer_int:	; IRQ 0
  1541                                  	; 06/02/2015
  1542                                  	;push	eax
  1543                                  	;push	edx
  1544                                  	;push	ecx
  1545                                  	;push	ebx
  1546                                  	;push	ds
  1547                                  	;push	es
  1548                                  	;mov	eax, KDATA
  1549                                  	;mov	ds, ax
  1550                                  	;mov	es, ax
  1551 0000083D FF05[0E790000]          	inc	dword [tcount]
  1552 00000843 BB[C0730000]            	mov	ebx, tcountstr + 4
  1553 00000848 66A1[0E790000]          	mov	ax, [tcount]
  1554 0000084E B90A000000              	mov	ecx, 10
  1555                                  rp_divtcnt:
  1556 00000853 31D2                    	xor	edx, edx
  1557 00000855 F7F1                    	div	ecx
  1558 00000857 80C230                  	add	dl, 30h
  1559 0000085A 8813                    	mov	[ebx], dl
  1560 0000085C 6609C0                  	or	ax, ax
  1561 0000085F 7403                    	jz	short print_lzero
  1562 00000861 4B                      	dec	ebx
  1563 00000862 EBEF                    	jmp	short rp_divtcnt
  1564                                  print_lzero:
  1565 00000864 81FB[BC730000]          	cmp	ebx, tcountstr
  1566 0000086A 7606                    	jna	short print_tcount
  1567 0000086C 4B                      	dec	ebx
  1568 0000086D C60330                   	mov	byte [ebx], 30h
  1569 00000870 EBF2                    	jmp	short print_lzero
  1570                                  print_tcount:
  1571 00000872 56                      	push	esi
  1572 00000873 57                      	push	edi
  1573 00000874 BE[98730000]            	mov	esi, timer_msg ; Timer interrupt message
  1574                                  	; 07/09/2014
  1575 00000879 66BB0100                	mov	bx, 1		; Video page 1
  1576                                  ptmsg:
  1577 0000087D AC                      	lodsb
  1578 0000087E 08C0                    	or	al, al
  1579 00000880 740F                    	jz	short ptmsg_ok
  1580 00000882 56                      	push	esi
  1581 00000883 6653                    	push	bx
  1582 00000885 B42F                            mov     ah,  2Fh ; Green background, white forecolor
  1583 00000887 E89D0F0000              	call 	WRITE_TTY
  1584 0000088C 665B                    	pop	bx
  1585 0000088E 5E                      	pop	esi
  1586 0000088F EBEC                    	jmp	short ptmsg
  1587                                  	;; 27/08/2014
  1588                                  	;mov     edi, 0B8000h + 0A0h ; Row 1
  1589                                  	;call	printk
  1590                                  	;
  1591                                  ptmsg_ok:
  1592                                  	; 07/09/2014
  1593 00000891 6631D2                  	xor	dx, dx		; column 0, row 0
  1594 00000894 E824100000              	call	_set_cpos	; set cursor position to 0,0 
  1595                                  	; 23/02/2015
  1596                                  	; 25/08/2014
  1597                                  	;mov	ebx, scounter		; (seconds counter)
  1598                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1599                                  ;	dec	byte [scounter+1]
  1600                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1601                                  ;	jns	short u_timer_retn
  1602                                  	; 26/02/2015
  1603                                  ;	call	rtc_p
  1604                                  ;	mov	ebx, scounter		; (seconds counter)
  1605                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1606                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1607                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1608                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1609                                  ;	mov	byte [ebx], 5
  1610                                  ;	inc	byte [ebx+1] ; 19
  1611                                  ;;timer_eoi:
  1612                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1613                                  ;;	out	20h, al	; 8259 PORT
  1614                                  	;
  1615                                  ;u_timer_retn:  ; 06/02/2015
  1616 00000899 5F                      	pop	edi
  1617 0000089A 5E                      	pop	esi
  1618                                  	;pop	es
  1619                                  	;pop	ds
  1620                                  	;pop	ebx
  1621                                  	;pop	ecx
  1622                                  	;pop	edx
  1623                                  	;pop	eax
  1624                                  	;iret
  1625 0000089B C3                      	retn	; 06/02/2015
  1626                                  
  1627                                  	; 28/08/2014
  1628                                  irq0:
  1629 0000089C 6A00                            push 	dword 0
  1630 0000089E EB48                    	jmp	short which_irq
  1631                                  irq1:
  1632 000008A0 6A01                            push 	dword 1
  1633 000008A2 EB44                    	jmp	short which_irq
  1634                                  irq2:
  1635 000008A4 6A02                            push 	dword 2
  1636 000008A6 EB40                    	jmp	short which_irq
  1637                                  irq3:
  1638                                  	; 20/11/2015
  1639                                  	; 24/10/2015
  1640 000008A8 2EFF15[A06D0000]        	call	dword [cs:com2_irq3]
  1641 000008AF 6A03                    	push 	dword 3
  1642 000008B1 EB35                    	jmp	short which_irq
  1643                                  irq4:
  1644                                  	; 20/11/2015
  1645                                  	; 24/10/2015
  1646 000008B3 2EFF15[9C6D0000]        	call	dword [cs:com1_irq4]
  1647 000008BA 6A04                            push 	dword 4
  1648 000008BC EB2A                    	jmp	short which_irq
  1649                                  irq5:
  1650 000008BE 6A05                            push 	dword 5
  1651 000008C0 EB26                    	jmp	short which_irq
  1652                                  irq6:
  1653 000008C2 6A06                            push 	dword 6
  1654 000008C4 EB22                    	jmp	short which_irq
  1655                                  irq7:
  1656 000008C6 6A07                            push 	dword 7
  1657 000008C8 EB1E                    	jmp	short which_irq
  1658                                  irq8:
  1659 000008CA 6A08                            push 	dword 8
  1660 000008CC EB1A                    	jmp	short which_irq
  1661                                  irq9:
  1662 000008CE 6A09                            push 	dword 9
  1663 000008D0 EB16                    	jmp	short which_irq
  1664                                  irq10:
  1665 000008D2 6A0A                            push 	dword 10
  1666 000008D4 EB12                    	jmp	short which_irq
  1667                                  irq11:
  1668 000008D6 6A0B                            push 	dword 11
  1669 000008D8 EB0E                    	jmp	short which_irq
  1670                                  irq12:
  1671 000008DA 6A0C                            push 	dword 12
  1672 000008DC EB0A                    	jmp	short which_irq
  1673                                  irq13:
  1674 000008DE 6A0D                            push 	dword 13
  1675 000008E0 EB06                    	jmp	short which_irq
  1676                                  irq14:
  1677 000008E2 6A0E                            push 	dword 14
  1678 000008E4 EB02                    	jmp	short which_irq
  1679                                  irq15:
  1680 000008E6 6A0F                            push 	dword 15
  1681                                  	;jmp	short which_irq
  1682                                  
  1683                                  	; 19/10/2015
  1684                                  	; 29/08/2014
  1685                                  	; 21/08/2014
  1686                                  which_irq:
  1687 000008E8 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1688 000008EB 53                      	push	ebx
  1689 000008EC 56                      	push	esi
  1690 000008ED 57                      	push	edi
  1691 000008EE 1E                      	push 	ds
  1692 000008EF 06                      	push 	es
  1693                                  	;
  1694 000008F0 88C3                    	mov	bl, al
  1695                                  	;
  1696 000008F2 B810000000              	mov	eax, KDATA
  1697 000008F7 8ED8                    	mov	ds, ax
  1698 000008F9 8EC0                    	mov	es, ax
  1699                                  	; 19/10/2015
  1700 000008FB FC                      	cld
  1701                                          ; 27/08/2014
  1702 000008FC 8105[79730000]A000-             add     dword [scr_row], 0A0h
  1703 00000904 0000               
  1704                                  	;
  1705 00000906 B417                    	mov	ah, 17h	; blue (1) background, 
  1706                                  			; light gray (7) forecolor
  1707 00000908 8B3D[79730000]                  mov     edi, [scr_row]
  1708 0000090E B049                    	mov	al, 'I'
  1709 00000910 66AB                    	stosw
  1710 00000912 B052                    	mov	al, 'R'
  1711 00000914 66AB                    	stosw
  1712 00000916 B051                    	mov	al, 'Q'
  1713 00000918 66AB                    	stosw
  1714 0000091A B020                    	mov	al, ' '
  1715 0000091C 66AB                    	stosw
  1716 0000091E 88D8                    	mov	al, bl
  1717 00000920 3C0A                    	cmp	al, 10
  1718 00000922 7208                    	jb	short iix
  1719 00000924 B031                    	mov	al, '1'
  1720 00000926 66AB                    	stosw
  1721 00000928 88D8                    	mov	al, bl
  1722 0000092A 2C0A                    	sub	al, 10
  1723                                  iix:
  1724 0000092C 0430                    	add	al, '0'
  1725 0000092E 66AB                    	stosw
  1726 00000930 B020                    	mov	al, ' '
  1727 00000932 66AB                    	stosw
  1728 00000934 B021                    	mov	al, '!'
  1729 00000936 66AB                    	stosw
  1730 00000938 B020                    	mov	al, ' '
  1731 0000093A 66AB                    	stosw
  1732                                  	; 23/02/2015
  1733 0000093C 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1734 0000093F 0F868D010000            	jna	iiret
  1735 00000945 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1736 00000947 E6A0                    	out	0A0h, al ; the 2nd 8259
  1737 00000949 E984010000              	jmp     iiret
  1738                                  	;
  1739                                  	; 22/08/2014
  1740                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1741                                  	;out	20h, al	; 8259 PORT
  1742                                  	;
  1743                                  	;pop	es
  1744                                  	;pop	ds
  1745                                  	;pop	edi
  1746                                  	;pop	esi
  1747                                  	;pop	ebx
  1748                                  	;pop 	eax
  1749                                  	;iret
  1750                                  
  1751                                  	; 02/04/2015
  1752                                  	; 25/08/2014
  1753                                  exc0:
  1754 0000094E 6A00                            push 	dword 0
  1755 00000950 E990000000                      jmp     cpu_except
  1756                                  exc1:
  1757 00000955 6A01                            push 	dword 1
  1758 00000957 E989000000                      jmp     cpu_except
  1759                                  exc2:
  1760 0000095C 6A02                            push 	dword 2
  1761 0000095E E982000000                      jmp     cpu_except
  1762                                  exc3:
  1763 00000963 6A03                            push 	dword 3
  1764 00000965 EB7E                            jmp     cpu_except
  1765                                  exc4:
  1766 00000967 6A04                            push 	dword 4
  1767 00000969 EB7A                            jmp     cpu_except
  1768                                  exc5:
  1769 0000096B 6A05                            push 	dword 5
  1770 0000096D EB76                            jmp     cpu_except
  1771                                  exc6:
  1772 0000096F 6A06                            push 	dword 6
  1773 00000971 EB72                            jmp     cpu_except
  1774                                  exc7:
  1775 00000973 6A07                            push 	dword 7
  1776 00000975 EB6E                            jmp     cpu_except
  1777                                  exc8:
  1778                                  	; [esp] = Error code
  1779 00000977 6A08                            push 	dword 8
  1780 00000979 EB5C                            jmp     cpu_except_en
  1781                                  exc9:
  1782 0000097B 6A09                            push 	dword 9
  1783 0000097D EB66                            jmp     cpu_except
  1784                                  exc10:
  1785                                  	; [esp] = Error code
  1786 0000097F 6A0A                            push 	dword 10
  1787 00000981 EB54                            jmp     cpu_except_en
  1788                                  exc11:
  1789                                  	; [esp] = Error code
  1790 00000983 6A0B                            push 	dword 11
  1791 00000985 EB50                            jmp     cpu_except_en
  1792                                  exc12:
  1793                                  	; [esp] = Error code
  1794 00000987 6A0C                            push 	dword 12
  1795 00000989 EB4C                            jmp     cpu_except_en
  1796                                  exc13:
  1797                                  	; [esp] = Error code
  1798 0000098B 6A0D                            push 	dword 13
  1799 0000098D EB48                            jmp     cpu_except_en
  1800                                  exc14:
  1801                                  	; [esp] = Error code
  1802 0000098F 6A0E                            push 	dword 14
  1803 00000991 EB44                    	jmp	short cpu_except_en
  1804                                  exc15:
  1805 00000993 6A0F                            push 	dword 15
  1806 00000995 EB4E                            jmp     cpu_except
  1807                                  exc16:
  1808 00000997 6A10                            push 	dword 16
  1809 00000999 EB4A                            jmp     cpu_except
  1810                                  exc17:
  1811                                  	; [esp] = Error code
  1812 0000099B 6A11                            push 	dword 17
  1813 0000099D EB38                    	jmp	short cpu_except_en
  1814                                  exc18:
  1815 0000099F 6A12                            push 	dword 18
  1816 000009A1 EB42                    	jmp	short cpu_except
  1817                                  exc19:
  1818 000009A3 6A13                            push 	dword 19
  1819 000009A5 EB3E                    	jmp	short cpu_except
  1820                                  exc20:
  1821 000009A7 6A14                            push 	dword 20
  1822 000009A9 EB3A                    	jmp	short cpu_except
  1823                                  exc21:
  1824 000009AB 6A15                            push 	dword 21
  1825 000009AD EB36                    	jmp	short cpu_except
  1826                                  exc22:
  1827 000009AF 6A16                            push 	dword 22
  1828 000009B1 EB32                    	jmp	short cpu_except
  1829                                  exc23:
  1830 000009B3 6A17                            push 	dword 23
  1831 000009B5 EB2E                    	jmp	short cpu_except
  1832                                  exc24:
  1833 000009B7 6A18                            push 	dword 24
  1834 000009B9 EB2A                    	jmp	short cpu_except
  1835                                  exc25:
  1836 000009BB 6A19                            push 	dword 25
  1837 000009BD EB26                    	jmp	short cpu_except
  1838                                  exc26:
  1839 000009BF 6A1A                            push 	dword 26
  1840 000009C1 EB22                    	jmp	short cpu_except
  1841                                  exc27:
  1842 000009C3 6A1B                            push 	dword 27
  1843 000009C5 EB1E                    	jmp	short cpu_except
  1844                                  exc28:
  1845 000009C7 6A1C                            push 	dword 28
  1846 000009C9 EB1A                    	jmp	short cpu_except
  1847                                  exc29:
  1848 000009CB 6A1D                            push 	dword 29
  1849 000009CD EB16                    	jmp	short cpu_except
  1850                                  exc30:
  1851 000009CF 6A1E                            push 	dword 30
  1852 000009D1 EB04                    	jmp	short cpu_except_en
  1853                                  exc31:
  1854 000009D3 6A1F                            push 	dword 31
  1855 000009D5 EB0E                            jmp     short cpu_except
  1856                                  
  1857                                  	; 19/10/2015
  1858                                  	; 19/09/2015
  1859                                  	; 01/09/2015
  1860                                  	; 28/08/2015
  1861                                  	; 28/08/2014
  1862                                  cpu_except_en:
  1863 000009D7 87442404                	xchg	eax, [esp+4] ; Error code
  1864 000009DB 36A3[24920000]          	mov	[ss:error_code], eax
  1865 000009E1 58                      	pop	eax  ; Exception number
  1866 000009E2 870424                  	xchg	eax, [esp]
  1867                                  		; eax = eax before exception
  1868                                  		; [esp] -> exception number
  1869                                  		; [esp+4] -> EIP to return
  1870                                  	; 19/10/2015
  1871                                  	; 19/09/2015
  1872                                  	; 01/09/2015
  1873                                  	; 28/08/2015
  1874                                  	; 29/08/2014
  1875                                  	; 28/08/2014
  1876                                  	; 25/08/2014
  1877                                  	; 21/08/2014
  1878                                  cpu_except:	; CPU Exceptions
  1879 000009E5 FC                      	cld
  1880 000009E6 870424                  	xchg	eax, [esp] 
  1881                                  		; eax = Exception number
  1882                                  		; [esp] = eax (before exception)	
  1883 000009E9 53                      	push	ebx
  1884 000009EA 56                      	push	esi
  1885 000009EB 57                      	push	edi
  1886 000009EC 1E                      	push 	ds
  1887 000009ED 06                      	push 	es
  1888                                  	; 28/08/2015
  1889 000009EE 66BB1000                	mov	bx, KDATA
  1890 000009F2 8EDB                    	mov	ds, bx
  1891 000009F4 8EC3                    	mov	es, bx
  1892 000009F6 0F20DB                  	mov	ebx, cr3
  1893 000009F9 53                      	push	ebx ; (*) page directory
  1894                                  	; 19/10/2015
  1895 000009FA FC                      	cld
  1896                                  	; 25/03/2015
  1897 000009FB 8B1D[C8780000]          	mov	ebx, [k_page_dir]
  1898 00000A01 0F22DB                  	mov	cr3, ebx
  1899                                  	; 28/08/2015
  1900 00000A04 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1901 00000A07 7512                    	jne	short cpu_except_nfp
  1902 00000A09 E8352A0000              	call	page_fault_handler
  1903 00000A0E 21C0                    	and 	eax, eax
  1904 00000A10 0F84B8000000                    jz	iiretp ; 01/09/2015
  1905 00000A16 B80E000000              	mov	eax, 0Eh ; 14
  1906                                  cpu_except_nfp:
  1907                                  	; 02/04/2015
  1908 00000A1B BB[3D070000]            	mov	ebx, hang
  1909 00000A20 875C241C                	xchg	ebx, [esp+28]
  1910                                  		; EIP (points to instruction which faults)
  1911                                  	  	; New EIP (hang)
  1912 00000A24 891D[28920000]          	mov	[FaultOffset], ebx
  1913 00000A2A C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1914 00000A32 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1915                                  	;
  1916 00000A3A 88C4                    	mov	ah, al
  1917 00000A3C 240F                    	and	al, 0Fh
  1918 00000A3E 3C09                    	cmp	al, 9
  1919 00000A40 7602                    	jna	short h1ok
  1920 00000A42 0407                    	add	al, 'A'-':'
  1921                                  h1ok:
  1922 00000A44 D0EC                    	shr	ah, 1
  1923 00000A46 D0EC                    	shr	ah, 1
  1924 00000A48 D0EC                    	shr	ah, 1
  1925 00000A4A D0EC                    	shr	ah, 1
  1926 00000A4C 80FC09                  	cmp	ah, 9
  1927 00000A4F 7603                    	jna	short h2ok
  1928 00000A51 80C407                  	add	ah, 'A'-':'
  1929                                  h2ok:	
  1930 00000A54 86E0                    	xchg 	ah, al	
  1931 00000A56 66053030                	add	ax, '00'
  1932 00000A5A 66A3[D4730000]          	mov	[excnstr], ax
  1933                                  	;
  1934                                  	; 29/08/2014
  1935 00000A60 A1[28920000]            	mov	eax, [FaultOffset]
  1936 00000A65 51                      	push	ecx
  1937 00000A66 52                      	push	edx
  1938 00000A67 89E3                    	mov	ebx, esp
  1939                                  	; 28/08/2015
  1940 00000A69 B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1941                                  			  ; to hexadecimal string
  1942                                  	;mov	ecx, 10	    ; divisor to convert	
  1943                                  			    ; binary number to decimal string
  1944                                  b2d1:
  1945 00000A6E 31D2                    	xor	edx, edx
  1946 00000A70 F7F1                    	div	ecx
  1947 00000A72 6652                    	push	dx
  1948 00000A74 39C8                    	cmp	eax, ecx
  1949 00000A76 73F6                    	jnb	short b2d1
  1950 00000A78 BF[DF730000]            	mov	edi, EIPstr ; EIP value
  1951                                  			    ; points to instruction which faults	
  1952                                  	; 28/08/2015
  1953 00000A7D 89C2                    	mov	edx, eax
  1954                                  b2d2:
  1955                                  	;add	al, '0'
  1956 00000A7F 8A82[6B1A0000]          	mov	al, [edx+hexchrs]
  1957 00000A85 AA                      	stosb		    ; write hexadecimal digit to its place	
  1958 00000A86 39E3                    	cmp	ebx, esp
  1959 00000A88 7606                    	jna	short b2d3
  1960 00000A8A 6658                    	pop	ax
  1961 00000A8C 88C2                    	mov	dl, al
  1962 00000A8E EBEF                    	jmp	short b2d2
  1963                                  b2d3:
  1964 00000A90 B068                    	mov 	al, 'h' ; 28/08/2015
  1965 00000A92 AA                      	stosb
  1966 00000A93 B020                    	mov	al, 20h	    ; space
  1967 00000A95 AA                      	stosb
  1968 00000A96 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  1969 00000A98 AA                      	stosb
  1970                                  	;
  1971 00000A99 5A                      	pop	edx
  1972 00000A9A 59                      	pop	ecx
  1973                                  	;
  1974 00000A9B B44F                    	mov	ah, 4Fh	; red (4) background, 
  1975                                  			; white (F) forecolor
  1976 00000A9D BE[C4730000]            	mov	esi, exc_msg ; message offset
  1977                                  	;
  1978 00000AA2 EB11                    	jmp	short piemsg
  1979                                  	;
  1980                                          ;add    dword [scr_row], 0A0h
  1981                                          ;mov    edi, [scr_row]
  1982                                          ;
  1983                                  	;call 	printk
  1984                                  	;
  1985                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1986                                  	;out	20h, al	; 8259 PORT
  1987                                  	;
  1988                                  	;pop	es
  1989                                  	;pop	ds
  1990                                  	;pop	edi
  1991                                  	;pop	esi
  1992                                  	;pop 	eax
  1993                                  	;iret
  1994                                  	
  1995                                  	; 28/08/2015
  1996                                  	; 23/02/2015
  1997                                  	; 20/08/2014
  1998                                  ignore_int:
  1999 00000AA4 50                      	push	eax
  2000 00000AA5 53                      	push	ebx ; 23/02/2015
  2001 00000AA6 56                      	push	esi
  2002 00000AA7 57                      	push	edi
  2003 00000AA8 1E                      	push 	ds
  2004 00000AA9 06                      	push 	es
  2005                                  	; 28/08/2015
  2006 00000AAA 0F20D8                  	mov	eax, cr3
  2007 00000AAD 50                      	push	eax ; (*) page directory
  2008                                  	;
  2009 00000AAE B467                    	mov	ah, 67h	; brown (6) background, 
  2010                                  			; light gray (7) forecolor
  2011 00000AB0 BE[82730000]            	mov	esi, int_msg ; message offset
  2012                                  piemsg:
  2013                                          ; 27/08/2014
  2014 00000AB5 8105[79730000]A000-             add     dword [scr_row], 0A0h
  2015 00000ABD 0000               
  2016 00000ABF 8B3D[79730000]                  mov     edi, [scr_row]
  2017                                          ;
  2018 00000AC5 E8B0FCFFFF              	call 	printk
  2019                                  	;
  2020                                  	; 23/02/2015
  2021 00000ACA B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2022 00000ACC E6A0                    	out	0A0h, al ; the 2nd 8259
  2023                                  iiretp: ; 01/09/2015
  2024                                  	; 28/08/2015
  2025 00000ACE 58                      	pop	eax ; (*) page directory
  2026 00000ACF 0F22D8                  	mov	cr3, eax
  2027                                  	;
  2028                                  iiret:
  2029                                  	; 22/08/2014
  2030 00000AD2 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2031 00000AD4 E620                    	out	20h, al	; 8259 PORT
  2032                                  	;
  2033 00000AD6 07                      	pop	es
  2034 00000AD7 1F                      	pop	ds
  2035 00000AD8 5F                      	pop	edi
  2036 00000AD9 5E                      	pop	esi
  2037 00000ADA 5B                      	pop	ebx ; 29/08/2014
  2038 00000ADB 58                      	pop 	eax
  2039 00000ADC CF                      	iretd
  2040                                  
  2041                                  	; 26/02/2015
  2042                                  	; 07/09/2014
  2043                                  	; 25/08/2014
  2044                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  2045                                  	; 22/08/2014
  2046 00000ADD 50                      	push	eax
  2047 00000ADE 53                      	push	ebx ; 29/08/2014
  2048 00000ADF 56                      	push	esi
  2049 00000AE0 57                      	push	edi
  2050 00000AE1 1E                      	push 	ds
  2051 00000AE2 06                      	push 	es
  2052                                  	;
  2053 00000AE3 B810000000              	mov	eax, KDATA
  2054 00000AE8 8ED8                    	mov	ds, ax
  2055 00000AEA 8EC0                    	mov	es, ax
  2056                                  	;
  2057                                  	; 25/08/2014
  2058 00000AEC E884000000              	call	rtc_p
  2059                                  	;
  2060                                  	; 22/02/2015 - dsectpm.s
  2061                                  	; [ source: http://wiki.osdev.org/RTC ]
  2062                                  	; read status register C to complete procedure
  2063                                  	;(it is needed to get a next IRQ 8) 
  2064 00000AF1 B00C                    	mov	al, 0Ch ; 
  2065 00000AF3 E670                    	out	70h, al ; select register C
  2066 00000AF5 90                      	nop
  2067 00000AF6 E471                    	in	al, 71h ; just throw away contents
  2068                                  	; 22/02/2015
  2069 00000AF8 B020                    	MOV	AL,EOI		; END OF INTERRUPT
  2070 00000AFA E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  2071                                  	;
  2072 00000AFC EBD4                    	jmp	short iiret	
  2073                                  
  2074                                  	; 22/08/2014
  2075                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  2076                                  	; (INT 1Ah)
  2077                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  2078                                  time_of_day:
  2079 00000AFE E8B7300000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  2080 00000B03 726F                            jc      short rtc_retn 
  2081 00000B05 B000                    	mov	al, CMOS_SECONDS
  2082 00000B07 E8C9300000              	call	CMOS_READ
  2083 00000B0C A2[3E790000]            	mov	[time_seconds], al 
  2084 00000B11 B002                    	mov	al, CMOS_MINUTES
  2085 00000B13 E8BD300000              	call	CMOS_READ
  2086 00000B18 A2[3F790000]            	mov	[time_minutes], al 
  2087 00000B1D B004                    	mov	al, CMOS_HOURS
  2088 00000B1F E8B1300000              	call	CMOS_READ
  2089 00000B24 A2[40790000]                    mov     [time_hours], al
  2090 00000B29 B006                    	mov	al, CMOS_DAY_WEEK 
  2091 00000B2B E8A5300000              	call	CMOS_READ
  2092 00000B30 A2[41790000]            	mov	[date_wday], al
  2093 00000B35 B007                     	mov	al, CMOS_DAY_MONTH
  2094 00000B37 E899300000              	call	CMOS_READ
  2095 00000B3C A2[42790000]            	mov	[date_day], al
  2096 00000B41 B008                    	mov	al, CMOS_MONTH
  2097 00000B43 E88D300000              	call	CMOS_READ
  2098 00000B48 A2[43790000]            	mov	[date_month], al
  2099 00000B4D B009                    	mov	al, CMOS_YEAR
  2100 00000B4F E881300000              	call	CMOS_READ
  2101 00000B54 A2[44790000]            	mov	[date_year], al
  2102 00000B59 B032                    	mov	al, CMOS_CENTURY
  2103 00000B5B E875300000              	call	CMOS_READ
  2104 00000B60 A2[45790000]            	mov	[date_century], al
  2105                                  	;
  2106 00000B65 B000                    	mov	al, CMOS_SECONDS
  2107 00000B67 E869300000              	call 	CMOS_READ
  2108 00000B6C 3A05[3E790000]          	cmp	al, [time_seconds]
  2109 00000B72 758A                    	jne	short time_of_day
  2110                                  
  2111                                  rtc_retn:
  2112 00000B74 C3                      	retn
  2113                                  
  2114                                  rtc_p:	
  2115                                  	; 07/09/2014
  2116                                  	; 29/08/2014
  2117                                  	; 27/08/2014
  2118                                  	; 25/08/2014
  2119                                   	; Print Real Time Clock content
  2120                                  	;
  2121                                  	;
  2122 00000B75 E884FFFFFF              	call	time_of_day
  2123 00000B7A 72F8                    	jc	short rtc_retn
  2124                                  	;
  2125 00000B7C 3A05[36740000]          	cmp	al, [ptime_seconds]
  2126 00000B82 74F0                            je      short rtc_retn ; 29/08/2014
  2127                                  	;
  2128 00000B84 A2[36740000]            	mov	[ptime_seconds], al
  2129                                  	;
  2130 00000B89 A0[45790000]            	mov	al, [date_century]
  2131 00000B8E E8BE000000              	call	bcd_to_ascii
  2132 00000B93 66A3[03740000]          	mov	[datestr+6], ax
  2133 00000B99 A0[44790000]            	mov	al, [date_year]
  2134 00000B9E E8AE000000              	call	bcd_to_ascii
  2135 00000BA3 66A3[05740000]          	mov	[datestr+8], ax
  2136 00000BA9 A0[43790000]            	mov	al, [date_month]
  2137 00000BAE E89E000000              	call	bcd_to_ascii
  2138 00000BB3 66A3[00740000]          	mov	[datestr+3], ax
  2139 00000BB9 A0[42790000]            	mov	al, [date_day]
  2140 00000BBE E88E000000              	call	bcd_to_ascii
  2141 00000BC3 66A3[FD730000]          	mov	[datestr], ax
  2142                                  	;
  2143 00000BC9 0FB61D[41790000]        	movzx	ebx, byte [date_wday]
  2144 00000BD0 C0E302                  	shl 	bl, 2
  2145 00000BD3 81C3[16740000]          	add	ebx, daytmp
  2146 00000BD9 8B03                    	mov	eax, [ebx]
  2147 00000BDB A3[08740000]            	mov	[daystr], eax
  2148                                  	;
  2149 00000BE0 A0[40790000]            	mov	al, [time_hours]
  2150 00000BE5 E867000000              	call	bcd_to_ascii
  2151 00000BEA 66A3[0C740000]          	mov	[timestr], ax
  2152 00000BF0 A0[3F790000]            	mov	al, [time_minutes]
  2153 00000BF5 E857000000              	call	bcd_to_ascii
  2154 00000BFA 66A3[0F740000]          	mov	[timestr+3], ax
  2155 00000C00 A0[3E790000]            	mov	al, [time_seconds]
  2156 00000C05 E847000000              	call	bcd_to_ascii
  2157 00000C0A 66A3[12740000]          	mov	[timestr+6], ax
  2158                                  	;		
  2159 00000C10 BE[EB730000]            	mov	esi, rtc_msg ; message offset
  2160                                  	; 23/02/2015
  2161 00000C15 52                      	push	edx
  2162 00000C16 51                      	push	ecx
  2163                                  	; 07/09/2014
  2164 00000C17 66BB0200                	mov	bx, 2		; Video page 2
  2165                                  prtmsg:
  2166 00000C1B AC                      	lodsb
  2167 00000C1C 08C0                    	or	al, al
  2168 00000C1E 740F                    	jz	short prtmsg_ok
  2169 00000C20 56                      	push	esi
  2170 00000C21 6653                    	push	bx
  2171 00000C23 B43F                            mov	ah, 3Fh	; cyan (6) background, 
  2172                                  			; white (F) forecolor
  2173 00000C25 E8FF0B0000              	call 	WRITE_TTY
  2174 00000C2A 665B                    	pop	bx
  2175 00000C2C 5E                      	pop	esi
  2176 00000C2D EBEC                    	jmp	short prtmsg
  2177                                  	;
  2178                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  2179                                  	;call	printk
  2180                                  prtmsg_ok:
  2181                                  	; 07/09/2014
  2182 00000C2F 6631D2                  	xor	dx, dx		; column 0, row 0
  2183 00000C32 E8860C0000              	call	_set_cpos	; set curspor position to 0,0 
  2184                                  	; 23/02/2015
  2185 00000C37 59                      	pop	ecx
  2186 00000C38 5A                      	pop	edx
  2187 00000C39 C3                      	retn
  2188                                  
  2189                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2190                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2191                                  default_irq7:
  2192 00000C3A 6650                    	push	ax
  2193 00000C3C B00B                    	mov	al, 0Bh  ; In-Service register
  2194 00000C3E E620                    	out	20h, al
  2195 00000C40 EB00                            jmp short $+2
  2196 00000C42 EB00                    	jmp short $+2
  2197 00000C44 E420                    	in	al, 20h
  2198 00000C46 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  2199 00000C48 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  2200 00000C4A B020                            mov     al, 20h ; EOI
  2201 00000C4C E620                    	out	20h, al 
  2202                                  irq7_iret:
  2203 00000C4E 6658                    	pop	ax
  2204 00000C50 CF                      	iretd
  2205                                  	
  2206                                  bcd_to_ascii:
  2207                                  	; 25/08/2014
  2208                                  	; INPUT ->
  2209                                  	;	al = Packed BCD number
  2210                                  	; OUTPUT ->
  2211                                  	;	ax  = ASCII word/number
  2212                                  	;
  2213                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  2214                                  	;
  2215 00000C51 D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  2216                                  					; AH = AL / 10h
  2217                                  					; AL = AL MOD 10h
  2218 00000C53 660D3030                	or ax,'00'                      ; Make it ASCII based
  2219                                  
  2220 00000C57 86E0                            xchg ah, al 
  2221                                  	
  2222 00000C59 C3                      	retn	
  2223                                  	
  2224                                  
  2225                                  %include 'keyboard.s' ; 07/03/2015
  2226                              <1> ; ****************************************************************************
  2227                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - keyboard.s
  2228                              <1> ; ----------------------------------------------------------------------------
  2229                              <1> ; Last Update: 29/01/2016
  2230                              <1> ; ----------------------------------------------------------------------------
  2231                              <1> ; Beginning: 17/01/2016
  2232                              <1> ; ----------------------------------------------------------------------------
  2233                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
  2234                              <1> ; ----------------------------------------------------------------------------
  2235                              <1> ; Turkish Rational DOS
  2236                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
  2237                              <1> ;
  2238                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
  2239                              <1> ; keyboard.inc (17/10/2015)
  2240                              <1> ;
  2241                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
  2242                              <1> ; ****************************************************************************
  2243                              <1> 
  2244                              <1> ; Retro UNIX 386 v1 Kernel - KEYBOARD.INC
  2245                              <1> ; Last Modification: 17/10/2015
  2246                              <1> ;		    (Keyboard Data is in 'KYBDATA.INC')	
  2247                              <1> ;
  2248                              <1> ; ///////// KEYBOARD FUNCTIONS (PROCEDURES) ///////////////
  2249                              <1> 
  2250                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
  2251                              <1> 
  2252                              <1> ; 03/12/2014
  2253                              <1> ; 26/08/2014
  2254                              <1> ; KEYBOARD I/O
  2255                              <1> ; (INT_16h - Retro UNIX 8086 v1 - U9.ASM, 30/06/2014)
  2256                              <1> 
  2257                              <1> ;NOTE: 'k0' to 'k7' are name of OPMASK registers.
  2258                              <1> ;	(The reason of using '_k' labels!!!) (27/08/2014)    
  2259                              <1> ;NOTE: 'NOT' keyword is '~' unary operator in NASM.
  2260                              <1> ;	('NOT LC_HC' --> '~LC_HC') (bit reversing operator)
  2261                              <1> 
  2262                              <1> int16h:	; 30/06/2015
  2263                              <1> ;getc:
  2264 00000C5A 9C                  <1> 	pushfd	; 28/08/2014
  2265 00000C5B 0E                  <1> 	push 	cs
  2266 00000C5C E801000000          <1> 	call 	KEYBOARD_IO_1 ; getc_int
  2267 00000C61 C3                  <1> 	retn	
  2268                              <1> 
  2269                              <1> getc_int:
  2270                              <1> 	; 28/02/2015
  2271                              <1> 	; 03/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2272                              <1> 	;	      instead of pc-at bios - 1985-)
  2273                              <1> 	; 28/08/2014 (_k1d)
  2274                              <1> 	; 30/06/2014
  2275                              <1> 	; 03/03/2014
  2276                              <1> 	; 28/02/2014
  2277                              <1> 	; Derived from "KEYBOARD_IO_1" procedure of IBM "pc-xt-286" 
  2278                              <1> 	; rombios source code (21/04/1986)
  2279                              <1> 	;	 'keybd.asm', INT 16H, KEYBOARD_IO
  2280                              <1> 	;
  2281                              <1> 	; KYBD --- 03/06/86  KEYBOARD BIOS
  2282                              <1> 	;
  2283                              <1> 	;--- INT 16 H -----------------------------------------------------------------
  2284                              <1> 	; KEYBOARD I/O								      :
  2285                              <1> 	;	THESE ROUTINES PROVIDE READ KEYBOARD SUPPORT			      :
  2286                              <1> 	; INPUT									      :
  2287                              <1> 	;	(AH)= 00H  READ THE NEXT ASCII CHARACTER ENTERED FROM THE KEYBOARD,   :
  2288                              <1> 	;		   RETURN THE RESULT IN (AL), SCAN CODE IN (AH).              :
  2289                              <1> 	;		   THIS IS THE COMPATIBLE READ INTERFACE, EQUIVALENT TO THE   :
  2290                              <1> 	;                  STANDARD PC OR PCAT KEYBOARD				      :	
  2291                              <1> 	;-----------------------------------------------------------------------------:
  2292                              <1> 	;	(AH)= 01H  SET THE ZERO FLAG TO INDICATE IF AN ASCII CHARACTER IS     :
  2293                              <1> 	;		   AVAILABLE TO BE READ FROM THE KEYBOARD BUFFER.	      :
  2294                              <1> 	;		   (ZF)= 1 -- NO CODE AVAILABLE			              :
  2295                              <1> 	;		   (ZF)= 0 -- CODE IS AVAILABLE  (AX)= CHARACTER              :
  2296                              <1> 	;		   IF (ZF)= 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS :
  2297                              <1> 	;		   IN (AX), AND THE ENTRY REMAINS IN THE BUFFER.              :
  2298                              <1> 	;		   THIS WILL RETURN ONLY PC/PCAT KEYBOARD COMPATIBLE CODES    :
  2299                              <1> 	;-----------------------------------------------------------------------------:	
  2300                              <1> 	;	(AH)= 02H  RETURN THE CURRENT SHIFT STATUS IN AL REGISTER             :
  2301                              <1> 	;		   THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE        :
  2302                              <1> 	;		   EQUATES FOR @KB_FLAG		                              :
  2303                              <1> 	;-----------------------------------------------------------------------------:	
  2304                              <1> 	;	(AH)= 03H  SET TYPAMATIC RATE AND DELAY                               :
  2305                              <1> 	;	      (AL) = 05H                                                      :
  2306                              <1> 	;	      (BL) = TYPAMATIC RATE (BITS 5 - 7 MUST BE RESET TO 0)           :
  2307                              <1> 	;		       							      :
  2308                              <1> 	;                     REGISTER     RATE      REGISTER     RATE                :
  2309                              <1> 	;                      VALUE     SELECTED     VALUE     SELECTED              :
  2310                              <1> 	;                     --------------------------------------------            :
  2311                              <1> 	;			00H        30.0        10H        7.5                 :
  2312                              <1> 	;			01H        26.7        11H        6.7                 :
  2313                              <1> 	;			02H        24.0        12H        6.0                 :
  2314                              <1> 	;			03H        21.8        13H        5.5                 :
  2315                              <1> 	;			04H        20.0        14H        5.0                 :
  2316                              <1> 	;			05H        18.5        15H        4.6                 :
  2317                              <1> 	;			06H        17.1        16H        4.3                 :
  2318                              <1> 	;			07H        16.0        17H        4.0                 :
  2319                              <1> 	;			08H        15.0        18H        3.7                 :
  2320                              <1> 	;			09H        13.3        19H        3.3                 :
  2321                              <1> 	;			0AH        12.0        1AH        3.0                 :
  2322                              <1> 	;			0BH        10.9        1BH        2.7                 :
  2323                              <1>         ;			0CH        10.0        1CH        2.5                 :
  2324                              <1> 	;			0DH         9.2        1DH        2.3                 :
  2325                              <1> 	;			0EH         8.6        1EH        2.1                 :
  2326                              <1> 	;			0FH         8.0        1FH        2.0                 :
  2327                              <1> 	;									      :
  2328                              <1> 	;	      (BH) = TYPAMATIC DELAY  (BITS 2 - 7 MUST BE RESET TO 0)         :
  2329                              <1> 	;		       							      :
  2330                              <1> 	;                     REGISTER     DELAY                                      :
  2331                              <1> 	;                      VALUE       VALUE                                      :
  2332                              <1> 	;                     ------------------                                      :
  2333                              <1> 	;			00H        250 ms                                     :
  2334                              <1> 	;			01H        500 ms                                     :
  2335                              <1> 	;			02H        750 ms                                     :
  2336                              <1> 	;			03H       1000 ms                                     :
  2337                              <1> 	;-----------------------------------------------------------------------------:
  2338                              <1> 	;	(AH)= 05H  PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD    :
  2339                              <1> 	;		   BUFFER AS IF STRUCK FROM KEYBOARD                          :
  2340                              <1> 	;		   ENTRY:  (CL) = ASCII CHARACTER		              :
  2341                              <1> 	;		           (CH) = SCAN CODE                                   :
  2342                              <1> 	;		   EXIT:   (AH) = 00H = SUCCESSFUL OPERATION                  :
  2343                              <1> 	;		           (AL) = 01H = UNSUCCESSFUL - BUFFER FULL            :
  2344                              <1> 	;		   FLAGS:  CARRY IF ERROR                                     :
  2345                              <1> 	;-----------------------------------------------------------------------------:		
  2346                              <1> 	;	(AH)= 10H  EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD,         :
  2347                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=0                            :
  2348                              <1> 	;-----------------------------------------------------------------------------:
  2349                              <1> 	;	(AH)= 11H  EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,           :
  2350                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=1                            :
  2351                              <1> 	;-----------------------------------------------------------------------------:	
  2352                              <1> 	;	(AH)= 12H  RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER            :
  2353                              <1> 	;		   AL = BITS FROM KB_FLAG, AH = BITS FOR LEFT AND RIGHT       :
  2354                              <1> 	;		   CTL AND ALT KEYS FROM KB_FLAG_1 AND KB_FLAG_3              :
  2355                              <1> 	; OUTPUT					                              :
  2356                              <1> 	;	AS NOTED ABOVE, ONLY (AX) AND FLAGS CHANGED	                      :
  2357                              <1> 	;	ALL REGISTERS RETAINED		                                      :
  2358                              <1> 	;------------------------------------------------------------------------------
  2359                              <1> 
  2360                              <1> KEYBOARD_IO_1:	
  2361 00000C62 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2362 00000C63 1E                  <1> 	push	ds			; SAVE CURRENT DS
  2363 00000C64 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
  2364                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
  2365 00000C65 66BB1000            <1>         mov     bx, KDATA 
  2366 00000C69 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
  2367 00000C6B 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
  2368 00000C6D 7439                <1> 	jz	short _K1		; ASCII_READ
  2369 00000C6F FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
  2370 00000C71 7452                <1>         jz      short _K2               ; ASCII_STATUS
  2371 00000C73 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
  2372 00000C75 0F8485000000        <1>         jz      _K3                     ; SHIFT STATUS
  2373 00000C7B FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
  2374 00000C7D 0F8484000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
  2375 00000C83 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
  2376 00000C86 0F84A1000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
  2377                              <1> _KIO1:	
  2378 00000C8C 80EC0B              <1> 	sub	ah, 11			; AH =  10H
  2379 00000C8F 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
  2380 00000C91 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
  2381 00000C93 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
  2382 00000C95 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
  2383 00000C97 7449                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
  2384                              <1> _KIO_EXIT:
  2385                              <1> 	;pop	ecx			; RECOVER REGISTER
  2386 00000C99 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2387 00000C9A 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2388 00000C9B CF                  <1> 	iretd				; INVALID COMMAND, EXIT
  2389                              <1> 
  2390                              <1> 	;-----	ASCII CHARACTER
  2391                              <1> _K1E:	
  2392 00000C9C E8B9000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
  2393 00000CA1 E82E010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2394 00000CA6 EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
  2395                              <1> _K1:	
  2396 00000CA8 E8AD000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
  2397 00000CAD E82D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2398 00000CB2 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
  2399                              <1> _K1A:
  2400 00000CB4 EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
  2401                              <1> 
  2402                              <1> 	;-----	ASCII STATUS
  2403                              <1> _K2E:	
  2404 00000CB6 E8EA000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
  2405 00000CBB 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2406 00000CBD 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2407 00000CBE E811010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2408 00000CC3 EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
  2409                              <1> _K2:	
  2410 00000CC5 E8DB000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
  2411 00000CCA 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2412 00000CCC 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2413 00000CCD E80D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2414 00000CD2 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
  2415 00000CD4 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
  2416 00000CD5 E880000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
  2417 00000CDA EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
  2418                              <1> _K2A:
  2419 00000CDC 9D                  <1> 	popf				; RESTORE ZF FROM TEST
  2420                              <1> _K2B:
  2421                              <1> 	;pop	ecx			; RECOVER REGISTER
  2422 00000CDD 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2423 00000CDE 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2424 00000CDF CA0400              <1> 	retf	4			; THROW AWAY (e)FLAGS
  2425                              <1> 
  2426                              <1> 	;-----	SHIFT STATUS
  2427                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
  2428 00000CE2 8A25[A2720000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2429 00000CE8 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2430                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2431                              <1> 	;shl	ah, cl			; BIT 7 POSITION
  2432 00000CEB C0E405              <1>         shl	ah, 5
  2433 00000CEE A0[A2720000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2434 00000CF3 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2435 00000CF5 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2436 00000CF7 A0[A4720000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2437 00000CFC 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2438 00000CFE 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2439                              <1> _K3:
  2440 00000D00 A0[A1720000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2441 00000D05 EB92                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2442                              <1> 
  2443                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
  2444                              <1> _K300:
  2445 00000D07 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
  2446 00000D09 758E                <1> 	jne	short _KIO_EXIT		; NO, RETURN
  2447 00000D0B F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
  2448 00000D0E 7589                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2449 00000D10 F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
  2450 00000D13 7584                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2451 00000D15 B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
  2452 00000D17 E8DA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2453                              <1> 	;mov	cx, 5			; SHIFT COUNT
  2454                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
  2455 00000D1C C0E705              <1> 	shl	bh, 5
  2456 00000D1F 88D8                <1> 	mov	al, bl			; PUT IN RATE
  2457 00000D21 08F8                <1> 	or	al, bh			; AND DELAY
  2458 00000D23 E8CE060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2459 00000D28 E96CFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
  2460                              <1> 
  2461                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
  2462                              <1> _K500:
  2463 00000D2D 56                  <1> 	push	esi			; SAVE SI (esi)
  2464 00000D2E FA                  <1> 	cli				; 
  2465 00000D2F 8B1D[B2720000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
  2466 00000D35 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
  2467 00000D37 E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
  2468 00000D3C 3B1D[AE720000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
  2469 00000D42 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
  2470 00000D44 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
  2471 00000D47 891D[B2720000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
  2472 00000D4D 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
  2473 00000D4F EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
  2474                              <1> _K502:
  2475 00000D51 B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
  2476                              <1> _K504:
  2477 00000D53 FB                  <1> 	sti				
  2478 00000D54 5E                  <1> 	pop	esi			; RECOVER SI (esi)
  2479 00000D55 E93FFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
  2480                              <1> 
  2481                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
  2482                              <1> _K1S:
  2483 00000D5A FA                  <1> 	cli	; 03/12/2014
  2484 00000D5B 8B1D[AE720000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2485 00000D61 3B1D[B2720000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2486                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
  2487 00000D67 750F                <1> 	jne	short _k1x ; 03/12/2014
  2488                              <1> 	;
  2489                              <1> 	; 03/12/2014
  2490                              <1> 	; 28/08/2014
  2491                              <1> 	; PERFORM OTHER FUNCTION ?? here !
  2492                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
  2493                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
  2494                              <1> _K1T:                                   ; ASCII READ
  2495 00000D69 FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
  2496 00000D6A 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
  2497                              <1> _K1U:	
  2498 00000D6B FA                  <1> 	cli				; INTERRUPTS BACK OFF
  2499 00000D6C 8B1D[AE720000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2500 00000D72 3B1D[B2720000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2501                              <1> _k1x:
  2502 00000D78 53                  <1> 	push	ebx			; SAVE ADDRESS		
  2503 00000D79 9C                  <1> 	pushf				; SAVE FLAGS
  2504 00000D7A E82F070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2505 00000D7F 8A1D[A3720000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2506 00000D85 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2507 00000D87 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
  2508 00000D8A 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
  2509 00000D8C E8C9060000          <1> 	call	SND_LED1
  2510 00000D91 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2511                              <1> _K1V:
  2512 00000D92 9D                  <1> 	popf				; RESTORE FLAGS
  2513 00000D93 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2514 00000D94 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
  2515                              <1> 	;
  2516 00000D96 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
  2517 00000D99 E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
  2518 00000D9E 891D[AE720000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
  2519 00000DA4 C3                  <1> 	retn				; RETURN
  2520                              <1> 
  2521                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
  2522                              <1> _K2S:
  2523 00000DA5 FA                  <1> 	cli				; INTERRUPTS OFF
  2524 00000DA6 8B1D[AE720000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
  2525 00000DAC 3B1D[B2720000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
  2526 00000DB2 668B03              <1> 	mov	ax, [ebx]
  2527 00000DB5 9C                  <1> 	pushf				; SAVE FLAGS
  2528 00000DB6 6650                <1> 	push	ax			; SAVE CODE
  2529 00000DB8 E8F1060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2530 00000DBD 8A1D[A3720000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2531 00000DC3 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2532 00000DC5 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
  2533 00000DC8 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
  2534 00000DCA E874060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2535                              <1> _K2T:
  2536 00000DCF 6658                <1> 	pop	ax			; RESTORE CODE
  2537 00000DD1 9D                  <1> 	popf				; RESTORE FLAGS
  2538 00000DD2 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2539 00000DD3 C3                  <1> 	retn				; RETURN
  2540                              <1> 
  2541                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
  2542                              <1> _KIO_E_XLAT:
  2543 00000DD4 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2544 00000DD6 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
  2545 00000DD8 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
  2546 00000DDA 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
  2547 00000DDC 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
  2548                              <1> _KIO_E_RET:				
  2549 00000DDE C3                  <1> 	retn				; GO BACK
  2550                              <1> 
  2551                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
  2552                              <1> _KIO_S_XLAT:
  2553 00000DDF 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
  2554 00000DE2 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
  2555 00000DE4 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
  2556 00000DE6 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
  2557 00000DE8 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
  2558 00000DEA 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
  2559 00000DEC B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
  2560                              <1> _kio_ret: ; 03/12/2014
  2561 00000DEE F8                  <1> 	clc
  2562 00000DEF C3                  <1> 	retn
  2563                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2564                              <1> _KIO_S1:				
  2565 00000DF0 B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
  2566                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2567 00000DF2 C3                  <1> 	retn
  2568                              <1> _KIO_S2:		
  2569 00000DF3 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
  2570 00000DF6 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
  2571 00000DF8 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2572 00000DFA 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
  2573 00000DFC 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2574 00000DFE 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
  2575 00000E00 EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
  2576                              <1> _KIO_S3:
  2577 00000E02 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
  2578                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
  2579 00000E04 75E8                <1> 	jne	short _kio_ret
  2580 00000E06 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2581 00000E08 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
  2582 00000E0A 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
  2583                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
  2584                              <1> _KIO_USE:
  2585                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
  2586 00000E0C C3                  <1> 	retn				; RETURN	
  2587                              <1> _KIO_DIS:
  2588 00000E0D F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
  2589 00000E0E C3                  <1> 	retn				; RETURN
  2590                              <1> 
  2591                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
  2592                              <1> _K4:    
  2593 00000E0F 43                  <1> 	inc     ebx
  2594 00000E10 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
  2595 00000E11 3B1D[AA720000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
  2596                              <1>         ;jne    short _K5               ; NO, CONTINUE
  2597 00000E17 7206                <1> 	jb	short _K5
  2598 00000E19 8B1D[A6720000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
  2599                              <1> _K5:
  2600 00000E1F C3                  <1> 	retn
  2601                              <1> 
  2602                              <1> ; 20/02/2015
  2603                              <1> ; 05/12/2014
  2604                              <1> ; 26/08/2014
  2605                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
  2606                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
  2607                              <1> ;
  2608                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
  2609                              <1> ; rombios source code (06/10/1985)
  2610                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
  2611                              <1> 
  2612                              <1> ; EQUATES (IBM PC-XT-286 BIOS, 1986, 'POSQEQU.INC')
  2613                              <1> 
  2614                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
  2615                              <1> ENA_KBD		equ	0AEh		; ENABLE KEYBOARD COMMAND
  2616                              <1> DIS_KBD		equ	0ADh		; DISABLE KEYBOARD COMMAND
  2617                              <1> SHUT_CMD	equ	0FEh		; CAUSE A SHUTDOWN COMMAND
  2618                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  2619                              <1> STATUS_PORT	equ	064h		; 8042 STATUS PORT
  2620                              <1> INPT_BUF_FULL	equ	00000010b 	; 1 = +INPUT BUFFER FULL
  2621                              <1> PORT_A		equ	060h		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  2622                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
  2623                              <1> KB_ACK		equ	0FAh		; ACKNOWLEDGE PROM TRANSMISSION
  2624                              <1> KB_RESEND	equ	0FEh		; RESEND REQUEST
  2625                              <1> KB_OVER_RUN	equ	0FFh		; OVER RUN SCAN CODE
  2626                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
  2627                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
  2628                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
  2629                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
  2630                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
  2631                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
  2632                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
  2633                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
  2634                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
  2635                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
  2636                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
  2637                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
  2638                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
  2639                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
  2640                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
  2641                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
  2642                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
  2643                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
  2644                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
  2645                              <1> F11_M		equ	87		; F11 KEY MAKE
  2646                              <1> F12_M		equ	88		; F12 KEY MAKE
  2647                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
  2648                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
  2649                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
  2650                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
  2651                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
  2652                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
  2653                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
  2654                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
  2655                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
  2656                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
  2657                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
  2658                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
  2659                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
  2660                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
  2661                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
  2662                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
  2663                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
  2664                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
  2665                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
  2666                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
  2667                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
  2668                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
  2669                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
  2670                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
  2671                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
  2672                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
  2673                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
  2674                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
  2675                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
  2676                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
  2677                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
  2678                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
  2679                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
  2680                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
  2681                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
  2682                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
  2683                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
  2684                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
  2685                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
  2686                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
  2687                              <1> ;
  2688                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
  2689                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
  2690                              <1> INTA00		equ	020h		; 8259 PORT
  2691                              <1> 
  2692                              <1> 
  2693                              <1> kb_int:
  2694                              <1> 
  2695                              <1> ; 17/10/2015 ('ctrlbrk') 
  2696                              <1> ; 05/12/2014
  2697                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-)
  2698                              <1> ; 26/08/2014
  2699                              <1> ;
  2700                              <1> ; 03/06/86  KEYBOARD BIOS
  2701                              <1> ;
  2702                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
  2703                              <1> ;										;
  2704                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
  2705                              <1> ;										;
  2706                              <1> ;--------------------------------------------------------------------------------
  2707                              <1> 
  2708                              <1> KB_INT_1:
  2709 00000E20 FB                  <1> 	sti				; ENABLE INTERRUPTS
  2710                              <1> 	;push	ebp
  2711 00000E21 50                  <1> 	push	eax
  2712 00000E22 53                  <1> 	push	ebx
  2713 00000E23 51                  <1> 	push	ecx
  2714 00000E24 52                  <1> 	push	edx
  2715 00000E25 56                  <1> 	push	esi
  2716 00000E26 57                  <1> 	push	edi
  2717 00000E27 1E                  <1> 	push	ds
  2718 00000E28 06                  <1> 	push	es
  2719 00000E29 FC                  <1> 	cld				; FORWARD DIRECTION
  2720 00000E2A 66B81000            <1> 	mov	ax, KDATA
  2721 00000E2E 8ED8                <1> 	mov	ds, ax
  2722 00000E30 8EC0                <1> 	mov	es, ax
  2723                              <1> 	;
  2724                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
  2725 00000E32 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
  2726 00000E34 E8A9050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
  2727 00000E39 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2728 00000E3A B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
  2729                              <1> KB_INT_01:
  2730 00000E3F E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
  2731 00000E41 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
  2732 00000E43 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
  2733                              <1> 	;
  2734                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
  2735 00000E45 E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
  2736                              <1> 	;
  2737                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
  2738                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
  2739                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
  2740                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
  2741                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
  2742                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
  2743                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
  2744                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
  2745                              <1> 	;
  2746                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
  2747                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
  2748 00000E47 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  2749 00000E48 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
  2750 00000E4A 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
  2751                              <1> 	;
  2752                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
  2753 00000E4C 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
  2754 00000E4E 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
  2755                              <1> 	;
  2756                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
  2757 00000E50 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2758 00000E51 800D[A3720000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
  2759 00000E58 E97A020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
  2760                              <1> 	;
  2761                              <1> 	;-----	RESEND THE LAST BYTE
  2762                              <1> KB_INT_4:
  2763 00000E5D FA                  <1> 	cli				; DISABLE INTERRUPTS
  2764 00000E5E 800D[A3720000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
  2765 00000E65 E96D020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
  2766                              <1> 	;
  2767                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
  2768                              <1> KB_INT_2:
  2769 00000E6A 6650                <1> 	push 	ax			; SAVE DATA IN
  2770 00000E6C E83D060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2771 00000E71 8A1D[A3720000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2772 00000E77 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2773 00000E79 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
  2774 00000E7C 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
  2775 00000E7E E8C0050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2776                              <1> UP0:
  2777 00000E83 6658                <1> 	pop	ax			; RESTORE DATA IN
  2778                              <1> ;------------------------------------------------------------------------
  2779                              <1> ;	START OF KEY PROCESSING						;
  2780                              <1> ;------------------------------------------------------------------------
  2781 00000E85 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
  2782                              <1> 	;
  2783                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
  2784 00000E87 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
  2785 00000E89 0F843F050000        <1>         je      K62			; BUFFER_FULL_BEEP
  2786                              <1> 	;
  2787                              <1> K16:	
  2788 00000E8F 8A3D[A4720000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
  2789                              <1> 	;
  2790                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
  2791 00000E95 F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
  2792 00000E98 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
  2793 00000E9A 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
  2794 00000E9C 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
  2795 00000E9E 7507                <1> 	jne	short RST_RD_ID
  2796 00000EA0 800D[A4720000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
  2797                              <1> RST_RD_ID:
  2798 00000EA7 8025[A4720000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
  2799                              <1>         ;jmp    short ID_EX		; AND EXIT
  2800 00000EAE E924020000          <1> 	jmp	K26
  2801                              <1> 	;
  2802                              <1> TST_ID_2:
  2803 00000EB3 8025[A4720000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
  2804 00000EBA 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
  2805 00000EBC 7419                <1>         je	short KX_BIT		; JUMP IF SO
  2806 00000EBE 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
  2807                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
  2808 00000EC0 0F8511020000        <1> 	jne	K26
  2809                              <1> 	;
  2810                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
  2811 00000EC6 F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
  2812 00000EC9 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
  2813 00000ECB 800D[A1720000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
  2814 00000ED2 E86C050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
  2815                              <1> KX_BIT:
  2816 00000ED7 800D[A4720000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
  2817 00000EDE E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
  2818                              <1> 	;
  2819                              <1> NOT_ID:
  2820 00000EE3 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
  2821 00000EE5 750C                <1> 	jne	short TEST_E1
  2822 00000EE7 800D[A4720000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
  2823                              <1> 	;jmp	short EXIT		; THROW AWAY THIS CODE
  2824 00000EEE E9EB010000          <1> 	jmp	K26A	
  2825                              <1> TEST_E1:	
  2826 00000EF3 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
  2827 00000EF5 750C                <1> 	jne	short NOT_HC
  2828 00000EF7 800D[A4720000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
  2829 00000EFE E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
  2830                              <1> 	;
  2831                              <1> NOT_HC:
  2832 00000F03 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
  2833 00000F05 F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
  2834 00000F08 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
  2835                              <1> 	;
  2836 00000F0A BF[8E710000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
  2837 00000F0F AE                  <1> 	scasb
  2838 00000F10 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
  2839 00000F16 AE                  <1> 	scasb
  2840 00000F17 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
  2841                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
  2842 00000F19 E9B9010000          <1> 	jmp	K26
  2843                              <1> 	;
  2844                              <1> NOT_LC_E0:
  2845 00000F1E F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
  2846 00000F21 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
  2847 00000F23 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
  2848 00000F28 BF[8C710000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
  2849 00000F2D F2AE                <1> 	repne	scasb			; CHECK IT
  2850                              <1> 	;je	short EXIT		; THROW AWAY IF SO
  2851 00000F2F 0F84A9010000        <1> 	je	K26A			
  2852                              <1> 	;
  2853 00000F35 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
  2854                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
  2855 00000F37 0F859A010000        <1> 	jne	K26
  2856 00000F3D F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
  2857                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
  2858 00000F40 0F8591010000        <1> 	jnz	K26
  2859                              <1>         ; 20/02/2015 
  2860 00000F46 F605[A2720000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
  2861                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
  2862 00000F4D 0F8584010000        <1> 	jnz	K26
  2863 00000F53 E9E1020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
  2864                              <1> 	;
  2865                              <1> 	;-----	TEST FOR SYSTEM KEY
  2866                              <1> T_SYS_KEY:
  2867 00000F58 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
  2868 00000F5A 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
  2869                              <1> 	;
  2870 00000F5C F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
  2871 00000F5F 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
  2872                              <1> 	;
  2873 00000F61 F605[A2720000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
  2874                              <1>         ;jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
  2875 00000F68 0F8569010000        <1> 	jnz     K26			
  2876                              <1> 	;
  2877 00000F6E 800D[A2720000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
  2878 00000F75 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  2879 00000F77 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  2880                              <1> 					; INTERRUPT-RETURN-NO-EOI
  2881 00000F79 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  2882 00000F7B E862040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  2883                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
  2884                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
  2885                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  2886                              <1> 	;INT	15H			; USER INTERRUPT	
  2887 00000F80 E965010000          <1>         jmp     K27A                    ; END PROCESSING
  2888                              <1> 	;
  2889                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
  2890                              <1> 	;
  2891                              <1> K16C:
  2892 00000F85 8025[A2720000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
  2893 00000F8C B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  2894 00000F8E E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
  2895                              <1> 					; INTERRUPT-RETURN-NO-EOI
  2896                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  2897                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  2898                              <1> 	;
  2899                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
  2900                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  2901                              <1> 	;INT	15H			; USER INTERRUPT
  2902                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
  2903                              <1> 	;
  2904 00000F90 E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
  2905                              <1> 	;
  2906                              <1> 	;-----	TEST FOR SHIFT KEYS
  2907                              <1> K16A:
  2908 00000F95 8A1D[A1720000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
  2909 00000F9B BF[88710000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
  2910 00000FA0 B908000000          <1> 	mov	ecx, _K6L		; LENGTH
  2911 00000FA5 F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
  2912 00000FA7 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
  2913 00000FA9 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
  2914                              <1> 	;
  2915                              <1> 	;------	SHIFT KEY FOUND
  2916                              <1> K17:
  2917 00000FAF 81EF[89710000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
  2918 00000FB5 8AA7[90710000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
  2919 00000FBB B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
  2920 00000FBD A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
  2921 00000FBF 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
  2922                              <1> 	;
  2923                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
  2924                              <1> K17C:
  2925 00000FC5 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
  2926 00000FC8 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
  2927                              <1> 	;
  2928                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
  2929 00000FCA 0825[A1720000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
  2930 00000FD0 A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
  2931                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
  2932 00000FD2 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
  2933                              <1> K17D:
  2934 00000FD8 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
  2935 00000FDB 740B                <1> 	jz 	short K17E		; NO, JUMP
  2936 00000FDD 0825[A4720000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
  2937 00000FE3 E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
  2938                              <1> K17E:
  2939 00000FE8 D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
  2940 00000FEA 0825[A2720000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
  2941 00000FF0 E9E2000000          <1> 	jmp	K26
  2942                              <1> 	;
  2943                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
  2944                              <1> K18:					; SHIFT-TOGGLE
  2945 00000FF5 F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
  2946                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
  2947 00000FF8 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
  2948                              <1> K18A:
  2949 00000FFE 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
  2950 00001000 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
  2951 00001002 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
  2952                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
  2953 00001005 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
  2954                              <1> K18B:
  2955 0000100B F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
  2956 0000100E 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
  2957                              <1> K19:	
  2958 00001010 F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
  2959 00001013 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
  2960 00001015 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
  2961 00001018 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
  2962                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
  2963 0000101A 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
  2964 0000101C E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
  2965                              <1> K21:					; MIGHT BE NUMERIC
  2966 00001021 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
  2967 00001024 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
  2968                              <1> 	;
  2969                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
  2970 00001026 8425[A2720000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
  2971 0000102C 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
  2972                              <1> K22A:
  2973 00001032 0825[A2720000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
  2974 00001038 3025[A1720000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
  2975                              <1> 	;
  2976                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
  2977 0000103E F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
  2978 00001041 7409                <1> 	jz	short K22B		; GO IF NOT
  2979                              <1> 	;
  2980 00001043 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
  2981 00001045 E8F9030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
  2982 0000104A 6658                <1> 	pop	ax			; RESTORE SCAN CODE
  2983                              <1> K22B:
  2984 0000104C 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
  2985 0000104E 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
  2986 00001054 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
  2987 00001056 E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
  2988                              <1> 	;
  2989                              <1> 	;-----	BREAK SHIFT FOUND
  2990                              <1> K23:					; BREAK-SHIFT-FOUND
  2991 0000105B 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
  2992 0000105E F6D4                <1> 	not	ah			; INVERT MASK
  2993 00001060 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
  2994 00001062 2025[A1720000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
  2995 00001068 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
  2996 0000106B 7730                <1> 	ja	short K23D		; NO, ALL DONE
  2997                              <1> 	;
  2998 0000106D F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
  2999 00001070 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
  3000 00001072 2025[A4720000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
  3001 00001078 EB08                <1> 	jmp	short K23B		; CONTINUE
  3002                              <1> K23A:
  3003 0000107A D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
  3004 0000107C 2025[A2720000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
  3005                              <1> K23B:
  3006 00001082 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
  3007 00001084 A0[A4720000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
  3008 00001089 D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
  3009 0000108B 0A05[A2720000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
  3010 00001091 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
  3011 00001093 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
  3012 00001095 0805[A1720000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
  3013 0000109B 88E0                <1> 	mov	al, ah
  3014                              <1> K23D:
  3015 0000109D 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
  3016 0000109F 7536                <1> 	jne	short K26		; INTERRUPT RETURN
  3017                              <1> 	;	
  3018                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
  3019 000010A1 A0[A5720000]        <1> 	mov	al, [ALT_INPUT]
  3020 000010A6 B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
  3021 000010A8 8825[A5720000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
  3022 000010AE 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
  3023 000010B0 7425                <1> 	je	short K26		; INTERRUPT_RETURN
  3024                              <1>         ; 29/01/2016
  3025                              <1> 	;jmp     K61                    ; IT WASN'T, SO PUT IN BUFFER
  3026 000010B2 E9D0020000          <1> 	jmp	_K60
  3027                              <1> 	;
  3028                              <1> K24:					; BREAK-TOGGLE
  3029 000010B7 2025[A2720000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
  3030 000010BD EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
  3031                              <1> 	;
  3032                              <1> 	;-----	TEST FOR HOLD STATE
  3033                              <1> 					; AL, AH = SCAN CODE
  3034                              <1> K25:					; NO-SHIFT-FOUND
  3035 000010BF 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
  3036 000010C1 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
  3037 000010C3 F605[A2720000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
  3038 000010CA 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
  3039 000010CC 3C45                <1> 	cmp	al, NUM_KEY
  3040 000010CE 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
  3041 000010D0 8025[A2720000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
  3042                              <1> 	;
  3043                              <1> K26:
  3044 000010D7 8025[A4720000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3045                              <1> K26A:					; INTERRUPT-RETURN
  3046 000010DE FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3047 000010DF B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3048 000010E1 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3049                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
  3050 000010E3 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3051 000010E5 E8F8020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3052                              <1> K27A:
  3053 000010EA FA                  <1> 	cli				; DISABLE INTERRUPTS
  3054 000010EB 07                  <1> 	pop	es			; RESTORE REGISTERS
  3055 000010EC 1F                  <1> 	pop	ds
  3056 000010ED 5F                  <1> 	pop	edi
  3057 000010EE 5E                  <1> 	pop	esi
  3058 000010EF 5A                  <1> 	pop	edx
  3059 000010F0 59                  <1> 	pop	ecx
  3060 000010F1 5B                  <1> 	pop	ebx
  3061 000010F2 58                  <1> 	pop	eax
  3062                              <1> 	;pop	ebp
  3063 000010F3 CF                  <1> 	iret				; RETURN
  3064                              <1> 
  3065                              <1> 	;-----	NOT IN	HOLD STATE
  3066                              <1> K28:					; NO-HOLD-STATE
  3067 000010F4 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
  3068 000010F6 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
  3069                              <1> 	;
  3070 000010F8 F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
  3071                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
  3072 000010FB 0F84F1000000        <1>         jz      K38
  3073                              <1> 	;
  3074 00001101 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
  3075 00001104 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  3076                              <1> 	 ;28/02/2015
  3077 00001106 F605[A2720000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
  3078                              <1> 	;jz	short K29		;  NO, ALT STATE IS REAL
  3079 0000110D 0F85DF000000        <1> 	jnz	K38			; YES, THIS IS PHONY ALT STATE 
  3080                              <1>         ;				; DUE TO PRESSING SYSREQ	
  3081                              <1> ;K28A:	jmp	short K38
  3082                              <1> 	;
  3083                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
  3084                              <1> K29:					; TEST-RESET
  3085 00001113 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
  3086 00001116 740B                <1> 	jz	short K31		; NO_RESET
  3087 00001118 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
  3088 0000111A 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
  3089                              <1> 	;
  3090                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
  3091                              <1>  	; 26/08/2014
  3092                              <1> cpu_reset:
  3093                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
  3094                              <1> 	; Send FEh (system reset command) to the keyboard controller.
  3095 0000111C B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
  3096 0000111E E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
  3097                              <1> khere:
  3098 00001120 F4                  <1> 	hlt				; WAIT FOR 80286 RESET
  3099 00001121 EBFD                <1> 	jmp 	short khere		; INSURE HALT
  3100                              <1> 
  3101                              <1> 	;
  3102                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
  3103                              <1> K31:					; NO-RESET
  3104 00001123 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
  3105 00001125 7507                <1> 	jne	short K311		; NOT THERE
  3106 00001127 B020                <1> 	mov	al, ' '			; SET SPACE CHAR
  3107 00001129 E948020000          <1>         jmp     K57                     ; BUFFER_FILL
  3108                              <1> K311:
  3109 0000112E 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
  3110 00001130 7509                <1> 	jne	short K312		; NOT THERE
  3111 00001132 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
  3112 00001136 E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
  3113                              <1> K312:
  3114 0000113B 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
  3115 0000113D 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
  3116 00001143 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
  3117 00001145 0F849A000000        <1>         je      K37B                    ; GO PROCESS
  3118                              <1> 	;
  3119                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
  3120                              <1> K32:					; ALT-KEY-PAD
  3121 0000114B BF[64710000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
  3122 00001150 B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
  3123 00001155 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
  3124 00001157 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
  3125 00001159 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
  3126 0000115C 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
  3127 00001162 81EF[65710000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
  3128 00001168 A0[A5720000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
  3129 0000116D B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
  3130 0000116F F6E4                <1> 	mul	ah
  3131 00001171 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
  3132 00001174 A2[A5720000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
  3133                              <1> ;K32A:
  3134 00001179 E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
  3135                              <1> 	;
  3136                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
  3137                              <1> K33:					; NO-ALT-KEYPAD
  3138 0000117E C605[A5720000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
  3139 00001185 B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
  3140 0000118A F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
  3141 0000118C 7450                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
  3142                              <1> 	;
  3143                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
  3144                              <1> K34:					; ALT-TOP-ROW
  3145 0000118E 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
  3146 00001190 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
  3147 00001192 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
  3148 00001194 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
  3149 00001196 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
  3150 00001199 EB43                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3151                              <1> 	;
  3152                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
  3153                              <1> K35:					; ALT-FUNCTION
  3154 0000119B 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
  3155 0000119D 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
  3156 0000119F 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
  3157 000011A1 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
  3158 000011A3 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
  3159 000011A6 EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3160                              <1> K35A:
  3161 000011A8 F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
  3162 000011AB 7422                <1> 	jz	short K37		; NO, JUMP
  3163 000011AD 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
  3164 000011AF 7509                <1>         jne     short K35B              ; NOT THERE
  3165 000011B1 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
  3166 000011B5 E9BC010000          <1> 	jmp	K57			; BUFFER FILL
  3167                              <1> K35B:
  3168 000011BA 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
  3169 000011BC 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
  3170 000011BE 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
  3171                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
  3172 000011C0 0F8511FFFFFF        <1>         jne     K26
  3173 000011C6 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
  3174 000011CA E9A7010000          <1> 	jmp	K57			; BUFFER FILL
  3175                              <1> K37:
  3176 000011CF 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
  3177 000011D1 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
  3178 000011D3 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
  3179                              <1>         ;ja	short K32A		; IF SO, IGNORE
  3180 000011D5 0F87FCFEFFFF        <1>         ja      K26
  3181 000011DB 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
  3182                              <1> K37A:
  3183 000011DE B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  3184 000011E0 E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  3185                              <1> K37B:
  3186 000011E5 B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  3187 000011E7 E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  3188                              <1> K37C:
  3189 000011EC 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  3190 000011EE 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  3191 000011F0 EBEC                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  3192                              <1> 	;
  3193                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  3194                              <1> K38:					; NOT-ALT-SHIFT
  3195                              <1> 					; BL STILL HAS SHIFT FLAGS
  3196 000011F2 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  3197                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
  3198 000011F5 0F84B0000000        <1>         jz      K44                     ; NOT-CTL-SHIFT
  3199                              <1> 	;
  3200                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  3201                              <1> 	;-----	TEST FOR BREAK
  3202                              <1> K38A:
  3203 000011FB 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  3204 000011FD 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
  3205 000011FF F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3206 00001202 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  3207 00001204 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3208 00001207 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  3209                              <1> K38B:
  3210 00001209 8B1D[AE720000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  3211 0000120F 891D[B2720000]      <1> 	mov	[BUFFER_TAIL], ebx
  3212 00001215 C605[A0720000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  3213                              <1> 	;
  3214                              <1> 	;-----	ENABLE KEYBOARD
  3215 0000121C B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3216 0000121E E8BF010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3217                              <1> 	;
  3218                              <1> 	; CTRL+BREAK code here !!!
  3219                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  3220                              <1> 	; 17/10/2015	
  3221 00001223 E8F42A0000          <1> 	call	ctrlbrk ; control+break subroutine
  3222                              <1> 	;
  3223 00001228 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
  3224 0000122B E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  3225                              <1> 	;
  3226                              <1> 	;-----	TEST FOR PAUSE
  3227                              <1> K39:					; NO_BREAK
  3228 00001230 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3229 00001233 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  3230 00001235 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  3231 00001237 7533                <1> 	jne	short K41		; NO-PAUSE
  3232                              <1> K39P:
  3233 00001239 800D[A2720000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  3234                              <1> 	;
  3235                              <1> 	;-----	ENABLE KEYBOARD
  3236 00001240 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3237 00001242 E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3238                              <1> K39A:
  3239 00001247 B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  3240 00001249 E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  3241                              <1> 	;
  3242                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  3243 0000124B 803D[D6720000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  3244 00001252 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  3245 00001254 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  3246 00001258 A0[D7720000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  3247 0000125D EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  3248                              <1> 	;
  3249                              <1> K40:					; PAUSE-LOOP
  3250 0000125E F605[A2720000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  3251 00001265 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  3252                              <1> 	;
  3253 00001267 E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  3254                              <1>         ;
  3255                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  3256                              <1> K41:					; NO-PAUSE
  3257 0000126C 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  3258 0000126E 7513                <1> 	jne	short K42		; NOT-KEY-55
  3259 00001270 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3260 00001273 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  3261 00001275 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3262 00001278 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  3263                              <1> K41A:	
  3264 0000127A 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  3265 0000127E E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  3266                              <1> 	;
  3267                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  3268                              <1> K42:					; NOT-KEY-55
  3269 00001283 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  3270 00001285 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  3271 00001287 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  3272 00001289 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  3273 0000128B F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  3274 0000128E 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  3275 00001290 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  3276 00001294 E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  3277                              <1> K42A: 
  3278                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3279 00001299 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  3280                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  3281                              <1> 	;;jb	K56 ; 20/02/2015
  3282                              <1> 	;;jmp	K64 ; 20/02/2015
  3283                              <1> K42B:
  3284 0000129B BB[98710000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3285 000012A0 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  3286 000012A6 E9B9000000          <1> 	jmp	K64	
  3287                              <1>         ;
  3288                              <1> 	;-----	NOT IN CONTROL SHIFT
  3289                              <1> K44:					; NOT-CTL-SHIFT
  3290 000012AB 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  3291 000012AD 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  3292 000012AF F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  3293 000012B2 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  3294 000012B4 F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  3295 000012B7 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  3296 000012B9 EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3297                              <1> K44A:
  3298 000012BB F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  3299 000012BE 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3300                              <1> 	;
  3301                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  3302                              <1> K44B:
  3303 000012C0 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3304 000012C2 E81B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3305 000012C7 B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  3306 000012C9 E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  3307                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  3308                              <1> 	;PUSH 	BP			; SAVE POINTER
  3309                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  3310                              <1> 	;POP	BP			; RESTORE POINTER
  3311 000012CB 8025[A4720000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  3312 000012D2 E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  3313                              <1> 	;
  3314                              <1> 	;-----	HANDLE IN-CORE KEYS
  3315                              <1> K45:					; NOT-PRINT-SCREEN
  3316 000012D7 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  3317 000012D9 7734                <1> 	ja	short K46		; JUMP IF NOT
  3318 000012DB 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  3319 000012DD 7505                <1> 	jne	short K45A		; NO, JUMP
  3320 000012DF F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  3321 000012E2 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  3322                              <1> K45A:
  3323 000012E4 B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  3324 000012E9 BF[6E710000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  3325 000012EE F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  3326                              <1> 		; 20/02/2015
  3327 000012F0 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  3328                              <1> 	;
  3329 000012F2 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  3330 000012F5 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  3331                              <1> K45B:
  3332 000012F7 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3333 000012FA 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  3334                              <1> 					; NO, LOWERCASE
  3335                              <1> K45C:
  3336 000012FC BB[F0710000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  3337 00001301 EB51                <1> 	jmp	short K56	
  3338                              <1> K45D:					; ALMOST-CAPS-STATE
  3339 00001303 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  3340 00001306 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  3341                              <1> K45E:
  3342 00001308 BB[48720000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  3343 0000130D EB45                <1> K45F:	jmp	short K56
  3344                              <1> 	;
  3345                              <1> 	;-----	TEST FOR KEYS F1 - F10
  3346                              <1> K46:					; NOT IN-CORE AREA
  3347 0000130F 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  3348                              <1> 	;ja	short K47		; JUMP IF NOT
  3349                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  3350 00001311 7635                <1> 	jna	short K53		
  3351                              <1> 	;
  3352                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  3353                              <1> K47:					; NOT F1 - F10
  3354 00001313 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  3355 00001315 772D                <1> 	ja	short K52		; JUMP IF NOT
  3356                              <1> 	;
  3357                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  3358                              <1> K48:
  3359 00001317 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  3360 00001319 74ED                <1> 	je	short K45E		; GO TRANSLATE
  3361 0000131B 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  3362 0000131D 74E9                <1> 	je	short K45E		; GO TRANSLATE
  3363 0000131F F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  3364 00001322 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  3365                              <1> 	;		
  3366 00001324 F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  3367 00001327 7514                <1> 	jnz	short K50		; TEST FOR SURE
  3368 00001329 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3369                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  3370 0000132C 75DA                <1> 	jnz	short K45E
  3371                              <1> 	;
  3372                              <1> 	;-----	BASE CASE FOR KEYPAD
  3373                              <1> K49:					
  3374 0000132E 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  3375 00001330 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  3376 00001332 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  3377 00001334 EB40                <1> 	jmp	short K57		; BUFFER FILL
  3378                              <1> K49A:
  3379 00001336 BB[F0710000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  3380 0000133B EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  3381                              <1> 	;
  3382                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  3383                              <1> K50:					; ALMOST-NUM-STATE
  3384 0000133D F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  3385 00001340 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  3386 00001342 EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  3387                              <1> 	;
  3388                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  3389                              <1> K52:					; NOT A NUMPAD KEY
  3390 00001344 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  3391                              <1> 	;jne	short K53		; JUMP IF NOT
  3392                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  3393 00001346 74AF                <1> 	je	short K45B		
  3394                              <1> 	;
  3395                              <1> 	;-----	MUST BE F11 OR F12 
  3396                              <1> K53:					; F1 - F10 COME HERE, TOO
  3397 00001348 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  3398 0000134B 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  3399                              <1> 		; 20/02/2015 
  3400 0000134D BB[48720000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  3401 00001352 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  3402                              <1> 	;
  3403                              <1> 	;-----	TRANSLATE THE CHARACTER
  3404                              <1> K56:					; TRANSLATE-CHAR
  3405 00001354 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3406 00001356 D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  3407 00001357 F605[A4720000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3408 0000135E 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3409 00001360 B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  3410 00001362 EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  3411                              <1> 	;
  3412                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  3413                              <1> K64:					; TRANSLATE-SCAN-ORGD
  3414 00001364 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3415 00001366 D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  3416 00001367 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  3417 00001369 B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  3418 0000136B F605[A4720000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3419 00001372 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3420 00001374 B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  3421                              <1> 	;
  3422                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  3423                              <1> K57:					; BUFFER_FILL
  3424 00001376 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  3425                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  3426 00001378 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  3427 0000137E 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  3428                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  3429 00001381 0F8450FDFFFF        <1> 	je      K26			; INTERRUPT_RETURN
  3430                              <1> ;K59:					; NEAR_INTERRUPT_RETURN
  3431                              <1> ;	jmp	K26			; INTERRUPT_RETURN
  3432                              <1> 
  3433                              <1> _K60: ; 29/01/2016
  3434 00001387 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  3435 0000138A 721F                <1> 	jb	short K61
  3436 0000138C 80FC6F              <1> 	cmp	ah, 6Fh ; ALT + F8 key	
  3437 0000138F 771A                <1> 	ja	short K61
  3438                              <1> 	;
  3439 00001391 8A1D[F8780000]      <1> 	mov	bl, [ACTIVE_PAGE]
  3440 00001397 80C368              <1> 	add	bl, 68h
  3441 0000139A 38E3                <1> 	cmp	bl, ah
  3442 0000139C 740D                <1> 	je	short K61
  3443 0000139E 6650                <1> 	push	ax
  3444 000013A0 88E0                <1> 	mov	al, ah
  3445 000013A2 2C68                <1> 	sub	al, 68h
  3446 000013A4 E85D020000          <1> 	call	set_active_page
  3447 000013A9 6658                <1> 	pop	ax
  3448                              <1> K61:					; NOT-CAPS-STATE
  3449 000013AB 8B1D[B2720000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  3450 000013B1 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  3451 000013B3 E857FAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  3452 000013B8 3B1D[AE720000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  3453 000013BE 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  3454 000013C0 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  3455 000013C3 891D[B2720000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  3456 000013C9 E909FDFFFF          <1> 	jmp	K26
  3457                              <1> 	;;cli				; TURN OFF INTERRUPTS
  3458                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  3459                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  3460                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3461                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3462                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  3463                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  3464                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3465                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  3466                              <1> 	;;jmp   K27                    
  3467                              <1> 	;
  3468                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  3469                              <1> K62:
  3470 000013CE B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  3471 000013D0 E620                <1> 	out	INTA00, al
  3472 000013D2 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  3473 000013D6 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  3474 000013D8 E839050000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  3475 000013DD E901FDFFFF          <1> 	jmp     K27			; EXIT   
  3476                              <1> 
  3477                              <1> SHIP_IT:
  3478                              <1> 	;---------------------------------------------------------------------------------
  3479                              <1> 	; SHIP_IT
  3480                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3481                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  3482                              <1> 	;---------------------------------------------------------------------------------
  3483                              <1> 	;
  3484 000013E2 6650                <1> 	push	ax			; SAVE DATA TO SEND
  3485                              <1> 
  3486                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  3487 000013E4 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  3488                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  3489 000013E5 B900000100          <1> 	mov	ecx, 10000h			
  3490                              <1> S10:
  3491 000013EA E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  3492 000013EC A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  3493 000013EE E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  3494                              <1> 
  3495 000013F0 6658                <1> 	pop	ax			; GET DATA TO SEND
  3496 000013F2 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  3497 000013F4 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3498 000013F5 C3                  <1> 	retn				; RETURN TO CALLER
  3499                              <1> 
  3500                              <1> SND_DATA:
  3501                              <1> 	; ---------------------------------------------------------------------------------
  3502                              <1> 	; SND_DATA
  3503                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3504                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  3505                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  3506                              <1> 	; ---------------------------------------------------------------------------------
  3507                              <1> 	;
  3508 000013F6 6650                <1> 	push	ax			; SAVE REGISTERS
  3509 000013F8 6653                <1> 	push	bx
  3510 000013FA 51                  <1> 	push	ecx
  3511 000013FB 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  3512 000013FD B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  3513                              <1> SD0:
  3514 000013FF FA                  <1> 	cli				; DISABLE INTERRUPTS
  3515 00001400 8025[A3720000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  3516                              <1> 	;
  3517                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  3518 00001407 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  3519                              <1> SD5:
  3520 0000140C E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  3521 0000140E A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  3522 00001410 E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  3523                              <1> 	;
  3524 00001412 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  3525 00001414 E660                <1> 	out	PORT_A, al		; SEND BYTE
  3526 00001416 FB                  <1> 	sti				; ENABLE INTERRUPTS
  3527                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  3528 00001417 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  3529                              <1> SD1:
  3530 0000141C F605[A3720000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  3531 00001423 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  3532 00001425 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  3533                              <1> SD2:
  3534 00001427 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  3535 00001429 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  3536 0000142B 800D[A3720000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  3537 00001432 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  3538                              <1> SD3:
  3539 00001434 F605[A3720000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  3540 0000143B 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  3541                              <1> SD4:	
  3542 0000143D 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  3543 0000143E 665B                <1> 	pop	bx
  3544 00001440 6658                <1> 	pop	ax
  3545 00001442 C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  3546                              <1> 
  3547                              <1> SND_LED:
  3548                              <1> 	; ---------------------------------------------------------------------------------
  3549                              <1> 	; SND_LED
  3550                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  3551                              <1> 	;
  3552                              <1> 	;----------------------------------------------------------------------------------
  3553                              <1> 	;
  3554 00001443 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3555 00001444 F605[A3720000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3556 0000144B 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3557                              <1> 	;
  3558 0000144D 800D[A3720000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3559 00001454 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3560 00001456 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3561 00001458 EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  3562                              <1> SND_LED1:
  3563 0000145A FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3564 0000145B F605[A3720000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3565 00001462 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3566                              <1> 	;
  3567 00001464 800D[A3720000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3568                              <1> SL0:
  3569 0000146B B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  3570 0000146D E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3571 00001472 FA                  <1> 	cli
  3572 00001473 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  3573 00001478 8025[A3720000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  3574 0000147F 0805[A3720000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  3575 00001485 F605[A3720000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3576 0000148C 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  3577                              <1> 	;
  3578 0000148E E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3579 00001493 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3580 00001494 F605[A3720000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3581 0000149B 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  3582                              <1> SL2:
  3583 0000149D B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  3584 0000149F E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3585 000014A4 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3586                              <1> SL3:
  3587 000014A5 8025[A3720000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  3588                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  3589 000014AC FB                  <1> 	sti				; ENABLE INTERRUPTS
  3590 000014AD C3                  <1> 	retn				; RETURN TO CALLER
  3591                              <1> 
  3592                              <1> MAKE_LED:
  3593                              <1> 	;---------------------------------------------------------------------------------
  3594                              <1> 	; MAKE_LED
  3595                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  3596                              <1> 	;	THE MODE INDICATORS.
  3597                              <1> 	;---------------------------------------------------------------------------------
  3598                              <1> 	;
  3599                              <1> 	;push 	cx			; SAVE CX
  3600 000014AE A0[A1720000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  3601 000014B3 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  3602                              <1> 	;mov	cl, 4			; SHIFT COUNT
  3603                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  3604 000014B5 C0C004              <1> 	rol	al, 4 ; 20/02/2015
  3605 000014B8 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  3606                              <1> 	;pop	cx
  3607 000014BA C3                  <1> 	retn				; RETURN TO CALLER
  3608                              <1> 
  3609                              <1> ; % include 'kybdata.s'   ; KEYBOARD DATA
  3610                              <1> 
  3611                              <1> 
  3612                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  3613                                  
  3614                                  %include 'video.s' ; 07/03/2015
  3615                              <1> ; ****************************************************************************
  3616                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - video.s
  3617                              <1> ; ----------------------------------------------------------------------------
  3618                              <1> ; Last Update: 30/01/2016
  3619                              <1> ; ----------------------------------------------------------------------------
  3620                              <1> ; Beginning: 16/01/2016
  3621                              <1> ; ----------------------------------------------------------------------------
  3622                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
  3623                              <1> ; ----------------------------------------------------------------------------
  3624                              <1> ; Turkish Rational DOS
  3625                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
  3626                              <1> ;
  3627                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
  3628                              <1> ; video.inc (13/08/2015)
  3629                              <1> ;
  3630                              <1> ; Derived from 'IBM PC-AT' BIOS source code (1985) 
  3631                              <1> ; ****************************************************************************
  3632                              <1> 
  3633                              <1> ; Retro UNIX 386 v1 Kernel - VIDEO.INC
  3634                              <1> ; Last Modification: 13/08/2015
  3635                              <1> ;		  (Video Data is in 'VIDATA.INC')
  3636                              <1> ;
  3637                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
  3638                              <1> 
  3639                              <1> ; 16/01/2016 (32 bit modifications, TRDOS386 - TRDOS v2.0, video.s)
  3640                              <1> ; INT 32H (TRDOS 386) = INT 10H (IBM PC/AT REAL MODE)
  3641                              <1> 
  3642                              <1> ; IBM PC-AT BIOS Source Code
  3643                              <1> ; TITLE VIDEO1 --- 06/10/85  VIDEO DISPLAY BIOS
  3644                              <1> 
  3645                              <1> int10h:
  3646                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  3647 000014BB 9C                  <1> 	pushfd
  3648 000014BC 0E                  <1> 	push 	cs
  3649 000014BD E851000000          <1> 	call 	VIDEO_IO_1
  3650 000014C2 C3                  <1> 	retn
  3651                              <1> 
  3652                              <1> ;--- INT 10 H -------------------------------------------------------------------
  3653                              <1> ; VIDEO_IO									:	
  3654                              <1> ;	THESE ROUTINES PROVIDE THE CRT DISPLAY INTERFACE			:
  3655                              <1> ;	THE FOLLOWING FUNCTIONS ARE PROVIDED:					:
  3656                              <1> ;										:
  3657                              <1> ;    (AH)= 00H	SET MODE (AL) CONTAINS MODE VALUE				:
  3658                              <1> ;		(AL) = 00H  40X25 BW MODE (POWER ON DEFAULT)			:
  3659                              <1> ;		(AL) = 01H  40X25 COLOR						:
  3660                              <1> ;		(AL) = 02H  80X25 BW						:
  3661                              <1> ;		(AL) = 03H  80X25 COLOR						:
  3662                              <1> ;		              GRAPHICS MODES					:
  3663                              <1> ;		(AL) = 04H  320X200 COLOR					:
  3664                              <1> ;		(AL) = 05H  320X200 BW MODE					:
  3665                              <1> ;		(AL) = 06H  640X200 BW MODE					:
  3666                              <1> ;		(AL) = 07H   80X25 MONOCHROME (USED INTERNAL TO VIDEO ONLY)	:
  3667                              <1> ;		*** NOTES -BW MODES OPERATE SAME AS COLOR MODES, BUT COLOR	:
  3668                              <1> ;		           BURST IS NOT ENABLED					:
  3669                              <1> ;		          -CURSOR IS NOT DISPLAYED IN GRAPHICS MODE		:
  3670                              <1> ;    (AH)= 01H	SET CURSOR TYPE							:
  3671                              <1> ;		(CH) = BITS 4-0 = START LINE FOR CURSOR				:
  3672                              <1> ;		       ** HARDWARE WILL ALWAYS CAUSE BLINK			:
  3673                              <1> ;		       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING	:
  3674                              <1> ;		          OR NO CURSOR AT ALL					:
  3675                              <1> ;		(CL) = BITS 4-0 = END LINE FOR CURSOR				:
  3676                              <1> ;    (AH)= 02H	SET CURSOR POSITION						:
  3677                              <1> ;		(DH,DL) = ROW,COLUMN  (00H,00H) IS UPPER LEFT			:
  3678                              <1> ;		(BH) = A PAGE NUMBER (MUST BE 00H FOR GRAPHICS MODES)		:
  3679                              <1> ;    (AH)= 03H	READ CURSOR POSITION						:
  3680                              <1> ;		(BH) = PAGE NUMBER (MUST BE 00H FOR GRAPHICS MODES)		:
  3681                              <1> ;		ON EXIT (DH,DL) = ROW,COLUMN OF CURRENT CURSOR			:
  3682                              <1> ;		        (CH,CL) = CURSOR MODE CURRENTLY SET			:
  3683                              <1> ;    (AH)= 04H	READ LIGHT PEN POSITION						:
  3684                              <1> ;		ON EXIT:							:
  3685                              <1> ;		(AH) = 00H -- LIGHT PEN SWITCH NOT DOWN/NOT TRIGGERED		:
  3686                              <1> ;		(AH) = 01H -- VALID LIGHT PEN VALUE IN REGISTERS		:
  3687                              <1> ;		        (DH,DL) = ROW,COLUMN OF CHARACTER LP POSITION		:
  3688                              <1> ;		        (CH) = RASTER LINE (0-199)				:
  3689                              <1> ;		        (BX) = PIXEL COLUMN (0-319,639)				:
  3690                              <1> ;    (AH)= 05H	SELECT ACTIVE DISPLAY PAGE (VALID ONLY FOR ALPHA MODES)		:
  3691                              <1> ;		(AL) = NEW PAGE VALUE (0-7 FOR MODES 0&1, 0-3 FOR MODES 2&3)	:
  3692                              <1> ;    (AH)= 06H	SCROLL ACTIVE PAGE UP						:
  3693                              <1> ;		(AL) = NUMBER OF LINES. ( LINES BLANKED AT BOTTOM OF WINDOW )	:
  3694                              <1> ;		        (AL) = 00H MEANS BLANK ENTIRE WINDOW			:
  3695                              <1> ;		(CH,CL) = ROW,COLUMN OF UPPER LEFT CORNER OF SCROLL		:
  3696                              <1> ;		(DH,DL) = ROW,COLUMN OF LOWER RIGHT CORNER OF SCROLL		:
  3697                              <1> ;		(BH) = ATTRIBUTE TO BE USED ON BLANK LINE			:
  3698                              <1> ;    (AH)= 07H	SCROLL ACTIVE PAGE DOWN						:
  3699                              <1> ;		(AL) = NUMBER OF LINES, INPUT LINES BLANKED AT TOP OF WINDOW	:
  3700                              <1> ;		        (AL) = 00H MEANS BLANK ENTIRE WINDOW			:
  3701                              <1> ;		(CH,CL) = ROW,COLUMN OF UPPER LEFT CORNER OF SCROLL		:
  3702                              <1> ;		(DH,DL) = ROW,COLUMN OF LOWER RIGHT CORNER OF SCROLL		:
  3703                              <1> ;		(BH) = ATTRIBUTE TO BE USED ON BLANK LINE			:
  3704                              <1> ;										:
  3705                              <1> ;   CHARACTER HANDLING ROUTINES							:
  3706                              <1> ;										:
  3707                              <1> ;    (AH)= 08H	READ ATTRIBUTE/CHARACTER AT CURRENT CURSOR POSITION		:
  3708                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
  3709                              <1> ;		ON EXIT:							:
  3710                              <1> ;		(AL) = CHAR READ						:
  3711                              <1> ;		(AH) = ATTRIBUTE OF CHARACTER READ (ALPHA MODES ONLY)		:
  3712                              <1> ;    (AH)= 09H	WRITE ATTRIBUTE/CHARACTER AT CURRENT CURSOR POSITION		:
  3713                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
  3714                              <1> ;		(CX) = COUNT OF CHARACTERS TO WRITE				:
  3715                              <1> ;		(AL) = CHAR TO WRITE						:
  3716                              <1> ;		(BL) = ATTRIBUTE OF CHARACTER (ALPHA)/COLOR OF CHAR (GRAPHICS)	:
  3717                              <1> ;		         SEE NOTE ON WRITE DOT FOR BIT 7 OF BL = 1.		:
  3718                              <1> ;    (AH) = 0AH	WRITE CHARACTER ONLY AT CURRENT CURSOR POSITION			:
  3719                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
  3720                              <1> ;		(CX) = COUNT OF CHARACTERS TO WRITE				:
  3721                              <1> ;		(AL) = CHAR TO WRITE						:
  3722                              <1> ;		       NOTE: USE FUNCTION (AH)= 09H IN GRAPHICS MODES		:
  3723                              <1> ;	FOR READ/WRITE CHARACTER INTERFACE WHILE IN GRAPHICS MODE, THE		:
  3724                              <1> ;		CHARACTERS ARE FORMED FROM A CHARACTER GENERATOR IMAGE		:
  3725                              <1> ;		MAINTAINED IN THE SYSTEM ROM. ONLY THE 1ST 128 CHARS		:
  3726                              <1> ;		ARE CONTAINED THERE. TO READ/WRITE THE SECOND 128 CHARS,	:
  3727                              <1> ;		THE USER MUST INITIALIZE THE POINTER AT INTERRUPT 1FH		:
  3728                              <1> ;		(LOCATION 0007CH) TO POINT TO THE 1K BYTE TABLE CONTAINING	:
  3729                              <1> ;		THE CODE POINTS FOR THE SECOND 128 CHARS (128-255).		:
  3730                              <1> ;	FOR WRITE CHARACTER INTERFACE IN GRAPHICS MODE, THE REPLICATION FACTOR	:
  3731                              <1> ;		CONTAINED IN (CX) ON ENTRY WILL PRODUCE VALID RESULTS ONLY	:
  3732                              <1> ;		FOR CHARACTERS CONTAINED ON THE SAME ROW. CONTINUATION TO	:
  3733                              <1> ;		SUCCEEDING LINES WILL NOT PRODUCE CORRECTLY.			:
  3734                              <1> ;										:
  3735                              <1> ;    GRAPHICS INTERFACE								:
  3736                              <1> ;    (AH)= 0BH	SET COLOR PALETTE						:
  3737                              <1> ;		(BH) = PALETTE COLOR ID BEING SET (0-127)			:
  3738                              <1> ;		(BL) = COLOR VALUE TO BE USED WITH THAT COLOR ID		:
  3739                              <1> ;		       NOTE: FOR THE CURRENT COLOR CARD, THIS ENTRY POINT HAS	:
  3740                              <1> ;		               MEANING ONLY FOR 320X200 GRAPHICS.		:
  3741                              <1> ;		       COLOR ID = 0 SELECTS THE BACKGROUND COLOR (0-15)		:
  3742                              <1> ;		       COLOR ID = 1 SELECTS THE PALETTE TO BE USED:		:
  3743                              <1> ;		               0 = GREEN(1)/RED(2)/YELLOW(3)			:
  3744                              <1> ;		               1 = CYAN(1)/MAGENTA(2)/WHITE(3)			:
  3745                              <1> ;		       IN 40X25 OR 80X25 ALPHA MODES, THE VALUE SET FOR 	:
  3746                              <1> ;		               PALETTE COLOR 0 INDICATES THE BORDER COLOR	:
  3747                              <1> ;		               TO BE USED (VALUES 0-31, WHERE 16-31 SELECT	:
  3748                              <1> ;		               THE HIGH INTENSITY BACKGROUND SET.		:
  3749                              <1> ;    (AH)= 0CH	WRITE DOT							:
  3750                              <1> ;		(DX) = ROW NUMBER						:
  3751                              <1> ;		(CX) = COLUMN NUMBER						:
  3752                              <1> ;		(AL) = COLOR VALUE						:
  3753                              <1> ;		        IF BIT 7 OF AL = 1, THEN THE COLOR VALUE IS EXCLUSIVE	:
  3754                              <1> ;		        ORed WITH THE CURRENT CONTENTS OF THE DOT		:
  3755                              <1> ;    (AH)= ODH	READ DOT							:
  3756                              <1> ;		(DX) = ROW NUMBER						:
  3757                              <1> ;		(CX) = COLUMN NUMBER						:
  3758                              <1> ;		(AL) = RETURNS THE DOT READ					:
  3759                              <1> ;										:
  3760                              <1> ;    ASCII TELETYPE ROUTINE FOR OUTPUT						:
  3761                              <1> ;										:
  3762                              <1> ;    (AH)= 0EH	WRITE TELETYPE TO ACTIVE PAGE					:
  3763                              <1> ;		(AL) = CHAR TO WRITE						:
  3764                              <1> ;		(BL) = FOREGROUND COLOR IN GRAPHICS MODE			:
  3765                              <1> ;		NOTE -- SCREEN WIDTH IS CONTROLLED BY PREVIOUS MODE SET		:
  3766                              <1> ;    (AH)= 0FH	CURRENT VIDEO STATE						:
  3767                              <1> ;		RETURNS THE CURRENT VIDEO STATE					:
  3768                              <1> ;		(AL) = MODE CURRENTLY SET ( SEE (AH)=00H FOR EXPLANATION)	:
  3769                              <1> ;		(AH) = NUMBER OR CHARACTER COLUMNS ON SCREEN			:
  3770                              <1> ;		(BH) = CURRENT ACTIVE DISPLAY PAGE				:
  3771                              <1> ;    (AH)= 10H	RESERVED							:
  3772                              <1> ;    (AH)= 11H	RESERVED							:
  3773                              <1> ;    (AH)= 12H	RESERVED							:
  3774                              <1> ;    (AH)= 13H	WRITE STRING							:
  3775                              <1> ;			ES:BP  -  POINTER T0 STRING TO BE WRITTEN		:
  3776                              <1> ;			CX     -  LENGTH OF CHARACTER STRING TO WRITTEN		:
  3777                              <1> ;			DX     -  CURSOR POSITION FOR STRING TO BE WRITTEN	:
  3778                              <1> ;			BH     -  PAGE NUMBER					:
  3779                              <1> ;		(AL)= 00H	WRITE CHARACTER STRING				:
  3780                              <1> ;			BL     -  ATTRIBUTE					:
  3781                              <1> ;			STRING IS  <CHAR,CHAR, ... ,CHAR>			:
  3782                              <1> ;			CURSOR NOT MOVED					:
  3783                              <1> ;		(AL)= 01H	WRITE CHARACTER STRING AND MOVE CURSOR		:
  3784                              <1> ;			BL     -  ATTRIBUTE					:
  3785                              <1> ;			STRING IS  <CHAR,CHAR, ... ,CHAR>			:
  3786                              <1> ;			CURSOR MOVED						:
  3787                              <1> ;		(AL)= 02H	WRITE CHARACTER AND ATTRIBUTE STRING		:
  3788                              <1> ;			       (VALID FOR ALPHA MODES ONLY)			:
  3789                              <1> ;			STRING IS <CHAR,ATTR,CHAR,ATTR ..  ,CHAR,ATTR>		:
  3790                              <1> ;			CURSOR IS NOT MOVED					:
  3791                              <1> ;		(AL)= 03H WRITE CHARACTER AND ATTRIBUTE STRING AND MOVE CURSOR	:
  3792                              <1> ;			       (VALID FOR ALPHA MODES ONLY)			:
  3793                              <1> ;			STRING IS <CHAR,ATTR,CHAR,ATTR ..  ,CHAR,ATTR>		:
  3794                              <1> ;			CURSOR IS MOVED						:
  3795                              <1> ;		 NOTE:  CARRIAGE RETURN, LINE FEED, BACKSPACE, AND BELL ARE	:
  3796                              <1> ;		        TREATED AS COMMANDS RATHER THAN PRINTABLE CHARACTERS.	:
  3797                              <1> ;										:
  3798                              <1> ;	BX,CX,DX,SI,DI,BP,SP,DS,ES,SS PRESERVED DURING CALLS EXCEPT FOR		:
  3799                              <1> ;	BX,CX,DX RETURN VALUES ON FUNCTIONS 03H,04H,0DH AND 0FH. ON ALL CALLS	:
  3800                              <1> ;	AX IS MODIFIED.								:
  3801                              <1> ;--------------------------------------------------------------------------------
  3802                              <1> 
  3803 000014C3 [5E150000]          <1> M1:	dd	SET_MODE	; TABLE OF ROUTINES WITHIN VIDEO I/O
  3804 000014C7 [BE150000]          <1> 	dd	SET_CTYPE
  3805 000014CB [D3150000]          <1> 	dd	SET_CPOS
  3806 000014CF [DA150000]          <1> 	dd	READ_CURSOR
  3807 000014D3 [63150000]          <1> 	dd	VIDEO_RETURN	; READ_LPEN
  3808 000014D7 [FC150000]          <1> 	dd	ACT_DISP_PAGE
  3809 000014DB [75160000]          <1> 	dd	SCROLL_UP
  3810 000014DF [59170000]          <1> 	dd	SCROLL_DOWN
  3811 000014E3 [A4170000]          <1> 	dd	READ_AC_CURRENT
  3812 000014E7 [D2170000]          <1> 	dd	WRITE_AC_CURRENT
  3813 000014EB [E5170000]          <1> 	dd	WRITE_C_CURRENT
  3814 000014EF [63150000]          <1> 	dd	VIDEO_RETURN	; SET_COLOR
  3815 000014F3 [63150000]          <1> 	dd	VIDEO_RETURN	; WRITE_DOT
  3816 000014F7 [63150000]          <1> 	dd	VIDEO_RETURN	; READ_DOT
  3817 000014FB [29180000]          <1> 	dd	WRITE_TTY
  3818 000014FF [4B150000]          <1> 	dd	VIDEO_STATE
  3819 00001503 [63150000]          <1> 	dd	VIDEO_RETURN	; RESERVED
  3820 00001507 [63150000]          <1> 	dd	VIDEO_RETURN	; RESERVED
  3821 0000150B [63150000]          <1> 	dd	VIDEO_RETURN	; RESERVED
  3822 0000150F [63150000]          <1> 	dd	VIDEO_RETURN	; WRITE_STRING
  3823                              <1> M1L	EQU	$ - M1
  3824                              <1> 
  3825                              <1> VIDEO_IO_1:
  3826 00001513 FB                  <1> 	sti				; INTERRUPTS BACK ON
  3827 00001514 FC                  <1> 	cld				; SET DIRECTION FORWARD
  3828 00001515 80FC14              <1> 	cmp	ah, M1L/4		; TEST FOR WITHIN TABLE RANGE
  3829 00001518 7320                <1> 	jnb	short M4		; BRANCH TO EXIT IF NOT A VALID COMMAND
  3830                              <1> 
  3831 0000151A 06                  <1> 	push	es
  3832 0000151B 1E                  <1> 	push	ds			; SAVE WORK AND PARAMETER REGISTERS
  3833 0000151C 52                  <1> 	push	edx
  3834 0000151D 51                  <1> 	push	ecx
  3835 0000151E 53                  <1> 	push	ebx
  3836 0000151F 56                  <1> 	push	esi
  3837 00001520 57                  <1> 	push	edi
  3838 00001521 55                  <1> 	push	ebp
  3839 00001522 66BE1000            <1> 	mov	si, KDATA 		; POINT DS: TO DATA SEGMENT
  3840 00001526 8EDE                <1> 	mov	ds, si
  3841 00001528 8EC6                <1> 	mov	es, si
  3842 0000152A BF00800B00          <1> 	mov	edi, 0B8000h		; GET offset FOR COLOR CARD
  3843 0000152F D0E4                <1> 	shl	ah, 1			; TIMES 2 FOR WORD TABLE LOOKUP
  3844 00001531 0FB6F4              <1> 	movzx	esi, ah			; MOVE OFFSET INTO LOOK UP REGISTER (SI)
  3845                              <1> 	;mov	ah, [CRT_MODE]		; MOVE CURRENT MODE INTO (AH) REGISTER
  3846                              <1> 
  3847 00001534 FFA6[C3140000]      <1> 	JMP	dword [esi+M1]		; GO TO SELECTED FUNCTION
  3848                              <1> 
  3849                              <1> M4:					;	COMMAND NOT VALID
  3850 0000153A CF                  <1> 	iret				; DO NOTHING IF NOT IN VALID RANGE
  3851                              <1> 
  3852                              <1> 
  3853                              <1> ; 02/09/2014 (Retro UNIX 386 v1)
  3854                              <1> ;
  3855                              <1> ; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  3856                              <1> 
  3857                              <1> set_mode_3:  	; will be called from 'write_tty' 
  3858 0000153B 53                  <1> 	push	ebx
  3859 0000153C 52                  <1> 	push	edx
  3860 0000153D 50                  <1> 	push	eax
  3861 0000153E 57                  <1> 	push	edi
  3862 0000153F 51                  <1> 	push	ecx
  3863 00001540 E827000000          <1> 	call	set_txt_mode
  3864 00001545 59                  <1> 	pop	ecx
  3865 00001546 5F                  <1> 	pop	edi
  3866 00001547 58                  <1> 	pop	eax
  3867 00001548 5A                  <1> 	pop	edx
  3868 00001549 5B                  <1> 	pop	ebx
  3869 0000154A C3                  <1> 	retn
  3870                              <1> 
  3871                              <1> VIDEO_STATE:
  3872                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  3873                              <1> 
  3874                              <1> ;---------------------------------------------------
  3875                              <1> ; VIDEO STATE
  3876                              <1> ;  RETURNS THE CURRENT VIDEO STATE IN AX
  3877                              <1> ;  AH = NUMBER OF COLUMNS ON THE SCREEN
  3878                              <1> ;  AL = CURRENT VIDEO MODE
  3879                              <1> ;  BH = CURRENT ACTIVE PAGE
  3880                              <1> ;---------------------------------------------------
  3881                              <1> 
  3882                              <1> 	;mov	ah, [CRT_COLS]	; GET NUMBER OF COLUMNS
  3883 0000154B B480                <1> 	mov	ah, 80h
  3884 0000154D A0[D6720000]        <1> 	mov	al, [CRT_MODE]	; CURRENT MODE
  3885                              <1> 	;movzx	esi, al
  3886                              <1> 	;mov	ah, [esi+M6] 
  3887                              <1> 	; BL = active page (not BH!)
  3888 00001552 8A1D[F8780000]      <1> 	mov	bl, [ACTIVE_PAGE] ; GET CURRENT ACTIVE PAGE
  3889 00001558 5D                  <1> 	pop	ebp		; RECOVER REGISTERS
  3890 00001559 5F                  <1> 	pop	edi
  3891 0000155A 5E                  <1> 	pop	esi
  3892 0000155B 59                  <1> 	pop	ecx	; DISCARD SAVED BX
  3893 0000155C EB09                <1> 	jmp	short M15	; RETURN TO CALLER
  3894                              <1> 
  3895                              <1> SET_MODE:
  3896                              <1> 	; For 32 bit TRDOS and Retro UNIX 386:
  3897                              <1> 	;	valid video mode: 03h only!
  3898                              <1> 	;	(VGA modes will be selected with another routine)
  3899                              <1> 	;
  3900                              <1> 	; set_txt_mode ; 80*25 (16 fore colors, 8 back colors)
  3901                              <1> 
  3902                              <1> ;------------------------------------------------------
  3903                              <1> ; SET MODE					      :
  3904                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
  3905                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
  3906                              <1> ; INPUT						      :
  3907                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
  3908                              <1> ; OUTPUT					      :
  3909                              <1> ;	NONE					      :
  3910                              <1> ;------------------------------------------------------
  3911                              <1> 
  3912 0000155E E809000000          <1> 	call	set_txt_mode
  3913                              <1> 
  3914                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  3915                              <1> 
  3916                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  3917                              <1> 
  3918                              <1> VIDEO_RETURN:
  3919 00001563 5D                  <1> 	pop	ebp
  3920 00001564 5F                  <1> 	pop	edi
  3921 00001565 5E                  <1> 	pop	esi
  3922 00001566 5B                  <1> 	pop	ebx
  3923                              <1> M15:			;VIDEO_RETURN_C
  3924 00001567 59                  <1> 	pop	ecx
  3925 00001568 5A                  <1> 	pop	edx
  3926 00001569 1F                  <1> 	pop	ds
  3927 0000156A 07                  <1> 	pop	es	; RECOVER SEGMENTS
  3928 0000156B CF                  <1> 	iret		; ALL DONE
  3929                              <1> 
  3930                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  3931                              <1> set_txt_mode:
  3932                              <1> 	;mov	dx, 03D4h 	; address of color card
  3933 0000156C B003                <1> 	mov	al, 3
  3934                              <1> ;M8:
  3935 0000156E A2[D6720000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
  3936 00001573 B029                <1> 	mov	al, 29h
  3937                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
  3938 00001575 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
  3939                              <1> 	;push	dx  		; save port value
  3940                              <1> 	;add	dx, 4		; point to control register
  3941 00001577 66BAD803            <1> 	mov	dx, 3D8h
  3942 0000157B EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
  3943                              <1> 	;pop	dx
  3944                              <1> ;M9:
  3945 0000157C BB[D8720000]        <1> 	mov	ebx, video_params ; initialization table
  3946 00001581 668B430A            <1> 	mov	ax, [ebx+10]      ; get the cursor mode from the table	
  3947 00001585 86E0                <1> 	xchg 	ah, al
  3948 00001587 66A3[E6780000]      <1> 	mov	[CURSOR_MODE], ax ; save cursor mode
  3949 0000158D 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
  3950                              <1> 	
  3951                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
  3952 0000158F B910000000          <1> 	mov	ecx, 16 ; 16/01/2016
  3953                              <1> M10:			;  initialization loop
  3954 00001594 88E0                <1> 	mov	al, ah 	; get 6845 register number
  3955 00001596 EE                  <1> 	out	dx, al
  3956 00001597 6642                <1> 	inc	dx      ; point to data port
  3957 00001599 FEC4                <1> 	inc	ah	; next register value
  3958 0000159B 8A03                <1> 	mov	al, [ebx] ; get table value
  3959 0000159D EE                  <1> 	out	dx, al	; out to chip
  3960 0000159E 43                  <1> 	inc	ebx	; next in table
  3961 0000159F 664A                <1> 	dec	dx	; back to pointer register
  3962 000015A1 E2F1                <1> 	loop	M10	; do the whole table
  3963                              <1> 
  3964                              <1> ;-----	FILL REGEN AREA WITH BLANK
  3965                              <1> 	;xor	ax, ax  
  3966                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
  3967                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
  3968                              <1> 	;mov	ecx, 8192 ; number of words in color card
  3969                              <1> 	; black background, light gray characeter color, space character
  3970                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
  3971                              <1> ;M13:			  ; clear buffer
  3972                              <1> 	;add	edi, 0B8000h ; [crt_base]
  3973                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
  3974                              <1> 
  3975                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
  3976                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
  3977                              <1> 			 ; prepare to output to video enable port
  3978                              <1> 	;add	dx,4	 ; point to the mode control gerister
  3979 000015A3 66BAD803            <1> 	mov	dx, 3D8h
  3980                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
  3981 000015A7 B029                <1> 	mov	al, 29h
  3982 000015A9 EE                  <1> 	out	dx, al	 ; set video enable port
  3983                              <1> 
  3984                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
  3985                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
  3986                              <1> 	;
  3987                              <1> 	;mov	byte [CRT_COLS], 80h ; initialize number of columns count
  3988                              <1> 	;
  3989                              <1> ;-----	SET CURSOR POSITIONS
  3990                              <1> 	;mov	word [CRT_LEN], 80*25*2
  3991 000015AA BF[E8780000]        <1> 	mov	edi, CURSOR_POSN
  3992 000015AF B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
  3993 000015B4 31C0                <1> 	xor	eax, eax
  3994 000015B6 F3AB                <1> 	rep 	stosd	; fill with zeroes
  3995                              <1> 
  3996                              <1> ;-----	SET UP OVERSCAN REGISTER
  3997 000015B8 6642                <1> 	inc	dx	; set overscan port to a default
  3998 000015BA B030                <1> 	mov	al, 30h	; 30H value for all modes except 640X200 bw
  3999                              <1> ;M14:
  4000 000015BC EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
  4001                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
  4002                              <1> 
  4003                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  4004 000015BD C3                  <1> 	retn
  4005                              <1> 
  4006                              <1> SET_CTYPE:
  4007                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4008 000015BE E802000000          <1> 	call	_set_ctype
  4009 000015C3 EB9E                <1> 	jmp	short VIDEO_RETURN
  4010                              <1> 
  4011                              <1> _set_ctype:
  4012                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4013                              <1> 	;
  4014                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4015                              <1> 
  4016                              <1> 	; (CH) = BITS 4-0 = START LINE FOR CURSOR
  4017                              <1> 	;  ** HARDWARE WILL ALWAYS CAUSE BLINK
  4018                              <1> 	;  ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
  4019                              <1> 	;     OR NO CURSOR AT ALL
  4020                              <1> 	; (CL) = BITS 4-0 = END LINE FOR CURSOR
  4021                              <1> 
  4022                              <1> ;------------------------------------------------
  4023                              <1> ; SET_CTYPE
  4024                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
  4025                              <1> ; INPUT
  4026                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
  4027                              <1> ; OUTPUT	
  4028                              <1> ;	NONE
  4029                              <1> ;------------------------------------------------
  4030                              <1> 
  4031 000015C5 B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  4032 000015C7 66890D[E6780000]    <1> 	mov	[CURSOR_MODE], cx ; save in data area
  4033                              <1> 	;call	m16	; output cx register
  4034                              <1> 	;retn
  4035 000015CE E915030000          <1>         jmp     m16
  4036                              <1> 
  4037                              <1> SET_CPOS:
  4038                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4039 000015D3 E8E5020000          <1> 	call	_set_cpos
  4040 000015D8 EB89                <1> 	jmp	short VIDEO_RETURN
  4041                              <1> 
  4042                              <1> READ_CURSOR:
  4043                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4044                              <1> 	;
  4045                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4046                              <1> 
  4047                              <1> ;------------------------------------------------------
  4048                              <1> ; READ_CURSOR
  4049                              <1> ;	THIS ROUTINE READS THE CURRENT CURSOR VALUE FROM THE
  4050                              <1> ;	845, FORMATS IT, AND SENDS IT BACK TO THE CALLER
  4051                              <1> ; INPUT
  4052                              <1> ;	BH - PAGE OF CURSOR
  4053                              <1> ; OUTPUT
  4054                              <1> ;	DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
  4055                              <1> ;	CX - CURRENT CURSOR MODE
  4056                              <1> ;------------------------------------------------------
  4057                              <1> 
  4058                              <1> 	; BL = Video page number (0 to 7)
  4059                              <1> 	
  4060                              <1> 
  4061 000015DA E810000000          <1> 	call	get_cpos
  4062 000015DF 0FB70D[E6780000]    <1> 	movzx	ecx, word [CURSOR_MODE]
  4063                              <1> 
  4064 000015E6 5D                  <1> 	pop	ebp
  4065 000015E7 5F                  <1> 	pop	edi
  4066 000015E8 5E                  <1> 	pop	esi
  4067 000015E9 5B                  <1> 	pop	ebx
  4068 000015EA 58                  <1> 	pop	eax	; DISCARD SAVED CX AND DX
  4069 000015EB 58                  <1> 	pop	eax
  4070 000015EC 1F                  <1> 	pop	ds
  4071 000015ED 07                  <1> 	pop	es
  4072 000015EE CF                  <1> 	iret
  4073                              <1> 
  4074                              <1> get_cpos:
  4075                              <1> 	; 16/01/2016
  4076                              <1> 	; BL = Video page number (0 to 7)
  4077                              <1> 	;
  4078 000015EF D0E3                <1> 	shl	bl, 1 ; WORD OFFSET
  4079 000015F1 0FB6F3              <1> 	movzx	esi, bl 
  4080 000015F4 0FB796[E8780000]    <1> 	movzx	edx, word [esi+CURSOR_POSN]
  4081 000015FB C3                  <1> 	retn
  4082                              <1> 
  4083                              <1> ACT_DISP_PAGE:
  4084                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4085                              <1> 	;
  4086                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4087                              <1> 	;
  4088                              <1> ;-----------------------------------------------------
  4089                              <1> ; ACT_DISP_PAGE
  4090                              <1> ;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
  4091                              <1> ;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
  4092                              <1> ; INPUT
  4093                              <1> ;	AL HAS THE NEW ACTIVE DISPLAY PAGE
  4094                              <1> ; OUTPUT
  4095                              <1> ;	THE 6845 IS RESET TO DISPLAY THAT PAGE
  4096                              <1> ;-----------------------------------------------------
  4097                              <1> 
  4098 000015FC E805000000          <1> 	call	set_active_page
  4099 00001601 E95DFFFFFF          <1>         jmp     VIDEO_RETURN
  4100                              <1> 
  4101                              <1> set_active_page:   ; tty_sw
  4102                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4103                              <1> 	; 30/06/2015
  4104                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
  4105                              <1> 	; 10/12/2013
  4106                              <1> 	; 04/12/2013
  4107                              <1> 	;
  4108 00001606 A2[F8780000]        <1> 	mov	[ACTIVE_PAGE], al ; save active page value ; [ptty]
  4109                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
  4110 0000160B 66B9A00F            <1> 	mov	cx, 25*80*2
  4111                              <1> 	; 27/06/2015
  4112 0000160F 0FB6D8              <1> 	movzx	ebx, al
  4113                              <1> 	;
  4114 00001612 6698                <1> 	cbw	; 07/09/2014 (ah=0)
  4115 00001614 66F7E1              <1> 	mul 	cx	; display page times regen length
  4116                              <1> 	; 10/12/2013
  4117 00001617 66A3[E4780000]      <1> 	mov	[CRT_START], ax ; save start address for later
  4118 0000161D 6689C1              <1> 	mov	cx, ax ; start address to cx
  4119                              <1> 	;sar	cx, 1
  4120 00001620 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
  4121 00001623 B40C                <1> 	mov	ah, 12	; 6845 register for start address
  4122 00001625 E8BE020000          <1> 	call	m16
  4123                              <1> 	;sal	bx, 1
  4124                              <1> 	; 01/09/2014
  4125 0000162A D0E3                <1> 	shl	bl, 1	; *2 for word offset
  4126 0000162C 81C3[E8780000]      <1> 	add	ebx, CURSOR_POSN
  4127 00001632 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
  4128                              <1> 	; 16/01/2016
  4129                              <1> 	;call	m18
  4130                              <1> 	;retn
  4131 00001635 E99A020000          <1> 	jmp	m18
  4132                              <1> 
  4133                              <1> position:
  4134                              <1> 	; 27/06/2015
  4135                              <1> 	; 02/09/2014
  4136                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4137                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
  4138                              <1> 	;
  4139                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4140                              <1> 	;
  4141                              <1> ;-----------------------------------------
  4142                              <1> ; POSITION
  4143                              <1> ;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
  4144                              <1> ;	OF A CHARACTER IN THE ALPHA MODE
  4145                              <1> ; INPUT
  4146                              <1> ;	AX = ROW, COLUMN POSITION
  4147                              <1> ; OUTPUT
  4148                              <1> ;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
  4149                              <1> ;-----------------------------------------
  4150                              <1> 
  4151                              <1> 		; DX = ROW, COLUMN POSITION
  4152                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
  4153 0000163A 31C0                <1> 	xor	eax, eax ; 02/09/2014
  4154 0000163C B050                <1> 	mov	al, 80   ; determine bytes to row	
  4155 0000163E F6E6                <1> 	mul	dh	 ; row value
  4156 00001640 30F6                <1> 	xor	dh, dh   ; 0	
  4157 00001642 6601D0              <1> 	add	ax, dx	 ; add column value to the result
  4158 00001645 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
  4159                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
  4160 00001648 C3                  <1> 	retn
  4161                              <1> 
  4162                              <1> find_position:
  4163                              <1> 	; 27/06/2015
  4164                              <1> 	; 07/09/2014
  4165                              <1> 	; 02/09/2014
  4166                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4167                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4168 00001649 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
  4169 0000164C 89CE                <1> 	mov	esi, ecx
  4170 0000164E 66D1E6              <1> 	shl	si, 1
  4171 00001651 668B96[E8780000]    <1> 	mov	dx, [esi + CURSOR_POSN]
  4172 00001658 740A                <1> 	jz	short p21
  4173 0000165A 6631F6              <1> 	xor	si, si
  4174                              <1> p20:
  4175                              <1> 	;add	si, [CRT_LEN]
  4176 0000165D 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
  4177 00001662 E2F9                <1> 	loop	p20
  4178                              <1> p21:
  4179 00001664 6621D2              <1> 	and	dx, dx
  4180 00001667 7407                <1> 	jz	short p22
  4181 00001669 E8CCFFFFFF          <1> 	call 	position ; determine location in regen in page
  4182 0000166E 01C6                <1> 	add	esi, eax ; add location to start of regen page
  4183                              <1> p22:	
  4184                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
  4185                              <1> 	;mov	dx, 03D4h ; I/O address of color card
  4186                              <1> 	;add	dx, 6	; point at status port
  4187 00001670 66BADA03            <1> 	mov	dx, 03DAh ; status port
  4188                              <1> 	; cx = 0
  4189 00001674 C3                  <1> 	retn
  4190                              <1> 
  4191                              <1> SCROLL_UP:
  4192                              <1> 	; 30/01/2016
  4193                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4194                              <1> 	; 07/09/2014
  4195                              <1> 	; 02/09/2014
  4196                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
  4197                              <1> 	; 04/04/2014
  4198                              <1> 	; 04/12/2013
  4199                              <1> 	;
  4200                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4201                              <1> 	;
  4202                              <1> ;----------------------------------------------
  4203                              <1> ; SCROLL UP
  4204                              <1> ;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
  4205                              <1> ;	ON THE SCREEN
  4206                              <1> ; INPUT
  4207                              <1> ;	(AH) = CURRENT CRT MODE
  4208                              <1> ;	(AL) = NUMBER OF ROWS TO SCROLL
  4209                              <1> ;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
  4210                              <1> ;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
  4211                              <1> ;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
  4212                              <1> ;	(DS) = DATA SEGMENT
  4213                              <1> ;	(ES) = REGEN BUFFER SEGMENT
  4214                              <1> ; OUTPUT
  4215                              <1> ;	NONE -- THE REGEN BUFFER IS MODIFIED
  4216                              <1> ;--------------------------------------------
  4217                              <1> 
  4218 00001675 E805000000          <1> 	call	_scroll_up
  4219 0000167A E9E4FEFFFF          <1>         jmp     VIDEO_RETURN
  4220                              <1> 
  4221                              <1> _scroll_up:  ; from 'write_tty'
  4222                              <1> 	;
  4223                              <1> 	; ((ah = 3))
  4224                              <1> 	; cl = left upper column
  4225                              <1> 	; ch = left upper row
  4226                              <1> 	; dl = right lower column
  4227                              <1> 	; dh = right lower row
  4228                              <1> 	;
  4229                              <1> 	; al = line count 
  4230                              <1> 	; ah = attribute to be used on blanked line	
  4231                              <1> 	; bl = video page number (0 to 7)
  4232                              <1> 	; 
  4233                              <1> 
  4234 0000167F E86C000000          <1> 	call	test_line_count ; 16/01/2016
  4235                              <1> 
  4236                              <1> 	;mov	bh, [CRT_MODE] ; current video mode	
  4237                              <1> 	;cmp	bh, 4
  4238                              <1>  	;jb	short n1
  4239                              <1> 
  4240                              <1> 	;cmp	bh, 7 ; TEST FOR BW CARD
  4241                              <1> 	;jne	GRAPHICS_UP
  4242                              <1> n1:
  4243 00001684 30FF                <1> 	xor	bh, bh	; 0
  4244 00001686 6650                <1> 	push	ax ; *
  4245                              <1> 	;mov 	esi, [CRT_BASE]
  4246 00001688 BE00800B00          <1>         mov     esi, 0B8000h  
  4247 0000168D 3A1D[F8780000]      <1>         cmp     bl, [ACTIVE_PAGE]
  4248 00001693 750B                <1> 	jne	short n2
  4249                              <1> 	;
  4250 00001695 66A1[E4780000]      <1>         mov     ax, [CRT_START]
  4251 0000169B 6601C6              <1>         add     si, ax
  4252 0000169E EB0F                <1>         jmp     short n4
  4253                              <1> n2:
  4254 000016A0 20DB                <1>         and     bl, bl
  4255 000016A2 740B                <1> 	jz	short n4
  4256 000016A4 88D8                <1> 	mov	al, bl
  4257                              <1> n3:
  4258                              <1>         ;add    si, [CRT_LEN]
  4259                              <1>         ;add    esi, 80*25*2 
  4260 000016A6 6681C6A00F          <1>         add     si, 80*25*2
  4261 000016AB FEC8                <1>         dec	al
  4262 000016AD 75F7                <1> 	jnz	short n3
  4263                              <1> n4:	
  4264 000016AF E84D000000          <1> 	call	scroll_position ; 16/01/2016
  4265 000016B4 7419                <1>         jz      short n6 
  4266                              <1> 
  4267 000016B6 01CE                <1>         add     esi, ecx ; from address for scroll
  4268 000016B8 88F7                <1> 	mov	bh, dh  ; #rows in block
  4269 000016BA 28C7                <1> 	sub	bh, al	; #rows to be moved
  4270                              <1> n5:
  4271 000016BC E880000000          <1> 	call	n10 ; 16/01/2016
  4272                              <1> 	
  4273                              <1>         ;mov    cl, [CRT_COLS] 
  4274                              <1> 	;add	cl, cl
  4275                              <1>         ;mov    ecx, 80*2
  4276 000016C1 66B9A000            <1>         mov     cx, 80*2
  4277 000016C5 01CE                <1>         add     esi, ecx  ; next line
  4278 000016C7 01CF                <1>         add     edi, ecx
  4279 000016C9 FECF                <1> 	dec	bh	 ; count of lines to move
  4280 000016CB 75EF                <1> 	jnz	short n5 ; row loop
  4281                              <1> 	; bh = 0
  4282 000016CD 88C6                <1> 	mov	dh, al	 ; #rows	
  4283                              <1> n6:
  4284                              <1> 	; attribute in ah
  4285 000016CF B020                <1> 	mov	al, ' '	 ; fill with blanks
  4286                              <1> n7:
  4287 000016D1 E878000000          <1> 	call	n11 ; 16/01/2016
  4288                              <1> 
  4289                              <1> 	;mov	cl, [CRT_COLS]
  4290                              <1> 	;add	cl, cl
  4291                              <1>         ;mov    ecx, 80*2
  4292 000016D6 66B9A000            <1>         mov	cx, 80*2
  4293 000016DA 01CF                <1>         add     edi, ecx
  4294 000016DC FECE                <1> 	dec	dh
  4295 000016DE 75F1                <1> 	jnz	short n7
  4296                              <1> 	;
  4297 000016E0 3A1D[F8780000]      <1> 	cmp	bl, [ACTIVE_PAGE]
  4298 000016E6 7507                <1> 	jne	short n8
  4299                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
  4300 000016E8 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
  4301 000016EA 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
  4302 000016EE EE                  <1> 	out	dx, al
  4303                              <1> n8:
  4304 000016EF C3                  <1> 	retn
  4305                              <1> 
  4306                              <1> 
  4307                              <1> test_line_count:
  4308                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4309                              <1> 	; 07/09/2014 (scroll_up)
  4310 000016F0 08C0                <1> 	or	al, al
  4311 000016F2 740C                <1> 	jz	short al_set
  4312 000016F4 88F7                <1> 	mov	bh, dh	; subtract lower row from upper row
  4313 000016F6 28EF                <1> 	sub	bh, ch
  4314 000016F8 FEC7                <1> 	inc	bh	; adjust difference by 1
  4315 000016FA 38C7                <1> 	cmp	bh, al 	; line count = amount of rows in window?
  4316 000016FC 7502                <1> 	jne	short al_set ; if not the we're all set
  4317 000016FE 30C0                <1> 	xor	al, al	; otherwise set al to zero
  4318                              <1> al_set:
  4319 00001700 C3                  <1> 	retn
  4320                              <1> 
  4321                              <1> scroll_position:
  4322                              <1> 	; 30/01/2016
  4323                              <1>         ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4324                              <1> 	; 07/09/2014 (scroll_up)
  4325                              <1> 
  4326 00001701 6652                <1> 	push	dx
  4327 00001703 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
  4328 00001706 E82FFFFFFF          <1> 	call	position
  4329 0000170B 01C6                <1> 	add	esi, eax
  4330 0000170D 89F7                <1> 	mov	edi, esi
  4331 0000170F 665A                <1> 	pop	dx	; lower right position in DX
  4332 00001711 6629CA              <1> 	sub	dx, cx
  4333 00001714 FEC6                <1> 	inc	dh	; dh = #rows 
  4334 00001716 FEC2                <1> 	inc	dl	; dl = #cols in block
  4335 00001718 59                  <1> 	pop	ecx 	; return address
  4336 00001719 6658                <1> 	pop	ax	; * ; al = line count, ah = attribute
  4337 0000171B 51                  <1> 	push	ecx	; return address
  4338 0000171C 0FB7C8              <1> 	movzx	ecx, ax
  4339                              <1> 	;mov	ah, [CRT_COLS]
  4340 0000171F B450                <1> 	mov	ah, 80
  4341 00001721 F6E4                <1> 	mul	ah	; determine offset to from address
  4342 00001723 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
  4343                              <1> 	;
  4344 00001726 6650                <1> 	push	ax	; offset 
  4345 00001728 6652                <1> 	push	dx
  4346                              <1> 	;
  4347                              <1> 	; 04/04/2014
  4348 0000172A 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
  4349                              <1> n9:                      ; wait_display_enable
  4350 0000172E EC                  <1>         in      al, dx   ; get port
  4351 0000172F A808                <1> 	test	al, RVRT ; wait for vertical retrace	
  4352 00001731 74FB                <1> 	jz	short n9 ; wait_display_enable
  4353 00001733 B025                <1> 	mov	al, 25h
  4354 00001735 B2D8                <1> 	mov	dl, 0D8h ; address control port
  4355 00001737 EE                  <1> 	out	dx, al	; turn off video during vertical retrace
  4356 00001738 665A                <1> 	pop	dx	; #rows, #cols
  4357 0000173A 6658                <1>        	pop	ax	; offset
  4358 0000173C 6691                <1> 	xchg	ax, cx	; 
  4359                              <1> 	; ecx = offset, al = line count, ah = attribute
  4360                              <1> 	;
  4361 0000173E 08C0                <1> 	or	al, al
  4362 00001740 C3                  <1> 	retn
  4363                              <1> 
  4364                              <1> n10:
  4365                              <1> 	; Move rows
  4366 00001741 88D1                <1> 	mov	cl, dl	; get # of cols to move
  4367 00001743 56                  <1> 	push	esi
  4368 00001744 57                  <1> 	push	edi	; save start address
  4369                              <1> n10r:
  4370 00001745 66A5                <1> 	movsw		; move that line on screen
  4371 00001747 FEC9                <1> 	dec	cl
  4372 00001749 75FA                <1>         jnz     short n10r
  4373 0000174B 5F                  <1> 	pop	edi
  4374 0000174C 5E                  <1> 	pop	esi	; recover addresses
  4375 0000174D C3                  <1> 	retn
  4376                              <1> n11:
  4377                              <1> 	; Clear rows
  4378                              <1>                 ; dh =  #rows
  4379 0000174E 88D1                <1>         mov	cl, dl	; get # of cols to clear
  4380 00001750 57                  <1>         push    edi     ; save address
  4381                              <1> n11r:
  4382 00001751 66AB                <1>         stosw           ; store fill character
  4383 00001753 FEC9                <1> 	dec	cl
  4384 00001755 75FA                <1>         jnz     short n11r
  4385 00001757 5F                  <1>         pop     edi     ; recover address
  4386 00001758 C3                  <1> 	retn
  4387                              <1> 
  4388                              <1> SCROLL_DOWN:
  4389                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4390                              <1> 	;
  4391                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4392                              <1> 
  4393                              <1> ;------------------------------------------
  4394                              <1> ; SCROLL DOWN
  4395                              <1> ;	THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
  4396                              <1> ;	BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
  4397                              <1> ;	WITH A DEFINED CHARACTER
  4398                              <1> ; INPUT
  4399                              <1> ;	(AH) = CURRENT CRT MODE
  4400                              <1> ;	(AL) = NUMBER OF LINES TO SCROLL
  4401                              <1> ;	(CX) = UPPER LEFT CORNER OF RECION
  4402                              <1> ;	(DX) = LOWER RIGHT CORNER OF REGION
  4403                              <1> ;	(BH) = FILL CHARACTER
  4404                              <1> ;	(DS) = DATA SEGMENT
  4405                              <1> ;	(ES) = REGEN SEGMENT
  4406                              <1> ; OUTPUT
  4407                              <1> ;	NONE -- SCREEN IS SCROLLED
  4408                              <1> ;------------------------------------------
  4409                              <1> 
  4410                              <1> 	; ((ah = 3))
  4411                              <1> 	; cl = left upper column
  4412                              <1> 	; ch = left upper row
  4413                              <1> 	; dl = right lower column
  4414                              <1> 	; dh = right lower row
  4415                              <1> 	;
  4416                              <1> 	; al = line count 
  4417                              <1> 	; ah = attribute to be used on blanked line	
  4418                              <1> 	; bl = video page number (0 to 7)
  4419                              <1> 	; 
  4420                              <1> 
  4421                              <1> 	; !!!!
  4422 00001759 FD                  <1> 	std		; DIRECTION FOR SCROLL DOWN
  4423                              <1> 	; !!!!
  4424 0000175A E891FFFFFF          <1> 	call	test_line_count ; 16/01/2016
  4425                              <1> 	
  4426                              <1> 	;mov	bh, [CRT_MODE] ; current video mode
  4427                              <1> 	;cmp	bh, 4
  4428                              <1>  	;jb	short n12
  4429                              <1> 
  4430                              <1> 	;cmp	bh, 7 ; TEST FOR BW CARD
  4431                              <1> 	;jne	GRAPHICS_DOWN
  4432                              <1> 
  4433                              <1> n12:			; CONTINUE_DOWN
  4434 0000175F 6650                <1> 	push	ax	; * ; save attribute in ah
  4435 00001761 6689D0              <1> 	mov	ax, dx	; LOWER RIGHT CORNER
  4436 00001764 E898FFFFFF          <1> 	call	scroll_position	; GET REGEN LOCATION
  4437 00001769 7419                <1> 	jz	short n14
  4438 0000176B 29CE                <1> 	sub	esi, ecx  ; SI IS FROM ADDRESS
  4439 0000176D 88F7                <1> 	mov	bh, dh  ; #rows in block
  4440 0000176F 28C7                <1> 	sub	bh, al	; #rows to be moved
  4441                              <1> n13:
  4442 00001771 E8CBFFFFFF          <1> 	call	n10	; MOVE ONE ROW
  4443                              <1> 
  4444                              <1> 	;mov    cl, [CRT_COLS] 
  4445                              <1> 	;add	cl, cl
  4446                              <1>         ;mov    ecx, 80*2
  4447 00001776 66B9A000            <1>         mov     cx, 80*2
  4448 0000177A 29CE                <1>         sub     esi, ecx  ; next line
  4449 0000177C 29CF                <1>         sub     edi, ecx
  4450 0000177E FECF                <1> 	dec	bh	 ; count of lines to move
  4451 00001780 75EF                <1> 	jnz	short n13 ; row loop
  4452                              <1> 	; bh = 0
  4453 00001782 88C6                <1> 	mov	dh, al	 ; #rows
  4454                              <1> n14:
  4455                              <1> 	; attribute in ah
  4456 00001784 B020                <1> 	mov	al, ' '	 ; fill with blanks
  4457                              <1> n15:
  4458 00001786 E8C3FFFFFF          <1> 	call	n11 ; 16/01/2016
  4459                              <1> 
  4460                              <1> 	;mov	cl, [CRT_COLS]
  4461                              <1> 	;add	cl, cl
  4462                              <1>         ;mov    ecx, 80*2
  4463 0000178B B1A0                <1>         mov	cl, 80*2
  4464 0000178D 29CF                <1>         sub     edi, ecx
  4465 0000178F FECE                <1> 	dec	dh
  4466 00001791 75F3                <1> 	jnz	short n15
  4467                              <1> 	;
  4468 00001793 3A1D[F8780000]      <1> 	cmp	bl, [ACTIVE_PAGE]
  4469 00001799 7507                <1> 	jne	short n16
  4470                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
  4471 0000179B B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
  4472 0000179D 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
  4473 000017A1 EE                  <1> 	out	dx, al
  4474                              <1> n16:
  4475                              <1> 	; !!!!
  4476 000017A2 FC                  <1> 	cld		; Clear direction flag !
  4477                              <1> 	; !!!!
  4478 000017A3 C3                  <1> 	retn
  4479                              <1> 
  4480                              <1> READ_AC_CURRENT:
  4481                              <1> 	; 18/01/2016
  4482                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4483                              <1> 	;
  4484                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4485                              <1> 	;
  4486                              <1> 
  4487 000017A4 E805000000          <1> 	call	_read_ac_current
  4488 000017A9 E9B5FDFFFF          <1>         jmp     VIDEO_RETURN
  4489                              <1> 
  4490                              <1> ;------------------------------------------------------------------------
  4491                              <1> ; READ_AC_CURRENT							:
  4492                              <1> ;	THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT	:
  4493                              <1> ;	CURSOR POSITION AND RETURNS THEM TO THE CALLER			:
  4494                              <1> ; INPUT									:
  4495                              <1> ;	(AH) = CURRENT CRT MODE						:
  4496                              <1> ;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )			:
  4497                              <1> ;	(DS) = DATA SEGMENT						:
  4498                              <1> ;	(ES) = REGEN SEGMENT						:
  4499                              <1> ; OUTPUT								:
  4500                              <1> ;	(AL) = CHARACTER READ						:
  4501                              <1> ;	(AH) = ATTRIBUTE READ						:
  4502                              <1> ;------------------------------------------------------------------------
  4503                              <1> 
  4504                              <1> _read_ac_current: ; 18/01/2016
  4505                              <1> 
  4506                              <1> p10:
  4507 000017AE E896FEFFFF          <1> 	call	find_position	; GET REGEN LOCATION AND PORT ADDRESS
  4508                              <1> 	;
  4509                              <1> 	; esi = regen location
  4510                              <1> 	; dx = status port
  4511                              <1> 	;
  4512                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  4513                              <1> 	;
  4514                              <1> p11:			; wait for horizontal retrace is low or vertical
  4515 000017B3 FB                  <1> 	sti		; enable interrupts first
  4516 000017B4 3A1D[F8780000]      <1>         cmp     bl, [ACTIVE_PAGE]
  4517 000017BA 750C                <1> 	jne	short p14 
  4518 000017BC FA                  <1> 	cli 		; block interrupts for single loop
  4519 000017BD EC                  <1> 	in	al, dx	; get status from the adapter
  4520 000017BE A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  4521 000017C0 75F1                <1> 	jnz	short p11 ; wait until it is
  4522                              <1> p12:			;  wait for either retrace high
  4523 000017C2 EC                  <1> 	in	al, dx ; get status again
  4524 000017C3 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  4525 000017C5 74FB                <1> 	jz	short p12 ; wait until either retrace active
  4526 000017C7 FB                  <1> 	sti
  4527                              <1> p14:
  4528 000017C8 81C600800B00        <1> 	add	esi, 0B8000h 
  4529 000017CE 668B06              <1> 	mov	ax, [esi]
  4530                              <1> 
  4531 000017D1 C3                  <1> 	retn	; 18/01/2016
  4532                              <1> 
  4533                              <1> 
  4534                              <1> WRITE_AC_CURRENT:
  4535                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4536                              <1> 	;
  4537                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4538                              <1> 	;
  4539                              <1> ;----------------------------------------------------------------
  4540                              <1> ; WRITE_AC_CURRENT						:
  4541                              <1> ;	THTS ROUTINE WRITES THE ATTRIBUTE AND CHARACTER		:
  4542                              <1> ;	AT THE CURRENT CURSOR POSITION				:
  4543                              <1> ; INPUT								:
  4544                              <1> ;	(AH) = CURRENT CRT MODE					:
  4545                              <1> ;	(BH) = DISPLAY PAGE					:
  4546                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
  4547                              <1> ;	(AL) = CHAR TO WRITE					:
  4548                              <1> ;	(BL) = ATTRIBUTE OF CHAR TO WRITE			:
  4549                              <1> ;	(DS) = DATA SEGMENT					:
  4550                              <1> ;	(ES) = REGEN SEGMENT					:
  4551                              <1> ; OUTPUT							:
  4552                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
  4553                              <1> ;----------------------------------------------------------------
  4554                              <1> 
  4555 000017D2 E821000000          <1> 	call	_write_c_current
  4556                              <1> 
  4557 000017D7 0FB6F3              <1> 	movzx	esi, bl ; video page number (0 to 7)	
  4558 000017DA 88A6[E8720000]      <1> 	mov	[esi+chr_attrib], ah ; color/attribute
  4559                              <1> 
  4560 000017E0 E97EFDFFFF          <1>         jmp     VIDEO_RETURN
  4561                              <1> 
  4562                              <1> WRITE_C_CURRENT:
  4563                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4564                              <1> 	;
  4565                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4566                              <1> 	;
  4567                              <1> 
  4568                              <1> 	;and	bl, 7 ; video page number (<= 7)
  4569 000017E5 0FB6F3              <1> 	movzx	esi, bl	
  4570 000017E8 8AA6[E8720000]      <1> 	mov	ah, [esi+chr_attrib]
  4571                              <1> 
  4572 000017EE E805000000          <1> 	call	_write_c_current
  4573 000017F3 E96BFDFFFF          <1>         jmp     VIDEO_RETURN
  4574                              <1> 
  4575                              <1> ;----------------------------------------------------------------
  4576                              <1> ; WRITE_C_CURRENT						:
  4577                              <1> ;	THIS ROUTINE WRITES THE CHARACTER AT			:
  4578                              <1> ;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED	:
  4579                              <1> ; INPUT								:
  4580                              <1> ;	(AH) = CURRENT CRT MODE					:
  4581                              <1> ;	(BH) = DISPLAY PAGE					:
  4582                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
  4583                              <1> ;	(AL) = CHAR TO WRITE					:
  4584                              <1> ;	(DS) = DATA SEGMENT					:
  4585                              <1> ;	(ES) = REGEN SEGMENT					:
  4586                              <1> ; OUTPUT							:
  4587                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
  4588                              <1> ;----------------------------------------------------------------
  4589                              <1> 
  4590                              <1> _write_c_current:  ; from 'write_tty'
  4591                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4592                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4593                              <1> 	; 18/01/2014
  4594                              <1> 	; 04/12/2013
  4595                              <1> 	;
  4596                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4597                              <1> 	;
  4598                              <1> 
  4599 000017F8 FA                  <1> 	cli		
  4600                              <1> 	; bl = video page
  4601                              <1> 	; al = character
  4602                              <1> 	; ah = color/attribute
  4603 000017F9 6652                <1> 	push	dx
  4604 000017FB 6650                <1> 	push	ax	; save character & attribute/color
  4605 000017FD E847FEFFFF          <1> 	call 	find_position  ; get regen location and port address
  4606                              <1> 	; esi = regen location
  4607                              <1> 	; dx = status port
  4608                              <1> 	;
  4609                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  4610                              <1> 	;
  4611                              <1> p41:			; wait for horizontal retrace is low or vertical
  4612 00001802 FB                  <1> 	sti		; enable interrupts first
  4613 00001803 3A1D[F8780000]      <1>         cmp     bl, [ACTIVE_PAGE]
  4614 00001809 7510                <1> 	jne	short p44 
  4615 0000180B FA                  <1> 	cli 		; block interrupts for single loop
  4616 0000180C EC                  <1> 	in	al, dx	; get status from the adapter
  4617 0000180D A808                <1> 	test	al, RVRT ; check for vertical retrace first
  4618 0000180F 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  4619 00001811 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  4620 00001813 75ED                <1> 	jnz	short p41 ; wait until it is
  4621                              <1> p42:			;  wait for either retrace high
  4622 00001815 EC                  <1> 	in	al, dx ; get status again
  4623 00001816 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  4624 00001818 74FB                <1> 	jz	short p42 ; wait until either retrace active
  4625                              <1> p43:	
  4626 0000181A FB                  <1> 	sti
  4627                              <1> p44:
  4628 0000181B 6658                <1> 	pop	ax	; restore the character (al) & attribute (ah)
  4629 0000181D 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  4630                              <1> 				; Retro UNIX 386 v1 feature only!
  4631 00001823 668906              <1> 	mov	[esi], ax
  4632 00001826 665A                <1> 	pop	dx
  4633 00001828 C3                  <1> 	retn
  4634                              <1> 
  4635                              <1> ; 18/01/2016
  4636                              <1> ; 16/01/2016
  4637                              <1> ; 30/06/2015
  4638                              <1> ; 27/06/2015
  4639                              <1> ; 11/03/2015
  4640                              <1> ; 02/09/2014
  4641                              <1> ; 30/08/2014
  4642                              <1> ; VIDEO FUNCTIONS
  4643                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  4644                              <1> 
  4645                              <1> WRITE_TTY:
  4646                              <1> 	; 30/01/2016
  4647                              <1> 	; 18/01/2016
  4648                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  4649                              <1> 	; 13/08/2015
  4650                              <1> 	; 02/09/2014
  4651                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  4652                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  4653                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  4654                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  4655                              <1> 	;
  4656                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  4657                              <1> 	;	   AL = Character to be written
  4658                              <1> 	;	   EBX = Video Page (0 to 7)
  4659                              <1> 	;	   (BH = 0 --> Video Mode 3)
  4660                              <1> 
  4661                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  4662                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  4663                              <1> 
  4664                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  4665                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  4666                              <1> ;
  4667                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  4668                              <1> ;
  4669                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  4670                              <1> ;										:
  4671                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  4672                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  4673                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  4674                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  4675                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  4676                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  4677                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  4678                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  4679                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  4680                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  4681                              <1> ;   THE 0 COLOR IS USED.							:
  4682                              <1> ;   ENTRY --									:
  4683                              <1> ;     (AH) = CURRENT CRT MODE							:
  4684                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  4685                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  4686                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  4687                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  4688                              <1> ;   EXIT -- 									:
  4689                              <1> ;     ALL REGISTERS SAVED							:
  4690                              <1> ;--------------------------------------------------------------------------------
  4691                              <1> 
  4692 00001829 FA                  <1> 	cli
  4693                              <1> 	;
  4694                              <1> 	; READ CURSOR (04/12/2013)
  4695                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  4696 0000182A 08FF                <1> 	or	bh, bh
  4697 0000182C 0F85D5000000        <1> 	jnz	beeper
  4698                              <1> 	; 01/09/2014
  4699 00001832 803D[D6720000]03    <1> 	cmp	byte [CRT_MODE], 3
  4700 00001839 7405                <1> 	je	short m3
  4701                              <1> 	;
  4702 0000183B E8FBFCFFFF          <1> 	call	set_mode_3 ; 16/01/2016
  4703                              <1> m3:
  4704 00001840 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  4705 00001842 66D1E6              <1> 	shl	si, 1
  4706 00001845 81C6[E8780000]      <1> 	add	esi, CURSOR_POSN
  4707 0000184B 668B16              <1> 	mov	dx, [esi]
  4708                              <1> 	;
  4709                              <1> 	; dx now has the current cursor position
  4710                              <1> 	;
  4711 0000184E 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  4712 00001850 762F                <1> 	jbe	short u8
  4713                              <1> 	;
  4714                              <1> 	; write the char to the screen
  4715                              <1> u0:	
  4716                              <1> 	; ah = attribute/color
  4717                              <1> 	; al = character
  4718                              <1> 	; bl = video page number (0 to 7)
  4719                              <1> 	; bh = 0
  4720                              <1> 	;
  4721 00001852 E8A1FFFFFF          <1> 	call	_write_c_current ; 16/01/2015
  4722                              <1> 	;
  4723                              <1> 	; position the cursor for next char
  4724 00001857 FEC2                <1> 	inc	dl		; next column
  4725                              <1> 	;cmp	dl, [CRT_COLS]
  4726 00001859 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  4727 0000185C 755F                <1>         jne     _set_cpos
  4728 0000185E B200                <1> 	mov	dl, 0		; column = 0
  4729                              <1> u10:				; (line feed found)
  4730 00001860 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  4731 00001863 7218                <1> 	jb 	short u6
  4732                              <1> 	;
  4733                              <1> 	; scroll required
  4734                              <1> u1:	
  4735                              <1> 	; SET CURSOR POSITION (04/12/2013)
  4736 00001865 E853000000          <1> 	call	_set_cpos
  4737                              <1> 	;
  4738                              <1> 	; determine value to fill with during scroll
  4739                              <1> u2:
  4740                              <1> 	; bl = video page number
  4741                              <1> 	;
  4742 0000186A E83FFFFFFF          <1> 	call _read_ac_current ; 18/01/2016
  4743                              <1> 	;
  4744                              <1> 	; al = character, ah = attribute
  4745                              <1> 	; bl = video page number 	
  4746                              <1> u3:
  4747                              <1> 	;;mov	ax, 0601h 	; scroll one line
  4748                              <1> 	;;sub	cx, cx		; upper left corner
  4749                              <1> 	;;mov	dh, 25-1 	; lower right row
  4750                              <1> 	;;;mov	dl, [CRT_COLS]
  4751                              <1> 	;mov	dl, 80		; lower right column	
  4752                              <1> 	;;dec	dl
  4753                              <1> 	;;mov	dl, 79
  4754                              <1> 
  4755                              <1> 	;;call	scroll_up	; 04/12/2013
  4756                              <1> 	;;; 11/03/2015
  4757                              <1> 	; 02/09/2014
  4758                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  4759                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  4760                              <1> 	; 11/03/2015
  4761 0000186F 6629C9              <1> 	sub	cx, cx
  4762 00001872 66BA4F18            <1> 	mov	dx, 184Fh ; dl = 79 (column), dh = 24 (row)
  4763                              <1> 	;
  4764 00001876 B001                <1> 	mov	al, 1		; scroll 1 line up
  4765                              <1> 		; ah = attribute
  4766 00001878 E902FEFFFF          <1> 	jmp	_scroll_up	; 16/01/2016
  4767                              <1> ;u4:
  4768                              <1> 	;;int	10h		; video-call return
  4769                              <1> 				; scroll up the screen
  4770                              <1> 				; tty return
  4771                              <1> ;u5:
  4772                              <1> 	;retn			; return to the caller
  4773                              <1> 
  4774                              <1> u6:				; set-cursor-inc
  4775 0000187D FEC6                <1> 	inc	dh		; next row
  4776                              <1> 				; set cursor
  4777                              <1> ;u7:					
  4778                              <1> 	;;mov	ah, 02h
  4779                              <1> 	;;jmp	short u4 	; establish the new cursor
  4780                              <1> 	;call	_set_cpos
  4781                              <1> 	;jmp 	short u5
  4782 0000187F EB3C                <1> 	jmp     _set_cpos
  4783                              <1> 
  4784                              <1> 	; check for control characters
  4785                              <1> u8:
  4786 00001881 7438                <1> 	je	short u9
  4787 00001883 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  4788 00001885 74D9                <1> 	je	short u10
  4789 00001887 3C07                <1> 	cmp	al, 07h 	; is it a bell
  4790 00001889 747C                <1> 	je	short u11
  4791 0000188B 3C08                <1> 	cmp	al, 08h		; is it a backspace
  4792                              <1> 	;jne	short u0
  4793 0000188D 7424                <1> 	je	short bs	; 12/12/2013
  4794                              <1> 	; 12/12/2013 (tab stop)
  4795 0000188F 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  4796 00001891 75BF                <1> 	jne	short u0
  4797 00001893 88D0                <1> 	mov	al, dl
  4798 00001895 6698                <1> 	cbw
  4799 00001897 B108                <1> 	mov	cl, 8
  4800 00001899 F6F1                <1> 	div	cl
  4801 0000189B 28E1                <1> 	sub	cl, ah
  4802                              <1> ts:
  4803                              <1> 	; 02/09/2014
  4804                              <1> 	; 01/09/2014
  4805 0000189D B020                <1> 	mov	al, 20h
  4806                              <1> tsloop:
  4807 0000189F 6651                <1> 	push	cx
  4808 000018A1 6650                <1> 	push	ax
  4809 000018A3 30FF                <1> 	xor 	bh, bh
  4810                              <1> 	;mov	bl, [ACTIVE_PAGE]
  4811 000018A5 E896FFFFFF          <1> 	call	m3
  4812 000018AA 6658                <1> 	pop	ax  ; ah = attribute/color
  4813 000018AC 6659                <1> 	pop	cx
  4814 000018AE FEC9                <1> 	dec	cl
  4815 000018B0 75ED                <1> 	jnz	short tsloop
  4816 000018B2 C3                  <1> 	retn
  4817                              <1> bs:	
  4818                              <1> 	; back space found
  4819                              <1> 
  4820 000018B3 08D2                <1> 	or	dl, dl 		; is it already at start of line
  4821                              <1> 	;je	short u7 	; set_cursor
  4822 000018B5 7406                <1> 	jz	short _set_cpos
  4823 000018B7 664A                <1> 	dec	dx     		; no -- just move it back
  4824                              <1> 	;jmp	short u7
  4825 000018B9 EB02                <1> 	jmp	short _set_cpos
  4826                              <1> 
  4827                              <1> 	; carriage return found
  4828                              <1> u9:
  4829 000018BB B200                <1> 	mov	dl, 0 		; move to first column
  4830                              <1> 	;jmp	short u7
  4831                              <1> 	;jmp	short _set_cpos ; 30/01/2016
  4832                              <1> 
  4833                              <1> 	; line feed found
  4834                              <1> ;u10:
  4835                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  4836                              <1> ;	jne	short u6 	; no, just set the cursor
  4837                              <1> ;       jmp     u1              ; yes, scroll the screen
  4838                              <1> 
  4839                              <1> _set_cpos:
  4840                              <1> 	; 27/06/2015
  4841                              <1> 	; 01/09/2014
  4842                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  4843                              <1> 	;
  4844                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  4845                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  4846                              <1> 	;
  4847                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4848                              <1> 	;
  4849                              <1> ;----------------------------------------------
  4850                              <1> ; SET_CPOS
  4851                              <1> ;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  4852                              <1> ;	NEW X-Y VALUES PASSED
  4853                              <1> ; INPUT
  4854                              <1> ;	DX - ROW,COLUMN OF NEW CURSOR
  4855                              <1> ;	BH - DISPLAY PAGE OF CURSOR
  4856                              <1> ; OUTPUT
  4857                              <1> ;	CURSOR ID SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  4858                              <1> ;----------------------------------------------
  4859                              <1> 	;
  4860 000018BD BE[E8780000]        <1> 	mov	esi, CURSOR_POSN
  4861 000018C2 0FB6C3              <1>         movzx   eax, bl	; BL = video page number ; 27/06/2015 (movzx)
  4862                              <1> ;	or	al, al
  4863                              <1> ;	jz	short _set_cpos_0
  4864 000018C5 D0E0                <1>         shl     al, 1   ; word offset
  4865 000018C7 01C6                <1>         add     esi, eax
  4866                              <1> ;_set_cpos_0:
  4867 000018C9 668916              <1> 	mov	[esi], dx ; save the pointer
  4868 000018CC 381D[F8780000]      <1> 	cmp	[ACTIVE_PAGE], bl
  4869 000018D2 7532                <1> 	jne	short m17
  4870                              <1> 	;call	m18	; CURSOR SET
  4871                              <1> ;m17:			; SET_CPOS_RETURN
  4872                              <1> 	; 01/09/2014
  4873                              <1> ;	retn
  4874                              <1> 		; DX  = row/column
  4875                              <1> m18:
  4876 000018D4 E861FDFFFF          <1> 	call	position ; determine location in regen buffer	
  4877 000018D9 668B0D[E4780000]    <1> 	mov	cx, [CRT_START]
  4878 000018E0 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  4879                              <1> 			; to the start address (offset) for this page
  4880 000018E3 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  4881 000018E6 B40E                <1> 	mov	ah, 14	; register number for cursor
  4882                              <1> 	;call	m16	; output value to the 6845	
  4883                              <1> 	;retn
  4884                              <1> 
  4885                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  4886                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  4887                              <1> m16:
  4888 000018E8 FA                  <1> 	cli
  4889                              <1> 	;mov	dx, [addr_6845] ; address register
  4890 000018E9 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  4891 000018ED 88E0                <1> 	mov	al, ah	; get value
  4892 000018EF EE                  <1> 	out	dx, al	; register set
  4893 000018F0 6642                <1> 	inc	dx	; data register
  4894 000018F2 EB00                <1> 	jmp	$+2	; i/o delay
  4895 000018F4 88E8                <1> 	mov	al, ch	; data
  4896 000018F6 EE                  <1> 	out	dx, al	
  4897 000018F7 664A                <1> 	dec	dx	
  4898 000018F9 88E0                <1> 	mov	al, ah
  4899 000018FB FEC0                <1> 	inc	al	; point to other data register
  4900 000018FD EE                  <1> 	out	dx, al	; set for second register
  4901 000018FE 6642                <1> 	inc	dx
  4902 00001900 EB00                <1> 	jmp	$+2	; i/o delay
  4903 00001902 88C8                <1> 	mov	al, cl	; second data value
  4904 00001904 EE                  <1> 	out	dx, al
  4905 00001905 FB                  <1> 	sti
  4906                              <1> m17:
  4907 00001906 C3                  <1> 	retn
  4908                              <1> 
  4909                              <1> beeper: 
  4910                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4911                              <1> 	; 18/01/2014
  4912                              <1> 	; 03/12/2013
  4913                              <1> 	; bell found
  4914                              <1> u11:
  4915 00001907 FB                  <1> 	sti
  4916 00001908 3A1D[F8780000]      <1> 	cmp	bl, [ACTIVE_PAGE]
  4917 0000190E 7551                <1> 	jne	short u12	; Do not sound the beep 
  4918                              <1> 				; if it is not written on the active page
  4919 00001910 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  4920 00001914 B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  4921                              <1> 	;call	beep		; sound the pod bell
  4922                              <1> 	;jmp	short u5 	; tty_return
  4923                              <1> 	;retn
  4924                              <1> 	
  4925                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  4926                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  4927                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  4928                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  4929                              <1> 
  4930                              <1> beep:
  4931                              <1> 	; 07/02/2015
  4932                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4933                              <1> 	; 18/01/2014
  4934                              <1> 	; 03/12/2013
  4935                              <1> 	;
  4936                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  4937                              <1> 	;
  4938                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  4939                              <1> 	;
  4940                              <1> 	; ENTRY:
  4941                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  4942                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  4943                              <1> 	; EXIT:				:
  4944                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  4945                              <1> 
  4946 00001916 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  4947 00001917 FA                  <1> 	cli			; block interrupts during update
  4948 00001918 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  4949 0000191A E643                <1> 	out	TIMER+3, al 	; write timer mode register
  4950 0000191C EB00                <1> 	jmp	$+2		; I/O delay
  4951 0000191E 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  4952 00001920 E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  4953 00001922 EB00                <1> 	jmp	$+2		; I/O delay
  4954 00001924 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  4955 00001926 E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  4956 00001928 E461                <1> 	in	al, PORT_B	; get current setting of port
  4957 0000192A 88C4                <1> 	mov	ah, al		; save that setting
  4958 0000192C 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  4959 0000192E E661                <1> 	out	PORT_B, al	; and restore interrupt status
  4960                              <1> 	;popf	; 18/01/2014
  4961 00001930 FB                  <1> 	sti
  4962                              <1> g7:				; 1/64 second per count (bl)
  4963 00001931 B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  4964 00001936 E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  4965 0000193B FECB                <1> 	dec	bl		; (bl) length count expired?
  4966 0000193D 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  4967                              <1> 	;
  4968                              <1> 	;pushf			; save interrupt status
  4969 0000193F FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  4970 00001940 E461                <1> 	in	al, PORT_B	; get current port value
  4971                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  4972 00001942 0CFC                <1>         or      al, ~(GATE2+SPK2)
  4973 00001944 20C4                <1>         and	ah, al		; someone turned them off during beep
  4974 00001946 88E0                <1> 	mov	al, ah		; recover value of port
  4975                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  4976 00001948 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  4977 0000194A E661                <1> 	out	PORT_B, al	; and stop speaker timer
  4978                              <1> 	;popf			; restore interrupt flag state
  4979 0000194C FB                  <1> 	sti
  4980 0000194D B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  4981 00001952 E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  4982                              <1> 	;pushf			; save interrupt status
  4983 00001957 FA                  <1> 	cli			; block interrupts during update
  4984 00001958 E461                <1> 	in	al, PORT_B	; get current port value in case	
  4985 0000195A 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  4986 0000195C 08E0                <1> 	or	al, ah		; recover value of port_b
  4987 0000195E E661                <1> 	out	PORT_B, al	; restore speaker status
  4988 00001960 9D                  <1> 	popf			; restore interrupt flag state
  4989                              <1> u12:	
  4990 00001961 C3                  <1> 	retn
  4991                              <1> 
  4992                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  4993                              <1> 
  4994                              <1> WAITF:
  4995                              <1> waitf:
  4996                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4997                              <1> 	; 03/12/2013
  4998                              <1> 	;
  4999                              <1> ;	push ax			; save work register (ah)	
  5000                              <1> ;waitf1:
  5001                              <1> 				; use timer 1 output bits
  5002                              <1> ;	in	al, PORT_B	; read current counter output status
  5003                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  5004                              <1> ;	cmp	al, ah		; did it just change
  5005                              <1> ;	je	short waitf1	; wait for a change in output line
  5006                              <1> ;	;
  5007                              <1> ;	mov	ah, al		; save new lflag state
  5008                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  5009                              <1> ;	;
  5010                              <1> ;	pop	ax		; restore (ah)
  5011                              <1> ;	retn			; return (cx)=0
  5012                              <1> 
  5013                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  5014                              <1> ; 17/12/2014 (dsectrm2.s)
  5015                              <1> ; WAITF
  5016                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  5017                              <1> ;
  5018                              <1> ;---WAITF-----------------------------------------------------------------------
  5019                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  5020                              <1> ; ENTRY:
  5021                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  5022                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  5023                              <1> ; EXIT:
  5024                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  5025                              <1> ;	(CX) = 0	
  5026                              <1> ;-------------------------------------------------------------------------------
  5027                              <1> 
  5028                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  5029                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  5030                              <1> 
  5031                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  5032 00001962 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  5033                              <1> 	; 16/12/2014
  5034                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  5035 00001964 D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  5036                              <1> ;17/12/2014	
  5037                              <1> ;WAITF1:
  5038                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  5039                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  5040                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  5041                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  5042                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  5043                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  5044                              <1> 	;
  5045                              <1> 	; 17/12/2014
  5046                              <1> 	;
  5047                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  5048                              <1> 	;
  5049                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  5050                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  5051                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  5052                              <1> WR_STATE_0:
  5053 00001966 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  5054 00001968 A810                <1> 	TEST	AL,010H
  5055 0000196A 74FA                <1> 	JZ	SHORT WR_STATE_0
  5056                              <1> WR_STATE_1:
  5057 0000196C E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  5058 0000196E A810                <1> 	TEST	AL,010H
  5059 00001970 75FA                <1> 	JNZ	SHORT WR_STATE_1
  5060 00001972 E2F2                <1>         LOOP    WR_STATE_0
  5061                              <1> 	;
  5062 00001974 6658                <1> 	POP	AX			; RESTORE (AH)
  5063 00001976 C3                  <1> 	RETn				; (CX) = 0
  5064                              <1> 
  5065                              <1> ; % include 'vidata.s' ; VIDEO DATA
  5066                              <1> 
  5067                              <1> ; /// End Of VIDEO FUNCTIONS ///
  5068                                  
  5069                                  setup_rtc_int:
  5070                                  ; source: http://wiki.osdev.org/RTC
  5071 00001977 FA                      	cli		; disable interrupts
  5072                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  5073                                  	; in order to change this ...
  5074                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  5075                                  	; (rate must be above 2 and not over 15)
  5076                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  5077 00001978 B08A                    	mov	al, 8Ah 
  5078 0000197A E670                    	out	70h, al ; set index to register A, disable NMI
  5079 0000197C 90                      	nop
  5080 0000197D E471                    	in	al, 71h ; get initial value of register A
  5081 0000197F 88C4                    	mov 	ah, al
  5082 00001981 80E4F0                  	and	ah, 0F0h
  5083 00001984 B08A                    	mov	al, 8Ah 
  5084 00001986 E670                    	out	70h, al ; reset index to register A
  5085 00001988 88E0                    	mov	al, ah
  5086 0000198A 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  5087 0000198C E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  5088                                  	; enable RTC interrupt
  5089 0000198E B08B                    	mov	al, 8Bh ;
  5090 00001990 E670                    	out	70h, al ; select register B and disable NMI
  5091 00001992 90                      	nop
  5092 00001993 E471                    	in	al, 71h ; read the current value of register B
  5093 00001995 88C4                    	mov	ah, al  ;
  5094 00001997 B08B                    	mov 	al, 8Bh ;
  5095 00001999 E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  5096 0000199B 88E0                    	mov	al, ah  ;
  5097 0000199D 0C40                    	or	al, 40h ;
  5098 0000199F E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  5099 000019A1 FB                      	sti
  5100 000019A2 C3                      	retn
  5101                                  
  5102                                  ; Write memory information
  5103                                  ; 29/01/2016
  5104                                  ; 06/11/2014
  5105                                  ; 14/08/2015 
  5106                                  memory_info:	
  5107 000019A3 A1[CC780000]            	mov	eax, [memory_size] ; in pages
  5108 000019A8 50                      	push	eax
  5109 000019A9 C1E00C                  	shl	eax, 12		   ; in bytes
  5110 000019AC BB0A000000              	mov	ebx, 10
  5111 000019B1 89D9                    	mov	ecx, ebx	   ; 10
  5112 000019B3 BE[9B740000]            	mov	esi, mem_total_b_str	
  5113 000019B8 E8BE000000              	call	bintdstr
  5114 000019BD 58                      	pop	eax
  5115 000019BE B107                    	mov	cl, 7
  5116 000019C0 BE[BF740000]            	mov	esi, mem_total_p_str
  5117 000019C5 E8B1000000              	call	bintdstr	
  5118                                  	; 14/08/2015
  5119 000019CA E8C9000000              	call	calc_free_mem
  5120                                  	; edx = calculated free pages
  5121                                  	; ecx = 0
  5122 000019CF A1[D0780000]            	mov 	eax, [free_pages]
  5123 000019D4 39D0                    	cmp	eax, edx ; calculated free mem value 
  5124                                  		; and initial free mem value are same or not?
  5125 000019D6 751D                    	jne 	short pmim ; print mem info with '?' if not
  5126 000019D8 52                      	push 	edx ; free memory in pages	
  5127                                  	;mov 	eax, edx
  5128 000019D9 C1E00C                  	shl	eax, 12 ; convert page count
  5129                                  			; to byte count
  5130 000019DC B10A                    	mov	cl, 10
  5131 000019DE BE[DF740000]            	mov	esi, free_mem_b_str
  5132 000019E3 E893000000              	call	bintdstr
  5133 000019E8 58                      	pop	eax
  5134 000019E9 B107                    	mov	cl, 7
  5135 000019EB BE[03750000]            	mov	esi, free_mem_p_str
  5136 000019F0 E886000000              	call	bintdstr
  5137                                  pmim:
  5138 000019F5 BE[89740000]            	mov	esi, msg_memory_info
  5139                                  	;
  5140 000019FA B407                    	mov	ah, 07h ; Black background, 
  5141                                  			; light gray forecolor
  5142                                  print_kmsg: ; 29/01/2016
  5143 000019FC 8825[F9780000]          	mov	[ccolor], ah
  5144                                  pkmsg_loop:
  5145 00001A02 AC                      	lodsb
  5146 00001A03 08C0                    	or	al, al
  5147 00001A05 7411                    	jz	short pkmsg_ok
  5148 00001A07 56                      	push	esi
  5149 00001A08 31DB                    	xor	ebx, ebx ; 0
  5150                                  			; Video page 0 (bl=0)
  5151 00001A0A 8A25[F9780000]          	mov	ah, [ccolor]
  5152 00001A10 E814FEFFFF              	call	WRITE_TTY
  5153 00001A15 5E                      	pop	esi
  5154 00001A16 EBEA                    	jmp	short pkmsg_loop
  5155                                  pkmsg_ok:
  5156 00001A18 C3                      	retn
  5157                                  
  5158                                  ; Convert binary number to hexadecimal string
  5159                                  ; 10/05/2015  
  5160                                  ; dsectpm.s (28/02/2015)
  5161                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  5162                                  ; 01/12/2014
  5163                                  ; 25/11/2014
  5164                                  ;
  5165                                  bytetohex:
  5166                                  	; INPUT ->
  5167                                  	; 	AL = byte (binary number)
  5168                                  	; OUTPUT ->
  5169                                  	;	AX = hexadecimal string
  5170                                  	;
  5171 00001A19 53                      	push	ebx
  5172 00001A1A 31DB                    	xor	ebx, ebx
  5173 00001A1C 88C3                    	mov	bl, al
  5174 00001A1E C0EB04                  	shr	bl, 4
  5175 00001A21 8A9B[6B1A0000]          	mov	bl, [ebx+hexchrs] 	 	
  5176 00001A27 86D8                    	xchg	bl, al
  5177 00001A29 80E30F                  	and	bl, 0Fh
  5178 00001A2C 8AA3[6B1A0000]          	mov	ah, [ebx+hexchrs] 
  5179 00001A32 5B                      	pop	ebx	
  5180 00001A33 C3                      	retn
  5181                                  
  5182                                  wordtohex:
  5183                                  	; INPUT ->
  5184                                  	; 	AX = word (binary number)
  5185                                  	; OUTPUT ->
  5186                                  	;	EAX = hexadecimal string
  5187                                  	;
  5188 00001A34 53                      	push	ebx
  5189 00001A35 31DB                    	xor	ebx, ebx
  5190 00001A37 86E0                    	xchg	ah, al
  5191 00001A39 6650                    	push	ax
  5192 00001A3B 88E3                    	mov	bl, ah
  5193 00001A3D C0EB04                  	shr	bl, 4
  5194 00001A40 8A83[6B1A0000]          	mov	al, [ebx+hexchrs] 	 	
  5195 00001A46 88E3                    	mov	bl, ah
  5196 00001A48 80E30F                  	and	bl, 0Fh
  5197 00001A4B 8AA3[6B1A0000]          	mov	ah, [ebx+hexchrs]
  5198 00001A51 C1E010                  	shl	eax, 16
  5199 00001A54 6658                    	pop	ax
  5200 00001A56 5B                      	pop	ebx
  5201 00001A57 EBC0                    	jmp	short bytetohex
  5202                                  	;mov	bl, al
  5203                                  	;shr	bl, 4
  5204                                  	;mov	bl, [ebx+hexchrs] 	 	
  5205                                  	;xchg	bl, al	 	
  5206                                  	;and	bl, 0Fh
  5207                                  	;mov	ah, [ebx+hexchrs] 
  5208                                  	;pop	ebx	
  5209                                  	;retn
  5210                                  
  5211                                  dwordtohex:
  5212                                  	; INPUT ->
  5213                                  	; 	EAX = dword (binary number)
  5214                                  	; OUTPUT ->
  5215                                  	;	EDX:EAX = hexadecimal string
  5216                                  	;
  5217 00001A59 50                      	push	eax
  5218 00001A5A C1E810                  	shr	eax, 16
  5219 00001A5D E8D2FFFFFF              	call	wordtohex
  5220 00001A62 89C2                    	mov	edx, eax
  5221 00001A64 58                      	pop	eax
  5222 00001A65 E8CAFFFFFF              	call	wordtohex
  5223 00001A6A C3                      	retn
  5224                                  
  5225                                  ; 10/05/2015
  5226                                  hex_digits:
  5227                                  hexchrs:
  5228 00001A6B 303132333435363738-     	db '0123456789ABCDEF'
  5229 00001A74 39414243444546     
  5230                                  
  5231                                  ; Convert binary number to decimal/numeric string
  5232                                  ; 06/11/2014
  5233                                  ; Temporary Code
  5234                                  ;
  5235                                  
  5236                                  bintdstr:
  5237                                  	; EAX = binary number
  5238                                  	; ESI = decimal/numeric string address
  5239                                  	; EBX = divisor (10)
  5240                                  	; ECX = string length (<=10)
  5241 00001A7B 01CE                    	add	esi, ecx
  5242                                  btdstr0:
  5243 00001A7D 4E                      	dec	esi
  5244 00001A7E 31D2                    	xor	edx, edx
  5245 00001A80 F7F3                    	div	ebx
  5246 00001A82 80C230                  	add	dl, 30h
  5247 00001A85 8816                    	mov	[esi], dl
  5248 00001A87 FEC9                    	dec	cl
  5249 00001A89 740C                    	jz	btdstr2
  5250 00001A8B 09C0                    	or	eax, eax
  5251 00001A8D 75EE                    	jnz	short btdstr0
  5252                                  btdstr1:
  5253 00001A8F 4E                      	dec	esi
  5254 00001A90 C60620                          mov     byte [esi], 20h ; blank space
  5255 00001A93 FEC9                    	dec	cl
  5256 00001A95 75F8                    	jnz	short btdstr1
  5257                                  btdstr2:
  5258 00001A97 C3                      	retn
  5259                                  
  5260                                  ; Calculate free memory pages on M.A.T.
  5261                                  ; 06/11/2014
  5262                                  ; Temporary Code
  5263                                  ;
  5264                                  
  5265                                  calc_free_mem:
  5266 00001A98 31D2                    	xor	edx, edx
  5267                                  	;xor	ecx, ecx
  5268 00001A9A 668B0D[E0780000]        	mov	cx, [mat_size] ; in pages
  5269 00001AA1 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  5270 00001AA4 BE00001000              	mov	esi, MEM_ALLOC_TBL
  5271                                  cfm0:
  5272 00001AA9 AD                      	lodsd
  5273 00001AAA 51                      	push	ecx
  5274 00001AAB B920000000              	mov	ecx, 32
  5275                                  cfm1:
  5276 00001AB0 D1E8                    	shr	eax, 1
  5277 00001AB2 7301                    	jnc	short cfm2
  5278 00001AB4 42                      	inc	edx
  5279                                  cfm2:
  5280 00001AB5 E2F9                    	loop	cfm1
  5281 00001AB7 59                      	pop	ecx
  5282 00001AB8 E2EF                    	loop	cfm0
  5283 00001ABA C3                      	retn
  5284                                  
  5285                                  %include 'diskio.s'  ; 07/03/2015
  5286                              <1> ; ****************************************************************************
  5287                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskio.s
  5288                              <1> ; ----------------------------------------------------------------------------
  5289                              <1> ; Last Update: 24/01/2016
  5290                              <1> ; ----------------------------------------------------------------------------
  5291                              <1> ; Beginning: 24/01/2016
  5292                              <1> ; ----------------------------------------------------------------------------
  5293                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
  5294                              <1> ; ----------------------------------------------------------------------------
  5295                              <1> ; Turkish Rational DOS
  5296                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
  5297                              <1> ;
  5298                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
  5299                              <1> ; diskio.inc (22/08/2015)
  5300                              <1> ;
  5301                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
  5302                              <1> ; ****************************************************************************
  5303                              <1> 
  5304                              <1> ; Retro UNIX 386 v1 Kernel - DISKIO.INC
  5305                              <1> ; Last Modification: 22/08/2015
  5306                              <1> ; 	(Initialized Disk Parameters Data is in 'DISKDATA.INC') 
  5307                              <1> ; 	(Uninitialized Disk Parameters Data is in 'DISKBSS.INC') 
  5308                              <1> 
  5309                              <1> ; DISK I/O SYSTEM - Erdogan Tan (Retro UNIX 386 v1 project)
  5310                              <1> 
  5311                              <1> ; ///////// DISK I/O SYSTEM ///////////////
  5312                              <1> 
  5313                              <1> ; 06/02/2015
  5314                              <1> diskette_io:
  5315 00001ABB 9C                  <1> 	pushfd
  5316 00001ABC 0E                  <1> 	push 	cs
  5317 00001ABD E809000000          <1> 	call 	DISKETTE_IO_1
  5318 00001AC2 C3                  <1> 	retn
  5319                              <1> 	
  5320                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
  5321                              <1> ;//////////////////////////////////////////////////////
  5322                              <1> 
  5323                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  5324                              <1> ; 20/02/2015
  5325                              <1> ; 06/02/2015 (unix386.s)
  5326                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
  5327                              <1> ;
  5328                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
  5329                              <1> ;
  5330                              <1> ; ADISK.EQU
  5331                              <1> 
  5332                              <1> ;----- Wait control constants 
  5333                              <1> 
  5334                              <1> ;amount of time to wait while RESET is active.
  5335                              <1> 
  5336                              <1> WAITCPU_RESET_ON	EQU	21		;Reset on must last at least 14us
  5337                              <1> 						;at 250 KBS xfer rate.
  5338                              <1> 						;see INTEL MCS, 1985, pg. 5-456
  5339                              <1> 
  5340                              <1> WAITCPU_FOR_STATUS	EQU	100		;allow 30 microseconds for
  5341                              <1> 						;status register to become valid
  5342                              <1> 						;before re-reading.
  5343                              <1> 
  5344                              <1> ;After sending a byte to NEC, status register may remain
  5345                              <1> ;incorrectly set for 24 us.
  5346                              <1> 
  5347                              <1> WAITCPU_RQM_LOW		EQU	24		;number of loops to check for
  5348                              <1> 						;RQM low.
  5349                              <1> 
  5350                              <1> ; COMMON.MAC
  5351                              <1> ;
  5352                              <1> ;	Timing macros
  5353                              <1> ;
  5354                              <1> 
  5355                              <1> %macro 		SIODELAY 0 			; SHORT IODELAY
  5356                              <1> 		jmp short $+2
  5357                              <1> %endmacro		
  5358                              <1> 
  5359                              <1> %macro		IODELAY  0			; NORMAL IODELAY
  5360                              <1> 		jmp short $+2
  5361                              <1> 		jmp short $+2
  5362                              <1> %endmacro
  5363                              <1> 
  5364                              <1> %macro		NEWIODELAY 0
  5365                              <1> 		out	0ebh,al
  5366                              <1> %endmacro 
  5367                              <1> 
  5368                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
  5369                              <1> ;;; WAIT_FOR_MEM
  5370                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
  5371                              <1> ;WAIT_FDU_INT_HI	equ	1
  5372                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
  5373                              <1> ;;; WAIT_FOR_PORT
  5374                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
  5375                              <1> ;WAIT_FDU_SEND_HI	equ	0
  5376                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
  5377                              <1> ;Time to wait while waiting for each byte of NEC results = .5
  5378                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  5379                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
  5380                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
  5381                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
  5382                              <1> ;;; WAIT_REFRESH
  5383                              <1> ;amount of time to wait for head settle, per unit in parameter
  5384                              <1> ;table = 1 ms.
  5385                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
  5386                              <1> 
  5387                              <1> 
  5388                              <1> ; //////////////// DISKETTE I/O ////////////////
  5389                              <1> 
  5390                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
  5391                              <1> 
  5392                              <1> ;----------------------------------------
  5393                              <1> ;	EQUATES USED BY POST AND BIOS	:
  5394                              <1> ;----------------------------------------
  5395                              <1> 
  5396                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  5397                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  5398                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  5399                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
  5400                              <1> 
  5401                              <1> ;----------------------------------------
  5402                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
  5403                              <1> ;-------------------------------------------------------------------------------
  5404                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
  5405                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
  5406                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
  5407                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
  5408                              <1> 
  5409                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
  5410                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
  5411                              <1> ;		EQU	011H		; - RESERVED			      ;C
  5412                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
  5413                              <1> ;		EQU	013H		; - RESERVED			      ;E
  5414                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
  5415                              <1> 
  5416                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
  5417                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
  5418                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
  5419                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
  5420                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
  5421                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
  5422                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
  5423                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
  5424                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
  5425                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
  5426                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
  5427                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
  5428                              <1> 
  5429                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
  5430                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
  5431                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
  5432                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
  5433                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
  5434                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
  5435                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
  5436                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
  5437                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
  5438                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
  5439                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
  5440                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
  5441                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
  5442                              <1> 
  5443                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
  5444                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
  5445                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
  5446                              <1> 
  5447                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
  5448                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
  5449                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
  5450                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
  5451                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
  5452                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
  5453                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
  5454                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
  5455                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
  5456                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
  5457                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
  5458                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
  5459                              <1> 
  5460                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
  5461                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
  5462                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
  5463                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
  5464                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
  5465                              <1> 
  5466                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
  5467                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
  5468                              <1> ;INTA00		EQU	020H		; 8259 PORT
  5469                              <1> INTA01		EQU	021H		; 8259 PORT
  5470                              <1> INTB00		EQU	0A0H		; 2ND 8259
  5471                              <1> INTB01		EQU	0A1H		;
  5472                              <1> 
  5473                              <1> ;-------------------------------------------------------------------------------
  5474                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
  5475                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
  5476                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
  5477                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
  5478                              <1> ;-------------------------------------------------------------------------------
  5479                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
  5480                              <1> 
  5481                              <1> ;-------------------------------------------------------------------------------
  5482                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
  5483                              <1> 
  5484                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
  5485                              <1> ; (unix386.s <-- dsectrm2.s)
  5486                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
  5487                              <1> 
  5488                              <1> ; 10/12/2014
  5489                              <1> ;
  5490                              <1> ;int40h:
  5491                              <1> ;	pushf
  5492                              <1> ;	push 	cs
  5493                              <1> ;	;cli
  5494                              <1> ;	call 	DISKETTE_IO_1
  5495                              <1> ;	retn
  5496                              <1> 
  5497                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
  5498                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  5499                              <1> ;
  5500                              <1> 
  5501                              <1> ;-- INT13H ---------------------------------------------------------------------
  5502                              <1> ; DISKETTE I/O
  5503                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
  5504                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
  5505                              <1> ; INPUT
  5506                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
  5507                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
  5508                              <1> ;		ON ALL DRIVES
  5509                              <1> ;------------------------------------------------------------------------------- 
  5510                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
  5511                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
  5512                              <1> ;-------------------------------------------------------------------------------
  5513                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
  5514                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5515                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
  5516                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
  5517                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
  5518                              <1> ;		320/360	320/360	    0-39
  5519                              <1> ;		320/360	1.2M	    0-39
  5520                              <1> ;		1.2M	1.2M	    0-79
  5521                              <1> ;		720K	720K	    0-79
  5522                              <1> ;		1.44M	1.44M	    0-79	
  5523                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
  5524                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
  5525                              <1> ;		320/360	320/360	     1-8/9
  5526                              <1> ;		320/360	1.2M	     1-8/9
  5527                              <1> ;		1.2M	1.2M	     1-15
  5528                              <1> ;		720K	720K	     1-9
  5529                              <1> ;		1.44M	1.44M	     1-18		
  5530                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
  5531                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
  5532                              <1> ;		320/360	320/360	        8/9
  5533                              <1> ;		320/360	1.2M	        8/9
  5534                              <1> ;		1.2M	1.2M		15
  5535                              <1> ;		720K	720K		9
  5536                              <1> ;		1.44M	1.44M		18
  5537                              <1> ;
  5538                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
  5539                              <1> ;
  5540                              <1> ;-------------------------------------------------------------------------------
  5541                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
  5542                              <1> ;-------------------------------------------------------------------------------
  5543                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
  5544                              <1> ;-------------------------------------------------------------------------------
  5545                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
  5546                              <1> ;-------------------------------------------------------------------------------
  5547                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
  5548                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
  5549                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
  5550                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
  5551                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
  5552                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
  5553                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
  5554                              <1> ;		READ/WRITE ACCESS.
  5555                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
  5556                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
  5557                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
  5558                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
  5559                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
  5560                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
  5561                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
  5562                              <1> ;
  5563                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
  5564                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
  5565                              <1> ;		---------------------------------------------
  5566                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
  5567                              <1> ;		---------------------------------------------
  5568                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
  5569                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
  5570                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
  5571                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
  5572                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
  5573                              <1> ;		---------------------------------------------
  5574                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
  5575                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
  5576                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
  5577                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
  5578                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
  5579                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
  5580                              <1> ;-------------------------------------------------------------------------------
  5581                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
  5582                              <1> ;	REGISTERS
  5583                              <1> ;	  INPUT
  5584                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5585                              <1> ;	  OUTPUT
  5586                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
  5587                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
  5588                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5589                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5590                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
  5591                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
  5592                              <1> ;	    (BH) - 0
  5593                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
  5594                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
  5595                              <1> ;	    (AX) - 0
  5596                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
  5597                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
  5598                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
  5599                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
  5600                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
  5601                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
  5602                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
  5603                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
  5604                              <1> ;-------------------------------------------------------------------------------
  5605                              <1> ;	(AH)= 15H  READ DASD TYPE
  5606                              <1> ;	OUTPUT REGISTERS
  5607                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
  5608                              <1> ;		00 - DRIVE NOT PRESENT	
  5609                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
  5610                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
  5611                              <1> ;		03 - RESERVED (FIXED DISK)
  5612                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5613                              <1> ;-------------------------------------------------------------------------------
  5614                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
  5615                              <1> ;	OUTPUT REGISTERS
  5616                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
  5617                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
  5618                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5619                              <1> ;-------------------------------------------------------------------------------
  5620                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
  5621                              <1> ;	INPUT REGISTERS
  5622                              <1> ;	(AL) -	00 - NOT USED	
  5623                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
  5624                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
  5625                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
  5626                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
  5627                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
  5628                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
  5629                              <1> ;-------------------------------------------------------------------------------
  5630                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
  5631                              <1> ;	INPUT REGISTERS
  5632                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
  5633                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5634                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5635                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
  5636                              <1> ;	OUTPUT REGISTERS:
  5637                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
  5638                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
  5639                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
  5640                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
  5641                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
  5642                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
  5643                              <1> ;-------------------------------------------------------------------------------
  5644                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
  5645                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
  5646                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
  5647                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
  5648                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
  5649                              <1> ;		CHANGE ERROR CODE
  5650                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
  5651                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
  5652                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
  5653                              <1> ;
  5654                              <1> ; DATA VARIABLE -- @DISK_POINTER
  5655                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
  5656                              <1> ;-------------------------------------------------------------------------------
  5657                              <1> ; OUTPUT FOR ALL FUNCTIONS
  5658                              <1> ;	AH = STATUS OF OPERATION
  5659                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
  5660                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
  5661                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
  5662                              <1> ;		TYPE AH=(15)).
  5663                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
  5664                              <1> ;	FOR READ/WRITE/VERIFY
  5665                              <1> ;		DS,BX,DX,CX PRESERVED
  5666                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
  5667                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
  5668                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
  5669                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
  5670                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
  5671                              <1> ;-------------------------------------------------------------------------------
  5672                              <1> ;
  5673                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
  5674                              <1> ;
  5675                              <1> ;   -----------------------------------------------------------------
  5676                              <1> ;   |       |       |       |       |       |       |       |       |
  5677                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
  5678                              <1> ;   |       |       |       |       |       |       |       |       |
  5679                              <1> ;   -----------------------------------------------------------------
  5680                              <1> ;	|	|	|	|	|	|	|	|
  5681                              <1> ;	|	|	|	|	|	-----------------
  5682                              <1> ;	|	|	|	|	|		|
  5683                              <1> ;	|	|	|	|    RESERVED		|
  5684                              <1> ;	|	|	|	|		  PRESENT STATE
  5685                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
  5686                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
  5687                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
  5688                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
  5689                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
  5690                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
  5691                              <1> ;	|	|	|	|	110: RESERVED
  5692                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
  5693                              <1> ;	|	|	|	|
  5694                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
  5695                              <1> ;	|	|	|
  5696                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
  5697                              <1> ;	|	|			DRIVE)
  5698                              <1> ;	|	|
  5699                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
  5700                              <1> ;
  5701                              <1> ;						00: 500 KBS
  5702                              <1> ;						01: 300 KBS
  5703                              <1> ;						10: 250 KBS
  5704                              <1> ;						11: RESERVED
  5705                              <1> ;
  5706                              <1> ;
  5707                              <1> ;-------------------------------------------------------------------------------
  5708                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
  5709                              <1> ;-------------------------------------------------------------------------------
  5710                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
  5711                              <1> ;-------------------------------------------------------------------------------
  5712                              <1> 
  5713                              <1> struc MD
  5714 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  5715 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  5716 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  5717 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
  5718 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
  5719 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
  5720 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
  5721 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
  5722 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
  5723 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
  5724 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
  5725 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
  5726 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
  5727                              <1> endstruc
  5728                              <1> 
  5729                              <1> BIT7OFF	EQU	7FH
  5730                              <1> BIT7ON	EQU	80H
  5731                              <1> 
  5732                              <1> ;;int13h: ; 16/02/2015
  5733                              <1> ;; 16/02/2015 - 21/02/2015
  5734                              <1> int40h:
  5735 00001AC3 9C                  <1> 	pushfd
  5736 00001AC4 0E                  <1> 	push 	cs
  5737 00001AC5 E801000000          <1> 	call 	DISKETTE_IO_1
  5738 00001ACA C3                  <1> 	retn	
  5739                              <1> 
  5740                              <1> DISKETTE_IO_1:
  5741                              <1> 
  5742 00001ACB FB                  <1> 	STI				; INTERRUPTS BACK ON
  5743 00001ACC 55                  <1> 	PUSH	eBP			; USER REGISTER
  5744 00001ACD 57                  <1> 	PUSH	eDI			; USER REGISTER
  5745 00001ACE 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
  5746 00001ACF 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
  5747 00001AD0 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
  5748 00001AD1 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
  5749                              <1> 					; [BP]   = SECTOR #
  5750                              <1> 					; [BP+1] = TRACK #
  5751                              <1> 					; [BP+2] = BUFFER OFFSET
  5752                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
  5753                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
  5754                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
  5755                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
  5756                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
  5757                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
  5758                              <1> 					; BH/[BP+3] = 0
  5759                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
  5760                              <1> 					; DH/[BP+5] = MAX HEAD #
  5761                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
  5762 00001AD3 06                  <1> 	push	es ; 06/02/2015	
  5763 00001AD4 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
  5764 00001AD5 56                  <1> 	PUSH	eSI			; USER REGISTERS
  5765                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
  5766                              <1> 	;mov	cx, cs
  5767                              <1> 	;mov	ds, cx
  5768 00001AD6 66B91000            <1> 	mov	cx, KDATA
  5769 00001ADA 8ED9                <1>         mov     ds, cx
  5770 00001ADC 8EC1                <1>         mov     es, cx
  5771                              <1> 
  5772                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
  5773 00001ADE 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4 ; 18/02/2015
  5774 00001AE1 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
  5775 00001AE3 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5776                              <1> OK_FUNC:
  5777 00001AE5 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
  5778 00001AE8 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
  5779 00001AEA 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
  5780 00001AED 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
  5781 00001AEF 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
  5782 00001AF2 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
  5783 00001AF4 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5784                              <1> OK_DRV:
  5785 00001AF6 31C9                <1> 	xor	ecx, ecx
  5786                              <1> 	;mov	esi, ecx ; 08/02/2015
  5787 00001AF8 89CF                <1> 	mov	edi, ecx ; 08/02/2015
  5788 00001AFA 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
  5789                              <1> 	;XOR	CH,CH			; CX = FUNCTION
  5790                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
  5791 00001AFC C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
  5792 00001AFF BB[371B0000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
  5793 00001B04 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
  5794 00001B06 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
  5795 00001B08 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
  5796 00001B0A 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
  5797 00001B0D 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
  5798                              <1> 	;
  5799                              <1> 	; 11/12/2014
  5800 00001B10 8815[71730000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
  5801                              <1> 	;
  5802 00001B16 8A25[54790000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
  5803 00001B1C C605[54790000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
  5804                              <1> 
  5805                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
  5806                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
  5807                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
  5808                              <1> ;
  5809                              <1> ;		DI	: DRIVE #
  5810                              <1> ;		SI-HI	: HEAD #
  5811                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
  5812                              <1> ;		ES	: BUFFER SEGMENT
  5813                              <1> ;		[BP]	: SECTOR #
  5814                              <1> ;		[BP+1]	: TRACK #
  5815                              <1> ;		[BP+2]	: BUFFER OFFSET
  5816                              <1> ;
  5817                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
  5818                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
  5819                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
  5820                              <1> ;	SPECIFIC ERROR CODE.
  5821                              <1> ;
  5822                              <1> 					; (AH) = @DSKETTE_STATUS
  5823 00001B23 FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
  5824 00001B25 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
  5825 00001B26 1F                  <1> 	POP	DS
  5826 00001B27 07                  <1> 	pop	es	; 06/02/2015
  5827 00001B28 59                  <1> 	POP	eCX
  5828 00001B29 5B                  <1> 	POP	eBX
  5829 00001B2A 5A                  <1> 	POP	eDX
  5830 00001B2B 5F                  <1> 	POP	eDI
  5831 00001B2C 89E5                <1> 	MOV	eBP, eSP
  5832 00001B2E 50                  <1> 	PUSH	eAX
  5833 00001B2F 9C                  <1> 	PUSHFd
  5834 00001B30 58                  <1> 	POP	eAX
  5835                              <1> 	;MOV	[BP+6], AX
  5836 00001B31 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
  5837 00001B34 58                  <1> 	POP	eAX
  5838 00001B35 5D                  <1> 	POP	eBP
  5839 00001B36 CF                  <1> 	IRETd
  5840                              <1> 
  5841                              <1> ;-------------------------------------------------------------------------------
  5842                              <1> ; DW --> dd (06/02/2015)
  5843 00001B37 [9B1B0000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
  5844 00001B3B [141C0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
  5845 00001B3F [251C0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
  5846 00001B43 [361C0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
  5847 00001B47 [471C0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
  5848 00001B4B [581C0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
  5849 00001B4F [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
  5850 00001B53 [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
  5851 00001B57 [EA1C0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
  5852 00001B5B [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
  5853 00001B5F [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
  5854 00001B63 [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
  5855 00001B67 [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
  5856 00001B6B [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
  5857 00001B6F [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
  5858 00001B73 [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
  5859 00001B77 [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
  5860 00001B7B [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
  5861 00001B7F [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
  5862 00001B83 [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
  5863 00001B87 [DD1C0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
  5864 00001B8B [AB1D0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
  5865 00001B8F [D61D0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
  5866 00001B93 [101E0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
  5867 00001B97 [931E0000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
  5868                              <1> FNC_TAE EQU     $                       ; END
  5869                              <1> 
  5870                              <1> ;-------------------------------------------------------------------------------
  5871                              <1> ; DISK_RESET	(AH = 00H)	
  5872                              <1> ;		RESET THE DISKETTE SYSTEM.
  5873                              <1> ;
  5874                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5875                              <1> ;-------------------------------------------------------------------------------
  5876                              <1> DSK_RESET:
  5877 00001B9B 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
  5878 00001B9F FA                  <1> 	CLI				; NO INTERRUPTS
  5879 00001BA0 A0[52790000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  5880 00001BA5 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
  5881 00001BA7 C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
  5882                              <1> 					; DRIVE SELECT TO LOW NIBBLE
  5883 00001BAA 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
  5884 00001BAC EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5885 00001BAD C605[51790000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  5886                              <1> 	;JMP	$+2			; WAIT FOR I/O
  5887                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
  5888                              <1> 					;      PULSE WIDTH)
  5889                              <1> 	; 19/12/2014
  5890                              <1> 	NEWIODELAY
  5891 00001BB4 E6EB                <2>  out 0ebh,al
  5892                              <1> 
  5893                              <1> 	; 17/12/2014 
  5894                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
  5895 00001BB6 B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
  5896                              <1> wdw1:
  5897                              <1> 	NEWIODELAY   ; 27/02/2015
  5898 00001BBB E6EB                <2>  out 0ebh,al
  5899 00001BBD E2FC                <1> 	loop	wdw1
  5900                              <1> 	;
  5901 00001BBF 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
  5902 00001BC1 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5903                              <1> 	; 16/12/2014
  5904                              <1> 	IODELAY
  5905 00001BC2 EB00                <2>  jmp short $+2
  5906 00001BC4 EB00                <2>  jmp short $+2
  5907                              <1> 	;
  5908                              <1> 	;STI				; ENABLE THE INTERRUPTS
  5909 00001BC6 E8240C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  5910 00001BCB 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
  5911 00001BCD 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
  5912                              <1> NXT_DRV:
  5913 00001BD1 6651                <1> 	PUSH	CX			; SAVE FOR CALL
  5914 00001BD3 B8[091C0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
  5915 00001BD8 50                  <1> 	PUSH	eAX			; "
  5916 00001BD9 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  5917 00001BDB E8020B0000          <1> 	CALL	NEC_OUTPUT
  5918 00001BE0 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  5919 00001BE1 E8390C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  5920 00001BE6 6659                <1> 	POP	CX			; RESTORE AFTER CALL
  5921 00001BE8 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
  5922 00001BEA 3A0D[55790000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
  5923 00001BF0 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
  5924 00001BF2 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
  5925 00001BF4 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
  5926 00001BF7 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
  5927                              <1> 	;
  5928 00001BF9 E852030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5929                              <1> RESBAC:
  5930 00001BFE E805090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5931 00001C03 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5932 00001C06 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5933 00001C08 C3                  <1> 	RETn		
  5934                              <1> DR_POP_ERR:
  5935 00001C09 6659                <1> 	POP	CX			; CLEAR STACK
  5936                              <1> DR_ERR:
  5937 00001C0B 800D[54790000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
  5938 00001C12 EBEA                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
  5939                              <1> 
  5940                              <1> ;-------------------------------------------------------------------------------
  5941                              <1> ; DISK_STATUS	(AH = 01H)
  5942                              <1> ;	DISKETTE STATUS.
  5943                              <1> ;
  5944                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
  5945                              <1> ;
  5946                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
  5947                              <1> ;-------------------------------------------------------------------------------
  5948                              <1> DSK_STATUS:
  5949 00001C14 8825[54790000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
  5950 00001C1A E8E9080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5951 00001C1F 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  5952 00001C22 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5953 00001C24 C3                  <1> 	RETn		
  5954                              <1> 
  5955                              <1> ;-------------------------------------------------------------------------------
  5956                              <1> ; DISK_READ	(AH = 02H)	
  5957                              <1> ;	DISKETTE READ.
  5958                              <1> ;
  5959                              <1> ; ON ENTRY:	DI	: DRIVE #
  5960                              <1> ;		SI-HI	: HEAD #
  5961                              <1> ;		SI-LOW	: # OF SECTORS
  5962                              <1> ;		ES	: BUFFER SEGMENT
  5963                              <1> ;		[BP]	: SECTOR #
  5964                              <1> ;		[BP+1]	: TRACK #
  5965                              <1> ;		[BP+2]	: BUFFER OFFSET
  5966                              <1> ;
  5967                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5968                              <1> ;-------------------------------------------------------------------------------
  5969                              <1> 
  5970                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5971                              <1> 
  5972                              <1> DSK_READ:
  5973 00001C25 8025[52790000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5974 00001C2C 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
  5975 00001C30 E825040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5976 00001C35 C3                  <1> 	RETn
  5977                              <1> 
  5978                              <1> ;-------------------------------------------------------------------------------
  5979                              <1> ; DISK_WRITE	(AH = 03H)
  5980                              <1> ;	DISKETTE WRITE.
  5981                              <1> ;
  5982                              <1> ; ON ENTRY:	DI	: DRIVE #
  5983                              <1> ;		SI-HI	: HEAD #
  5984                              <1> ;		SI-LOW	: # OF SECTORS
  5985                              <1> ;		ES	: BUFFER SEGMENT
  5986                              <1> ;		[BP]	: SECTOR #
  5987                              <1> ;		[BP+1]	: TRACK #
  5988                              <1> ;		[BP+2]	: BUFFER OFFSET
  5989                              <1> ;
  5990                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5991                              <1> ;-------------------------------------------------------------------------------
  5992                              <1> 
  5993                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5994                              <1> 
  5995                              <1> DSK_WRITE:
  5996 00001C36 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
  5997 00001C3A 800D[52790000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
  5998 00001C41 E814040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5999 00001C46 C3                  <1> 	RETn
  6000                              <1> 
  6001                              <1> ;-------------------------------------------------------------------------------
  6002                              <1> ; DISK_VERF	(AH = 04H)
  6003                              <1> ;	DISKETTE VERIFY.
  6004                              <1> ;
  6005                              <1> ; ON ENTRY:	DI	: DRIVE #
  6006                              <1> ;		SI-HI	: HEAD #
  6007                              <1> ;		SI-LOW	: # OF SECTORS
  6008                              <1> ;		ES	: BUFFER SEGMENT
  6009                              <1> ;		[BP]	: SECTOR #
  6010                              <1> ;		[BP+1]	: TRACK #
  6011                              <1> ;		[BP+2]	: BUFFER OFFSET
  6012                              <1> ;
  6013                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6014                              <1> ;-------------------------------------------------------------------------------
  6015                              <1> DSK_VERF:
  6016 00001C47 8025[52790000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  6017 00001C4E 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
  6018 00001C52 E803040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  6019 00001C57 C3                  <1> 	RETn
  6020                              <1> 
  6021                              <1> ;-------------------------------------------------------------------------------
  6022                              <1> ; DISK_FORMAT	(AH = 05H)
  6023                              <1> ;	DISKETTE FORMAT.
  6024                              <1> ;
  6025                              <1> ; ON ENTRY:	DI	: DRIVE #
  6026                              <1> ;		SI-HI	: HEAD #
  6027                              <1> ;		SI-LOW	: # OF SECTORS
  6028                              <1> ;		ES	: BUFFER SEGMENT
  6029                              <1> ;		[BP]	: SECTOR #
  6030                              <1> ;		[BP+1]	: TRACK #
  6031                              <1> ;		[BP+2]	: BUFFER OFFSET
  6032                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
  6033                              <1> ;
  6034                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6035                              <1> ;-------------------------------------------------------------------------------
  6036                              <1> DSK_FORMAT:
  6037 00001C58 E83C030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6038 00001C5D E838050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
  6039 00001C62 800D[52790000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
  6040 00001C69 E880050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
  6041 00001C6E 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
  6042 00001C70 E8DB020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  6043 00001C75 E8E6050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
  6044 00001C7A 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
  6045 00001C7C E8BD050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
  6046                              <1> FM_WR:
  6047 00001C81 E872060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
  6048 00001C86 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
  6049 00001C88 B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
  6050 00001C8A E8CF060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
  6051 00001C8F 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
  6052 00001C91 B8[CD1C0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
  6053 00001C96 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6054 00001C97 B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
  6055 00001C99 E83E090000          <1> 	CALL	GET_PARM
  6056 00001C9E E83F0A0000          <1> 	CALL	NEC_OUTPUT
  6057 00001CA3 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
  6058 00001CA5 E832090000          <1> 	CALL	GET_PARM
  6059 00001CAA E8330A0000          <1> 	CALL	NEC_OUTPUT
  6060 00001CAF B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
  6061 00001CB1 E826090000          <1> 	CALL	GET_PARM
  6062 00001CB6 E8270A0000          <1> 	CALL	NEC_OUTPUT
  6063 00001CBB B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
  6064 00001CBD E81A090000          <1> 	CALL	GET_PARM
  6065 00001CC2 E81B0A0000          <1> 	CALL	NEC_OUTPUT
  6066 00001CC7 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  6067 00001CC8 E80F070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
  6068                              <1> FM_DON:
  6069 00001CCD E8F8020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6070 00001CD2 E831080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6071 00001CD7 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  6072 00001CDA 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  6073 00001CDC C3                  <1> 	RETn
  6074                              <1> 
  6075                              <1> ;-------------------------------------------------------------------------------
  6076                              <1> ; FNC_ERR
  6077                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
  6078                              <1> ;	SET BAD COMMAND IN STATUS.
  6079                              <1> ;
  6080                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6081                              <1> ;-------------------------------------------------------------------------------
  6082                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
  6083 00001CDD 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
  6084 00001CE0 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  6085 00001CE2 8825[54790000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
  6086 00001CE8 F9                  <1> 	STC				; SET CARRY INDICATING ERROR
  6087 00001CE9 C3                  <1> 	RETn
  6088                              <1> 
  6089                              <1> ;-------------------------------------------------------------------------------
  6090                              <1> ; DISK_PARMS	(AH = 08H)	
  6091                              <1> ;	READ DRIVE PARAMETERS.
  6092                              <1> ;
  6093                              <1> ; ON ENTRY:	DI : DRIVE #
  6094                              <1> ;
  6095                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
  6096                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
  6097                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
  6098                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
  6099                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
  6100                              <1> ;		BH/[BP+3] = 0
  6101                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
  6102                              <1> ;		DH/[BP+5] = MAX HEAD #
  6103                              <1> ;		DI/[BP+6] = OFFSET TO DISK_BASE
  6104                              <1> ;		ES        = SEGMENT OF DISK_BASE
  6105                              <1> ;		AX        = 0
  6106                              <1> ;
  6107                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
  6108                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
  6109                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
  6110                              <1> ;		       CALLER.
  6111                              <1> ;-------------------------------------------------------------------------------
  6112                              <1> DSK_PARMS:
  6113 00001CEA E8AA020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  6114                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
  6115 00001CEF 29D2                <1> 	sub     edx, edx ; 20/02/2015
  6116 00001CF1 895504              <1>         mov	[ebp+4], edx ; 20/02/2015
  6117                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
  6118                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
  6119                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
  6120                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
  6121                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
  6122                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
  6123                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
  6124                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
  6125                              <1> 	;sub	edx, edx
  6126 00001CF4 66A1[AE750000]      <1> 	mov     ax, [fd0_type]
  6127 00001CFA 6621C0              <1> 	and     ax, ax
  6128 00001CFD 7474                <1> 	jz      short NON_DRV
  6129 00001CFF FEC2                <1> 	inc     dl
  6130 00001D01 20E4                <1> 	and     ah, ah
  6131 00001D03 7402                <1> 	jz      short STO_DL
  6132 00001D05 FEC2                <1> 	inc     dl
  6133                              <1> STO_DL:
  6134                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
  6135 00001D07 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
  6136 00001D0A 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
  6137 00001D0E 7766                <1> 	JA	short NON_DRV1		; DRIVE INVALID
  6138                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
  6139 00001D10 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
  6140 00001D14 E8BA080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  6141                              <1> 	;;20/02/2015
  6142                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
  6143                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
  6144 00001D19 7412                <1> 	JZ	short CHK_EST		; JUMP IF SO
  6145 00001D1B E805020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  6146 00001D20 720B                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
  6147                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
  6148 00001D22 884504              <1>         mov	[ebp+4], al ; 06/02/2015
  6149 00001D25 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
  6150 00001D28 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
  6151 00001D2B EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
  6152                              <1> CHK_EST:
  6153 00001D2D 8AA7[61790000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
  6154 00001D33 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
  6155 00001D36 743E                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
  6156                              <1> USE_EST:
  6157 00001D38 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
  6158 00001D3B 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  6159 00001D3E 7557                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
  6160                              <1> 
  6161                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
  6162                              <1> 
  6163 00001D40 B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
  6164 00001D42 E8DE010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  6165 00001D47 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  6166 00001D4A 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  6167 00001D4D F687[61790000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
  6168 00001D54 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
  6169                              <1> 
  6170                              <1> ;-----	IT IS 1.44 MB DRIVE
  6171                              <1> 
  6172                              <1> PARM144:
  6173 00001D56 B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
  6174 00001D58 E8C8010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  6175 00001D5D 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  6176 00001D60 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  6177                              <1> STO_CX:
  6178 00001D63 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
  6179                              <1> ES_DI:
  6180                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
  6181 00001D66 895D0C              <1> 	mov	[ebp+12], ebx ; 06/02/2015
  6182                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
  6183                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  6184                              <1> DP_OUT:
  6185 00001D69 E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6186 00001D6E 6631C0              <1> 	XOR	AX,AX			; CLEAR
  6187 00001D71 F8                  <1> 	CLC
  6188 00001D72 C3                  <1> 	RETn
  6189                              <1> 
  6190                              <1> ;-----	NO DRIYE PRESENT HANDLER
  6191                              <1> 
  6192                              <1> NON_DRV:
  6193                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
  6194 00001D73 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
  6195                              <1> NON_DRV1:
  6196 00001D76 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
  6197 00001D7B 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
  6198                              <1> 
  6199                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
  6200                              <1> 	
  6201 00001D7D E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
  6202 00001D82 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
  6203 00001D85 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  6204 00001D87 F9                  <1> 	STC
  6205 00001D88 C3                  <1> 	RETn
  6206                              <1> 
  6207                              <1> NON_DRV2:
  6208                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
  6209 00001D89 31C0                <1> 	xor	eax, eax	
  6210 00001D8B 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
  6211                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
  6212 00001D8F 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
  6213                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
  6214 00001D92 89450C              <1> 	mov	[ebp+12], eax
  6215                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  6216 00001D95 EBD2                <1> 	JMP	SHORT DP_OUT
  6217                              <1> 
  6218                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
  6219                              <1> 
  6220                              <1> USE_EST2:
  6221 00001D97 B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
  6222 00001D99 E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  6223 00001D9E 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  6224 00001DA1 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  6225 00001DA4 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  6226 00001DA7 74BA                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
  6227 00001DA9 EBAB                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
  6228                              <1> 
  6229                              <1> ;-------------------------------------------------------------------------------
  6230                              <1> ; DISK_TYPE (AH = 15H)	
  6231                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
  6232                              <1> ;
  6233                              <1> ;  ON ENTRY:	DI = DRIVE #
  6234                              <1> ;
  6235                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
  6236                              <1> ;-------------------------------------------------------------------------------
  6237                              <1> DSK_TYPE:
  6238 00001DAB E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6239 00001DB0 8A87[61790000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
  6240 00001DB6 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
  6241 00001DB8 7418                <1> 	JZ	short NO_DRV
  6242 00001DBA B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
  6243 00001DBC A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
  6244 00001DBE 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
  6245 00001DC0 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
  6246                              <1> DT_BACK:
  6247 00001DC2 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
  6248 00001DC4 E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6249 00001DC9 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
  6250 00001DCB F8                  <1> 	CLC				; NO ERROR
  6251 00001DCC 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  6252 00001DCF 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  6253 00001DD1 C3                  <1> 	RETn
  6254                              <1> NO_DRV:	
  6255 00001DD2 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
  6256 00001DD4 EBEC                <1> 	JMP	SHORT DT_BACK
  6257                              <1> 
  6258                              <1> ;-------------------------------------------------------------------------------
  6259                              <1> ; DISK_CHANGE	(AH = 16H)
  6260                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
  6261                              <1> ;
  6262                              <1> ; ON ENTRY:	DI = DRIVE #
  6263                              <1> ;
  6264                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
  6265                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
  6266                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
  6267                              <1> ;-------------------------------------------------------------------------------
  6268                              <1> DSK_CHANGE:
  6269 00001DD6 E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6270 00001DDB 8A87[61790000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  6271 00001DE1 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  6272 00001DE3 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  6273 00001DE5 A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  6274 00001DE7 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  6275                              <1> DC0:
  6276 00001DE9 E88C0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  6277 00001DEE 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  6278                              <1> 
  6279 00001DF0 C605[54790000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  6280                              <1> 
  6281 00001DF7 E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6282 00001DFC E807070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6283 00001E01 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  6284 00001E04 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  6285 00001E06 C3                  <1> 	RETn
  6286                              <1> DC_NON:
  6287 00001E07 800D[54790000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  6288 00001E0E EBE7                <1> 	JMP	SHORT FINIS
  6289                              <1> 
  6290                              <1> ;-------------------------------------------------------------------------------
  6291                              <1> ; FORMAT_SET	(AH = 17H)
  6292                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  6293                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  6294                              <1> ;
  6295                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  6296                              <1> ;		DI     = DRIVE #
  6297                              <1> ;
  6298                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  6299                              <1> ;		AH = @DSKETTE_STATUS
  6300                              <1> ;		CY = 1 IF ERROR
  6301                              <1> ;-------------------------------------------------------------------------------
  6302                              <1> FORMAT_SET:
  6303 00001E10 E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6304 00001E15 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  6305 00001E17 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  6306 00001E1A 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  6307 00001E1C 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  6308 00001E1F 80A7[61790000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  6309 00001E26 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  6310 00001E28 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  6311 00001E2A 808F[61790000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  6312 00001E31 EB48                <1> 	JMP	SHORT S0
  6313                              <1> 
  6314                              <1> NOT_320:
  6315 00001E33 E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  6316 00001E38 803D[54790000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  6317 00001E3F 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  6318                              <1> S3:
  6319 00001E41 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  6320 00001E43 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  6321 00001E45 808F[61790000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  6322 00001E4C EB2D                <1> 	JMP	SHORT S0
  6323                              <1> 
  6324                              <1> NOT_320_12:
  6325 00001E4E 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  6326 00001E50 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  6327 00001E52 808F[61790000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  6328 00001E59 EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  6329                              <1> 
  6330                              <1> NOT_12:	
  6331 00001E5B 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  6332 00001E5D 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  6333                              <1> 
  6334 00001E5F F687[61790000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  6335 00001E66 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  6336 00001E68 B050                <1> 	MOV	AL,MED_DET+RATE_300
  6337 00001E6A F687[61790000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  6338 00001E71 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  6339                              <1> 
  6340                              <1> ASSUME:
  6341 00001E73 B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  6342                              <1> 
  6343                              <1> OR_IT_IN:
  6344 00001E75 0887[61790000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  6345                              <1> S0:
  6346 00001E7B E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6347 00001E80 E883060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6348 00001E85 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  6349 00001E87 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  6350 00001E89 C3                  <1> 	RETn
  6351                              <1> 
  6352                              <1> FS_ERR:
  6353 00001E8A C605[54790000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  6354 00001E91 EBE8                <1> 	JMP	SHORT S0
  6355                              <1> 
  6356                              <1> ;-------------------------------------------------------------------------------
  6357                              <1> ; SET_MEDIA	(AH = 18H)
  6358                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  6359                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  6360                              <1> ;
  6361                              <1> ; ON ENTRY:
  6362                              <1> ;	[BP]	= SECTOR PER TRACK
  6363                              <1> ;	[BP+1]	= TRACK #
  6364                              <1> ;	DI	= DRIVE #
  6365                              <1> ;
  6366                              <1> ; ON EXIT:
  6367                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  6368                              <1> ;	IF NO ERROR:
  6369                              <1> ;		AH = 0
  6370                              <1> ;		CY = 0
  6371                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  6372                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  6373                              <1> ;	IF ERROR:	
  6374                              <1> ;		AH = @DSKETTE_STATUS
  6375                              <1> ;		CY = 1
  6376                              <1> ;-------------------------------------------------------------------------------
  6377                              <1> SET_MEDIA:
  6378 00001E93 E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6379 00001E98 F687[61790000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  6380 00001E9F 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  6381 00001EA1 E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  6382 00001EA6 803D[54790000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  6383 00001EAD 746B                <1> 	JE	short SM_RTN
  6384 00001EAF C605[54790000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  6385                              <1> SM_CMOS:
  6386 00001EB6 E818070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6387                              <1> 	;;20/02/2015
  6388                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  6389                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  6390 00001EBB 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  6391 00001EBD E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  6392 00001EC2 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  6393 00001EC4 57                  <1> 	PUSH	eDI			; SAVE REG.
  6394 00001EC5 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  6395 00001EC7 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6396                              <1> DR_SEARCH:
  6397 00001ECC 8AA3[FC720000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  6398 00001ED2 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  6399 00001ED5 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  6400 00001ED7 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  6401                              <1> DR_FND:
  6402 00001ED9 8BBB[FD720000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  6403                              <1> MD_SEARCH:
  6404 00001EDF 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  6405 00001EE2 386500              <1> 	CMP	[eBP],AH		; MATCH?
  6406 00001EE5 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  6407 00001EE7 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  6408 00001EEA 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  6409 00001EED 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  6410                              <1> NXT_MD:
  6411                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6412 00001EEF 83C305              <1>         add	ebx, 5 ; 18/02/2015
  6413 00001EF2 E2D8                <1> 	LOOP    DR_SEARCH
  6414 00001EF4 5F                  <1> 	POP	eDI			; RESTORE REG.
  6415                              <1> MD_NOT_FND:
  6416 00001EF5 C605[54790000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  6417 00001EFC EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  6418                              <1> MD_FND:
  6419 00001EFE 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  6420 00001F01 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  6421 00001F03 7502                <1> 	JNE	short MD_SET
  6422 00001F05 0C20                <1> 	OR	AL,DBL_STEP
  6423                              <1> MD_SET:
  6424                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  6425 00001F07 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  6426 00001F0A 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  6427 00001F0C 5F                  <1> 	POP	eDI
  6428 00001F0D 80A7[61790000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  6429 00001F14 0887[61790000]      <1> 	OR	[DSK_STATE+eDI], AL
  6430                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  6431                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  6432                              <1> SM_RTN:
  6433 00001F1A E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6434 00001F1F E8E4050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6435 00001F24 C3                  <1> 	RETn
  6436                              <1> 
  6437                              <1> ;----------------------------------------------------------------
  6438                              <1> ; DR_TYPE_CHECK							:
  6439                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  6440                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  6441                              <1> ; ON ENTRY:							:
  6442                              <1> ;	AL = DRIVE TYPE						:
  6443                              <1> ; ON EXIT:							:
  6444                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  6445                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  6446                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  6447                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  6448                              <1> ; REGISTERS ALTERED: eBX						:
  6449                              <1> ;----------------------------------------------------------------		
  6450                              <1> DR_TYPE_CHECK:
  6451 00001F25 6650                <1> 	PUSH	AX			
  6452 00001F27 51                  <1> 	PUSH	eCX
  6453 00001F28 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6454 00001F2A B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6455                              <1> TYPE_CHK:	
  6456 00001F2F 8AA3[FC720000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  6457 00001F35 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6458 00001F37 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  6459                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6460 00001F39 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  6461 00001F3C E2F1                <1> 	LOOP    TYPE_CHK
  6462                              <1> 	;
  6463 00001F3E BB[5B730000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  6464                              <1> 					; Default for GET_PARM (11/12/2014)
  6465                              <1> 	;
  6466 00001F43 F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  6467 00001F44 EB06                <1> 	JMP	SHORT TYPE_RTN
  6468                              <1> DR_TYPE_VALID:
  6469 00001F46 8B9B[FD720000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  6470                              <1> TYPE_RTN:
  6471 00001F4C 59                  <1> 	POP	eCX
  6472 00001F4D 6658                <1> 	POP	AX
  6473 00001F4F C3                  <1> 	RETn	
  6474                              <1> 		
  6475                              <1> ;----------------------------------------------------------------
  6476                              <1> ; SEND_SPEC							:
  6477                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6478                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  6479                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  6480                              <1> ; ON EXIT:	NONE						:	
  6481                              <1> ; REGISTERS ALTERED: CX, DX					:
  6482                              <1> ;----------------------------------------------------------------		
  6483                              <1> SEND_SPEC:
  6484 00001F50 50                  <1> 	PUSH	eAX			; SAVE AX
  6485 00001F51 B8[771F0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  6486 00001F56 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6487 00001F57 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6488 00001F59 E884070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6489 00001F5E 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  6490 00001F60 E877060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6491 00001F65 E878070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6492 00001F6A B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  6493 00001F6C E86B060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6494 00001F71 E86C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6495 00001F76 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6496                              <1> SPECBAC:
  6497 00001F77 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6498 00001F78 C3                  <1> 	RETn
  6499                              <1> 
  6500                              <1> ;----------------------------------------------------------------
  6501                              <1> ; SEND_SPEC_MD							:
  6502                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6503                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  6504                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  6505                              <1> ; ON EXIT:	NONE						:	
  6506                              <1> ; REGISTERS ALTERED: AX						:
  6507                              <1> ;----------------------------------------------------------------		
  6508                              <1> SEND_SPEC_MD:
  6509 00001F79 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  6510 00001F7A B8[971F0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  6511 00001F7F 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6512 00001F80 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6513 00001F82 E85B070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6514 00001F87 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  6515 00001F89 E854070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6516 00001F8E 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  6517 00001F91 E84C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6518 00001F96 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6519                              <1> SPEC_ESBAC:
  6520 00001F97 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6521 00001F98 C3                  <1> 	RETn
  6522                              <1> 
  6523                              <1> ;-------------------------------------------------------------------------------
  6524                              <1> ; XLAT_NEW  
  6525                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  6526                              <1> ;	MODE TO NEW ARCHITECTURE.
  6527                              <1> ;
  6528                              <1> ; ON ENTRY:	DI = DRIVE #
  6529                              <1> ;-------------------------------------------------------------------------------
  6530                              <1> XLAT_NEW:
  6531 00001F99 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  6532 00001F9C 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  6533 00001F9E 80BF[61790000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  6534 00001FA5 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  6535 00001FA7 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  6536 00001FAA C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  6537 00001FAD A0[60790000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  6538 00001FB2 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  6539 00001FB4 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  6540 00001FB6 80A7[61790000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  6541 00001FBD 0887[61790000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  6542                              <1> XN_OUT:
  6543 00001FC3 C3                  <1> 	RETn
  6544                              <1> DO_DET:
  6545 00001FC4 E8BE080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  6546 00001FC9 C3                  <1> 	RETn
  6547                              <1> 
  6548                              <1> ;-------------------------------------------------------------------------------
  6549                              <1> ; XLAT_OLD 
  6550                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  6551                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  6552                              <1> ;
  6553                              <1> ; ON ENTRY:	DI = DRIVE
  6554                              <1> ;-------------------------------------------------------------------------------
  6555                              <1> XLAT_OLD:
  6556 00001FCA 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  6557                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  6558 00001FCD 0F8786000000        <1>         ja      XO_OUT
  6559 00001FD3 80BF[61790000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  6560 00001FDA 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  6561                              <1> 
  6562                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  6563                              <1> 
  6564 00001FDC 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  6565 00001FDF C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  6566 00001FE2 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  6567 00001FE4 D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  6568 00001FE6 8425[60790000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  6569 00001FEC 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  6570                              <1> 
  6571                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  6572                              <1> 
  6573 00001FEE B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  6574 00001FF0 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  6575 00001FF2 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  6576 00001FF4 2025[60790000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  6577                              <1> 
  6578                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  6579                              <1> 
  6580 00001FFA 8A87[61790000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  6581 00002000 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  6582 00002002 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  6583 00002004 0805[60790000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  6584                              <1> 
  6585                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  6586                              <1> 
  6587                              <1> SAVE_SET:
  6588 0000200A 8AA7[61790000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  6589 00002010 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  6590 00002012 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  6591 00002015 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  6592 00002018 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  6593 0000201A B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  6594 0000201C 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  6595 0000201F 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  6596 00002021 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  6597 00002024 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  6598                              <1> UNKNO:
  6599 00002026 B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  6600 00002028 EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  6601                              <1> CHK_144:
  6602 0000202A E8A4050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6603                              <1> 	;;20/02/2015
  6604                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  6605 0000202F 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  6606 00002031 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  6607 00002033 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  6608 00002035 B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  6609 00002037 EB0C                <1> 	JMP	SHORT TST_DET
  6610                              <1> CHK_250:
  6611 00002039 B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  6612 0000203B 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  6613 0000203E 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  6614 00002040 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  6615 00002043 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  6616                              <1> TST_DET:
  6617 00002045 F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  6618 00002048 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  6619 0000204A 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  6620                              <1> AL_SET:
  6621 0000204C 80A7[61790000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  6622 00002053 0887[61790000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  6623                              <1> XO_OUT:
  6624 00002059 C3                  <1> 	RETn
  6625                              <1> 
  6626                              <1> ;-------------------------------------------------------------------------------
  6627                              <1> ; RD_WR_VF
  6628                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  6629                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  6630                              <1> ;
  6631                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  6632                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  6633                              <1> ;
  6634                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6635                              <1> ;-------------------------------------------------------------------------------
  6636                              <1> RD_WR_VF:
  6637 0000205A 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  6638 0000205C E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6639 00002061 E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  6640 00002066 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  6641                              <1> DO_AGAIN:
  6642 00002068 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6643 0000206A E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  6644 0000206F 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  6645 00002071 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  6646                              <1> RWV:
  6647 00002077 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6648 00002079 8AB7[61790000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6649 0000207F 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  6650 00002082 E84C050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  6651                              <1> 	;;20/02/2015
  6652                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  6653 00002087 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  6654 00002089 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  6655 0000208B 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  6656 0000208D F687[61790000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  6657 00002094 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  6658 00002096 B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  6659 00002098 EB0F                <1> 	JMP	SHORT RWV_2
  6660                              <1> RWV_1:
  6661 0000209A 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  6662 0000209C F687[61790000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  6663 000020A3 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  6664 000020A5 B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  6665 000020A7 EB04                <1> 	jmp	short rwv_3
  6666                              <1> RWV_2:
  6667 000020A9 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  6668 000020AB 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  6669                              <1> rwv_3:
  6670 000020AD E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  6671 000020B2 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  6672                              <1> 
  6673                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  6674                              <1> 
  6675 000020B4 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  6676 000020B5 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6677 000020B7 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6678                              <1> RWV_DR_SEARCH:
  6679 000020BC 8AA3[FC720000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  6680 000020C2 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  6681 000020C5 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6682 000020C7 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  6683                              <1> RWV_DR_FND:
  6684 000020C9 8BBB[FD720000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  6685                              <1> RWV_MD_SEARH:
  6686 000020CF 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  6687 000020D2 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  6688                              <1> RWV_NXT_MD:
  6689                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6690 000020D4 83C305              <1> 	add	eBX, 5
  6691 000020D7 E2E3                <1> 	LOOP	RWV_DR_SEARCH
  6692 000020D9 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6693                              <1> 
  6694                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  6695                              <1> 
  6696                              <1> RWV_ASSUME:
  6697 000020DA BB[1A730000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  6698 000020DF F687[61790000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  6699 000020E6 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  6700 000020E8 BB[34730000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  6701 000020ED EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  6702                              <1> 
  6703                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  6704                              <1> 	 			
  6705                              <1> RWV_MD_FND:
  6706 000020EF 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  6707 000020F1 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6708                              <1> 	
  6709                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  6710                              <1> 
  6711                              <1> RWV_MD_FND1:
  6712 000020F2 E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  6713 000020F7 E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  6714 000020FC 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  6715 000020FE E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  6716                              <1> RWV_DBL:
  6717 00002103 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6718 00002104 E821040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  6719 00002109 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6720 0000210A 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  6721 0000210C 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  6722 0000210E 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6723 00002110 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6724 00002111 E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  6725 00002116 5B                  <1> 	POP	eBX 
  6726 00002117 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  6727 00002119 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  6728 0000211B 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  6729 0000211D 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6730 0000211E E83B020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  6731 00002123 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6732 00002124 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6733 00002126 E865020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  6734 0000212B 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6735 0000212D E8AA020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  6736                              <1> CHK_RET:
  6737 00002132 E849030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  6738 00002137 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  6739 00002139 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  6740 0000213B E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  6741                              <1> RWV_END:
  6742 00002140 E8F3020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  6743 00002145 E886030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  6744                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  6745 0000214A 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  6746 0000214C E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6747 00002151 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  6748 00002153 E8B0030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6749 00002158 C3                  <1> 	RETn
  6750                              <1> 
  6751                              <1> ;-------------------------------------------------------------------------------
  6752                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  6753                              <1> ;-------------------------------------------------------------------------------
  6754                              <1> SETUP_STATE:
  6755 00002159 F687[61790000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  6756 00002160 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  6757 00002162 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  6758 00002166 F687[61790000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  6759 0000216D 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  6760 0000216F F687[61790000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  6761 00002176 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  6762 00002178 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  6763                              <1> AX_SET:	
  6764 0000217C 80A7[61790000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  6765 00002183 08A7[61790000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  6766 00002189 8025[5C790000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  6767 00002190 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  6768 00002193 0805[5C790000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  6769                              <1> J1C:	
  6770 00002199 C3                  <1> 	RETn
  6771                              <1> 
  6772                              <1> ;-------------------------------------------------------------------------------
  6773                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  6774                              <1> ;-------------------------------------------------------------------------------
  6775                              <1> FMT_INIT:
  6776 0000219A F687[61790000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  6777 000021A1 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  6778 000021A3 E82B040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  6779                              <1> 	;; 20/02/2015
  6780                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  6781 000021A8 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  6782 000021AA FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  6783                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  6784 000021AC 8AA7[61790000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  6785 000021B2 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  6786 000021B5 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  6787 000021B7 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  6788 000021B9 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  6789 000021BC EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6790                              <1> N_360:	
  6791 000021BE FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  6792 000021C0 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  6793                              <1> F1_RATE:
  6794 000021C2 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  6795 000021C5 EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6796                              <1> N_12:	
  6797 000021C7 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  6798 000021C9 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  6799 000021CB F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  6800 000021CE 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  6801 000021D0 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  6802 000021D3 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  6803 000021D5 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  6804 000021D8 EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  6805                              <1> N_720:
  6806 000021DA FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  6807 000021DC 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  6808 000021DE EBE2                <1> 	JMP	SHORT F1_RATE
  6809                              <1> ISNT_12: 
  6810 000021E0 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  6811                              <1> 
  6812                              <1> SKP_STATE:
  6813 000021E3 88A7[61790000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  6814                              <1> F1_OUT:
  6815 000021E9 C3                  <1> 	RETn
  6816                              <1> CL_DRV:	
  6817 000021EA 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  6818 000021EC EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  6819                              <1> 
  6820                              <1> ;-------------------------------------------------------------------------------
  6821                              <1> ; MED_CHANGE	
  6822                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  6823                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  6824                              <1> ;
  6825                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  6826                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  6827                              <1> ;-------------------------------------------------------------------------------
  6828                              <1> MED_CHANGE:
  6829 000021EE E887060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  6830 000021F3 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  6831 000021F5 80A7[61790000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  6832                              <1> 
  6833                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  6834                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  6835                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  6836                              <1> 
  6837 000021FC 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  6838 000021FF B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  6839 00002201 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  6840 00002203 F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  6841 00002205 FA                  <1> 	CLI				; NO INTERRUPTS
  6842 00002206 2005[52790000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  6843 0000220C FB                  <1> 	STI				; INTERRUPTS ENABLED
  6844 0000220D E80F040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  6845                              <1> 
  6846                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  6847                              <1> 
  6848 00002212 E884F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  6849 00002217 B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  6850 00002219 E8FE040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6851 0000221E 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  6852 00002220 E8F7040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6853 00002225 C605[54790000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  6854                              <1> OK1:
  6855 0000222C E849060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  6856 00002231 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  6857                              <1> OK4:
  6858 00002233 C605[54790000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  6859                              <1> OK2:		
  6860 0000223A F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  6861 0000223B C3                  <1> 	RETn
  6862                              <1> MC_OUT:
  6863 0000223C F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  6864 0000223D C3                  <1> 	RETn
  6865                              <1> 
  6866                              <1> ;-------------------------------------------------------------------------------
  6867                              <1> ; SEND_RATE
  6868                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  6869                              <1> ; ON ENTRY:	DI = DRIVE #
  6870                              <1> ; ON EXIT:	NONE
  6871                              <1> ; REGISTERS ALTERED: DX
  6872                              <1> ;-------------------------------------------------------------------------------
  6873                              <1> SEND_RATE:
  6874 0000223E 6650                <1> 	PUSH	AX			; SAVE REG.
  6875 00002240 8025[5C790000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  6876 00002247 8A87[61790000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6877 0000224D 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  6878 0000224F 0805[5C790000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  6879 00002255 C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  6880 00002258 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  6881 0000225C EE                  <1> 	OUT	DX,AL
  6882 0000225D 6658                <1> 	POP	AX			; RESTORE REG.
  6883 0000225F C3                  <1> 	RETn
  6884                              <1> 
  6885                              <1> ;-------------------------------------------------------------------------------
  6886                              <1> ; CHK_LASTRATE
  6887                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  6888                              <1> ; ON ENTRY:
  6889                              <1> ;	DI = DRIVE #
  6890                              <1> ; ON EXIT:
  6891                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  6892                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  6893                              <1> ; REGISTERS ALTERED: DX
  6894                              <1> ;-------------------------------------------------------------------------------
  6895                              <1> CHK_LASTRATE:
  6896 00002260 6650                <1> 	PUSH	AX			; SAVE REG
  6897 00002262 2225[5C790000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  6898 00002268 8A87[61790000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6899 0000226E 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  6900 00002272 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  6901                              <1> 					; ZF = 1 RATE IS THE SAME
  6902 00002274 6658                <1> 	POP	AX			; RESTORE REG.
  6903 00002276 C3                  <1> 	RETn
  6904                              <1> 
  6905                              <1> ;-------------------------------------------------------------------------------
  6906                              <1> ; DMA_SETUP
  6907                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  6908                              <1> ;
  6909                              <1> ; ON ENTRY:	AL = DMA COMMAND
  6910                              <1> ;
  6911                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6912                              <1> ;-------------------------------------------------------------------------------
  6913                              <1> 
  6914                              <1> ; SI = Head #, # of Sectors or DASD Type
  6915                              <1> 
  6916                              <1> ; 22/08/2015
  6917                              <1> ; 08/02/2015 - Protected Mode Modification
  6918                              <1> ; 06/02/2015 - 07/02/2015
  6919                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  6920                              <1> ; (DMA Addres = Physical Address)
  6921                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  6922                              <1> ;
  6923                              <1> 
  6924                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  6925                              <1> ; 16/12/2014 (IODELAY)
  6926                              <1> 
  6927                              <1> DMA_SETUP:
  6928                              <1> ;; 20/02/2015
  6929 00002277 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6930 0000227A F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  6931 00002280 756D                <1> 	jnz	short dma_bnd_err_stc
  6932                              <1> 	;
  6933 00002282 6650                <1> 	push	ax			; DMA command
  6934 00002284 52                  <1> 	push	edx			; *
  6935 00002285 B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  6936 00002287 E850030000          <1> 	call	GET_PARM		; 
  6937 0000228C 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6938 0000228E 6689F0              <1> 	mov	ax, si			; Sector count
  6939 00002291 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  6940 00002293 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  6941 00002295 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  6942 00002298 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  6943 0000229B 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  6944 0000229D 6689C1              <1> 	mov	cx, ax
  6945 000022A0 5A                  <1> 	pop	edx			; *
  6946 000022A1 6658                <1> 	pop	ax
  6947 000022A3 3C42                <1> 	cmp	al, 42h
  6948 000022A5 7507                <1>         jne     short NOT_VERF
  6949 000022A7 BA0000FF00          <1> 	mov	edx, 0FF0000h
  6950 000022AC EB08                <1> 	jmp	short J33
  6951                              <1> NOT_VERF:
  6952 000022AE 6601CA              <1> 	add	dx, cx			; check for overflow
  6953 000022B1 723D                <1> 	jc	short dma_bnd_err
  6954                              <1> 	;
  6955 000022B3 6629CA              <1> 	sub	dx, cx			; Restore start address
  6956                              <1> J33:
  6957 000022B6 FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6958 000022B7 E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6959                              <1> 	IODELAY				; WAIT FOR I/O
  6960 000022B9 EB00                <2>  jmp short $+2
  6961 000022BB EB00                <2>  jmp short $+2
  6962 000022BD E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6963 000022BF 89D0                <1> 	mov	eax, edx		; Buffer address
  6964 000022C1 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6965                              <1> 	IODELAY				; WAIT FOR I/O
  6966 000022C3 EB00                <2>  jmp short $+2
  6967 000022C5 EB00                <2>  jmp short $+2
  6968 000022C7 88E0                <1> 	MOV	AL,AH
  6969 000022C9 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6970 000022CB C1E810              <1> 	shr	eax, 16
  6971                              <1> 	IODELAY				; I/O WAIT STATE
  6972 000022CE EB00                <2>  jmp short $+2
  6973 000022D0 EB00                <2>  jmp short $+2
  6974 000022D2 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6975                              <1> 	IODELAY
  6976 000022D4 EB00                <2>  jmp short $+2
  6977 000022D6 EB00                <2>  jmp short $+2
  6978 000022D8 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  6979 000022DB E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6980                              <1> 	IODELAY				; WAIT FOR I/O
  6981 000022DD EB00                <2>  jmp short $+2
  6982 000022DF EB00                <2>  jmp short $+2
  6983 000022E1 88E0                <1> 	MOV	AL, AH
  6984 000022E3 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6985                              <1> 	IODELAY
  6986 000022E5 EB00                <2>  jmp short $+2
  6987 000022E7 EB00                <2>  jmp short $+2
  6988 000022E9 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6989 000022EA B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  6990 000022EC E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6991 000022EE C3                  <1> 	retn
  6992                              <1> dma_bnd_err_stc:
  6993 000022EF F9                  <1> 	stc
  6994                              <1> dma_bnd_err:
  6995 000022F0 C605[54790000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6996 000022F7 C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  6997                              <1> 
  6998                              <1> ;; 16/12/2014
  6999                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  7000                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  7001                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7002                              <1> ;;	IODELAY
  7003                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  7004                              <1> ;;	;SIODELAY
  7005                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  7006                              <1> ;;      ;JNE	short NOT_VERF		; NO
  7007                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  7008                              <1> ;;      ;JMP	SHORT J33
  7009                              <1> ;;;NOT_VERF:	
  7010                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  7011                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  7012                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  7013                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  7014                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  7015                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  7016                              <1> ;;	;JNC	short J33
  7017                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  7018                              <1> ;;;J33:
  7019                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  7020                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  7021                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7022                              <1> ;;	IODELAY
  7023                              <1> ;;	MOV	AL,AH
  7024                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  7025                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  7026                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  7027                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  7028                              <1> ;;	IODELAY
  7029                              <1> ;;	;AND	AL,00001111B
  7030                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  7031                              <1> ;;	;SIODELAY
  7032                              <1> ;;
  7033                              <1> ;;;----- DETERMINE COUNT
  7034                              <1> ;;	sub	eax, eax ; 08/02/2015
  7035                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  7036                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  7037                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  7038                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  7039                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  7040                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  7041                              <1> ;;	CALL	GET_PARM		; "
  7042                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  7043                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  7044                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  7045                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  7046                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  7047                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  7048                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7049                              <1> ;;	IODELAY
  7050                              <1> ;;	MOV	AL, AH
  7051                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  7052                              <1> ;;	;IODELAY
  7053                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  7054                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  7055                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  7056                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  7057                              <1> ;;	add	ecx, eax ; 08/02/2015
  7058                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  7059                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7060                              <1> ;;	SIODELAY
  7061                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  7062                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  7063                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  7064                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  7065                              <1> ;;	jz	short NO_BAD
  7066                              <1> ;;dma_bnd_err:
  7067                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  7068                              <1> ;;NO_BAD:
  7069                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  7070                              <1> 
  7071                              <1> ;-------------------------------------------------------------------------------
  7072                              <1> ; FMTDMA_SET
  7073                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  7074                              <1> ;
  7075                              <1> ; ON ENTRY:	NOTHING REQUIRED
  7076                              <1> ;
  7077                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7078                              <1> ;-------------------------------------------------------------------------------
  7079                              <1> 
  7080                              <1> FMTDMA_SET:
  7081                              <1> ;; 20/02/2015 modification	
  7082 000022F8 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  7083 000022FB F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  7084 00002301 75EC                <1> 	jnz	short dma_bnd_err_stc
  7085                              <1> 	;
  7086 00002303 6652                <1> 	push	dx			; *
  7087 00002305 B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  7088 00002307 E8D0020000          <1> 	call	GET_PARM		; "
  7089 0000230C 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  7090 0000230E 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  7091 00002310 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  7092 00002314 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  7093 00002316 6689C1              <1> 	mov	cx, ax
  7094 00002319 665A                <1> 	pop	dx			; *
  7095 0000231B 6601CA              <1> 	add	dx, cx			; check for overflow
  7096 0000231E 72D0                <1> 	jc	short dma_bnd_err
  7097                              <1> 	;
  7098 00002320 6629CA              <1> 	sub	dx, cx			; Restore start address
  7099                              <1> 	;
  7100 00002323 B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  7101 00002325 FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  7102 00002326 E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  7103                              <1> 	IODELAY				; WAIT FOR I/O
  7104 00002328 EB00                <2>  jmp short $+2
  7105 0000232A EB00                <2>  jmp short $+2
  7106 0000232C E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  7107 0000232E 89D0                <1> 	mov	eax, edx		; Buffer address
  7108 00002330 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  7109                              <1> 	IODELAY				; WAIT FOR I/O
  7110 00002332 EB00                <2>  jmp short $+2
  7111 00002334 EB00                <2>  jmp short $+2
  7112 00002336 88E0                <1> 	MOV	AL,AH
  7113 00002338 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  7114 0000233A C1E810              <1> 	shr	eax, 16
  7115                              <1> 	IODELAY				; I/O WAIT STATE
  7116 0000233D EB00                <2>  jmp short $+2
  7117 0000233F EB00                <2>  jmp short $+2
  7118 00002341 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  7119                              <1> 	IODELAY
  7120 00002343 EB00                <2>  jmp short $+2
  7121 00002345 EB00                <2>  jmp short $+2
  7122 00002347 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  7123 0000234A E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  7124                              <1> 	IODELAY				; WAIT FOR I/O
  7125 0000234C EB00                <2>  jmp short $+2
  7126 0000234E EB00                <2>  jmp short $+2
  7127 00002350 88E0                <1> 	MOV	AL, AH
  7128 00002352 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  7129                              <1> 	IODELAY
  7130 00002354 EB00                <2>  jmp short $+2
  7131 00002356 EB00                <2>  jmp short $+2
  7132 00002358 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  7133 00002359 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  7134 0000235B E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  7135 0000235D C3                  <1> 	retn
  7136                              <1> 
  7137                              <1> ;; 08/02/2015 - Protected Mode Modification
  7138                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  7139                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  7140                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  7141                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7142                              <1> ;;	IODELAY
  7143                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  7144                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  7145                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  7146                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  7147                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  7148                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  7149                              <1> ;;	;JNC	short J33A
  7150                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  7151                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  7152                              <1> ;;;J33A:
  7153                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  7154                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  7155                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7156                              <1> ;;	IODELAY
  7157                              <1> ;;	MOV	AL,AH
  7158                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  7159                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  7160                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  7161                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  7162                              <1> ;;	IODELAY
  7163                              <1> ;;	;AND	AL,00001111B
  7164                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  7165                              <1> ;;
  7166                              <1> ;;;----- DETERMINE COUNT
  7167                              <1> ;;	sub	eax, eax ; 08/02/2015
  7168                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  7169                              <1> ;;	CALL	GET_PARM		; "
  7170                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  7171                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  7172                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  7173                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  7174                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  7175                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  7176                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7177                              <1> ;;	IODELAY
  7178                              <1> ;;	MOV	AL, AH
  7179                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  7180                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  7181                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  7182                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  7183                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  7184                              <1> ;;	add	ecx, eax ; 08/02/2015
  7185                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  7186                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7187                              <1> ;;	SIODELAY
  7188                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  7189                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  7190                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  7191                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  7192                              <1> ;;	jz	short FMTDMA_OK
  7193                              <1> ;;	stc	; 20/02/2015
  7194                              <1> ;;fmtdma_bnd_err:
  7195                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  7196                              <1> ;;FMTDMA_OK:
  7197                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  7198                              <1> 
  7199                              <1> ;-------------------------------------------------------------------------------
  7200                              <1> ; NEC_INIT	
  7201                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  7202                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  7203                              <1> ;
  7204                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  7205                              <1> ;
  7206                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7207                              <1> ;-------------------------------------------------------------------------------
  7208                              <1> NEC_INIT:
  7209 0000235E 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  7210 00002360 E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  7211                              <1> 
  7212                              <1> ;-----	DO THE SEEK OPERATION
  7213                              <1> 
  7214 00002365 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  7215 00002368 E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  7216 0000236D 6658                <1> 	POP	AX			; RECOVER COMMAND
  7217 0000236F 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  7218 00002371 BB[8F230000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  7219 00002376 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  7220                              <1> 
  7221                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  7222                              <1> 
  7223 00002377 E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  7224 0000237C 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  7225 0000237F 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  7226 00002381 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  7227 00002384 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  7228 00002387 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  7229 00002389 E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  7230 0000238E 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  7231                              <1> ER_1:
  7232 0000238F C3                  <1> 	RETn
  7233                              <1> 
  7234                              <1> ;-------------------------------------------------------------------------------
  7235                              <1> ; RWV_COM
  7236                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  7237                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  7238                              <1> ;
  7239                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  7240                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7241                              <1> ;-------------------------------------------------------------------------------
  7242                              <1> RWV_COM:
  7243 00002390 B8[DB230000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  7244 00002395 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  7245 00002396 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  7246 00002399 E844030000          <1> 	CALL	NEC_OUTPUT
  7247 0000239E 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  7248 000023A1 E83C030000          <1> 	CALL	NEC_OUTPUT
  7249 000023A6 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  7250 000023A9 E834030000          <1> 	CALL	NEC_OUTPUT
  7251 000023AE B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  7252 000023B0 E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  7253 000023B5 E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  7254 000023BA B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  7255 000023BC E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  7256 000023C1 E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  7257 000023C6 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  7258                              <1> _R15:
  7259 000023C9 E814030000          <1> 	CALL	NEC_OUTPUT
  7260 000023CE B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  7261 000023D0 E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  7262 000023D5 E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  7263 000023DA 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  7264                              <1> ER_2:
  7265 000023DB C3                  <1> 	RETn
  7266                              <1> 
  7267                              <1> ;-------------------------------------------------------------------------------
  7268                              <1> ; NEC_TERM
  7269                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  7270                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  7271                              <1> ;
  7272                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7273                              <1> ;-------------------------------------------------------------------------------
  7274                              <1> NEC_TERM:
  7275                              <1> 
  7276                              <1> ;-----	LET THE OPERATION HAPPEN
  7277                              <1> 
  7278 000023DC 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  7279 000023DD E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  7280 000023E2 9C                  <1> 	PUSHF
  7281 000023E3 E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  7282 000023E8 724B                <1> 	JC	short SET_END_POP
  7283 000023EA 9D                  <1> 	POPF
  7284 000023EB 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  7285                              <1> 
  7286                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  7287                              <1> 
  7288 000023ED FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  7289 000023EE BE[55790000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  7290 000023F3 AC                  <1> 	lodsb				; GET ST0
  7291 000023F4 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  7292 000023F6 7433                <1> 	JZ	short SET_END
  7293 000023F8 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  7294 000023FA 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  7295                              <1> 
  7296                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  7297                              <1> 
  7298 000023FC AC                  <1> 	lodsb				; GET ST1
  7299 000023FD D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  7300 000023FF B404                <1> 	MOV	AH,RECORD_NOT_FND
  7301 00002401 7222                <1> 	JC	short J19
  7302 00002403 C0E002              <1> 	SAL	AL,2
  7303 00002406 B410                <1> 	MOV	AH,BAD_CRC
  7304 00002408 721B                <1> 	JC	short J19
  7305 0000240A D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  7306 0000240C B408                <1> 	MOV	AH,BAD_DMA
  7307 0000240E 7215                <1> 	JC	short J19
  7308 00002410 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  7309 00002413 B404                <1> 	MOV	AH,RECORD_NOT_FND
  7310 00002415 720E                <1> 	JC	short J19
  7311 00002417 D0E0                <1> 	SAL	AL,1
  7312 00002419 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  7313 0000241B 7208                <1> 	JC	short J19
  7314 0000241D D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  7315 0000241F B402                <1> 	MOV	AH,BAD_ADDR_MARK
  7316 00002421 7202                <1> 	JC	short J19
  7317                              <1> 
  7318                              <1> ;----- 	NEC MUST HAVE FAILED
  7319                              <1> J18:
  7320 00002423 B420                <1> 	MOV	AH,BAD_NEC
  7321                              <1> J19:
  7322 00002425 0825[54790000]      <1> 	OR	[DSKETTE_STATUS], AH
  7323                              <1> SET_END:
  7324 0000242B 803D[54790000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  7325 00002432 F5                  <1> 	CMC
  7326 00002433 5E                  <1> 	POP	eSI
  7327 00002434 C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  7328                              <1> 
  7329                              <1> SET_END_POP:
  7330 00002435 9D                  <1> 	POPF
  7331 00002436 EBF3                <1> 	JMP	SHORT SET_END
  7332                              <1> 
  7333                              <1> ;-------------------------------------------------------------------------------
  7334                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  7335                              <1> ;-------------------------------------------------------------------------------
  7336                              <1> DSTATE:
  7337 00002438 803D[54790000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  7338 0000243F 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  7339 00002441 808F[61790000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  7340 00002448 F687[61790000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  7341 0000244F 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  7342 00002451 8A87[61790000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  7343 00002457 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  7344 00002459 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  7345 0000245B 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  7346                              <1> 
  7347                              <1> ;----- 	CHECK IF IT IS 1.44M
  7348                              <1> 
  7349 0000245D E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  7350                              <1> 	;;20/02/2015
  7351                              <1> 	;;JC	short M_12		; CMOS BAD
  7352 00002462 7414                <1> 	jz	short M_12 ;; 20/02/2015
  7353 00002464 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  7354 00002466 7410                <1> 	JE	short M_12		; YES
  7355                              <1> M_720:
  7356 00002468 80A7[61790000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  7357 0000246F 808F[61790000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  7358 00002476 EB07                <1> 	JMP	SHORT SETBAC		; BACK
  7359                              <1> M_12:	
  7360 00002478 808F[61790000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  7361                              <1> 					; TURN ON DETERMINED & FMT CAPA
  7362                              <1> SETBAC:
  7363 0000247F C3                  <1> 	RETn
  7364                              <1> 
  7365                              <1> ;-------------------------------------------------------------------------------
  7366                              <1> ; RETRY	
  7367                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  7368                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  7369                              <1> ;
  7370                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  7371                              <1> ;-------------------------------------------------------------------------------
  7372                              <1> RETRY:
  7373 00002480 803D[54790000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  7374 00002487 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  7375 00002489 803D[54790000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  7376 00002490 743C                <1> 	JZ	short NO_RETRY
  7377 00002492 8AA7[61790000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  7378 00002498 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  7379 0000249B 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  7380 0000249D 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  7381 000024A0 8A2D[5C790000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  7382 000024A6 C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  7383 000024A9 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  7384 000024AC 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  7385 000024AE 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  7386                              <1> 
  7387                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  7388                              <1> ;	 00000000B (500) -> 10000000B	(250)
  7389                              <1> ;	 10000000B (250) -> 01000000B	(300)
  7390                              <1> ;	 01000000B (300) -> 00000000B	(500)
  7391                              <1> 
  7392 000024B0 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  7393 000024B3 D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  7394 000024B5 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  7395 000024B8 80A7[61790000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  7396                              <1> 					; RATE, DBL STEP OFF
  7397 000024BF 08A7[61790000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  7398 000024C5 C605[54790000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  7399 000024CC F9                  <1> 	STC				; SET CARRY FOR RETRY
  7400 000024CD C3                  <1> 	RETn				; RETRY RETURN
  7401                              <1> 
  7402                              <1> NO_RETRY:
  7403 000024CE F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  7404 000024CF C3                  <1> 	RETn				; NO RETRY RETURN
  7405                              <1> 
  7406                              <1> ;-------------------------------------------------------------------------------
  7407                              <1> ; NUM_TRANS
  7408                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  7409                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  7410                              <1> ;
  7411                              <1> ; ON ENTRY:	[BP+1] = TRACK
  7412                              <1> ;		SI-HI  = HEAD
  7413                              <1> ;		[BP]   = START SECTOR
  7414                              <1> ;
  7415                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  7416                              <1> ;-------------------------------------------------------------------------------
  7417                              <1> NUM_TRANS:
  7418 000024D0 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  7419 000024D2 803D[54790000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  7420 000024D9 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  7421 000024DB B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  7422 000024DD E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  7423 000024E2 8A1D[5A790000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  7424 000024E8 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  7425 000024EB 3A2D[59790000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  7426 000024F1 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  7427 000024F3 8A2D[58790000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  7428 000024F9 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  7429 000024FC 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  7430 000024FE 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7431                              <1> DIF_HD:
  7432 00002500 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7433                              <1> SAME_TRK:
  7434 00002502 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  7435 00002505 88D8                <1> 	MOV	AL,BL			; TO AL
  7436                              <1> NT_OUT:
  7437 00002507 C3                  <1> 	RETn
  7438                              <1> 
  7439                              <1> ;-------------------------------------------------------------------------------
  7440                              <1> ; SETUP_END
  7441                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  7442                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  7443                              <1> ;
  7444                              <1> ; ON EXIT:
  7445                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7446                              <1> ;-------------------------------------------------------------------------------
  7447                              <1> SETUP_END:
  7448 00002508 B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  7449 0000250A 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  7450 0000250C E8CB000000          <1> 	CALL	GET_PARM
  7451 00002511 8825[53790000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  7452 00002517 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  7453 00002519 8A25[54790000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  7454 0000251F 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  7455 00002521 7402                <1> 	JZ	short NUN_ERR			; NO ERROR
  7456 00002523 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  7457                              <1> NUN_ERR: 
  7458 00002525 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  7459 00002528 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  7460 00002529 C3                  <1> 	RETn
  7461                              <1> 
  7462                              <1> ;-------------------------------------------------------------------------------
  7463                              <1> ; SETUP_DBL
  7464                              <1> ;	CHECK DOUBLE STEP.
  7465                              <1> ;
  7466                              <1> ; ON ENTRY :	DI = DRIVE
  7467                              <1> ;
  7468                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  7469                              <1> ;-------------------------------------------------------------------------------
  7470                              <1> SETUP_DBL:
  7471 0000252A 8AA7[61790000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  7472 00002530 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  7473 00002533 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  7474                              <1> 
  7475                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  7476                              <1> 
  7477 00002535 C605[51790000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  7478 0000253C E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  7479 00002541 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  7480 00002543 E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  7481 00002548 E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  7482 0000254D 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  7483                              <1> 
  7484                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  7485                              <1> 
  7486 0000254F 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  7487 00002553 F687[61790000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  7488 0000255A 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  7489 0000255C B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  7490                              <1> 
  7491                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  7492                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  7493                              <1> ;	THEN SET DOUBLE STEP ON.
  7494                              <1> 
  7495                              <1> CNT_OK:
  7496 0000255E C605[53790000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  7497 00002565 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  7498 00002567 C605[54790000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  7499 0000256E 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  7500 00002571 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  7501 00002573 C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  7502 00002576 6650                <1> 	PUSH	AX			; SAVE HEAD
  7503 00002578 E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  7504 0000257D 6658                <1> 	POP	AX			; RESTORE HEAD
  7505 0000257F 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  7506 00002582 E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  7507 00002587 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  7508 00002588 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  7509 0000258D 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  7510 0000258E 6659                <1> 	POP	CX			; RESTORE COUNT
  7511 00002590 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  7512 00002592 FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  7513 00002594 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  7514 00002596 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  7515                              <1> 
  7516                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  7517                              <1> 
  7518                              <1> SD_ERR:	
  7519 00002598 F9                  <1> 	STC				; SET CARRY FOR ERROR
  7520 00002599 C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  7521                              <1> 
  7522                              <1> DO_CHK:
  7523 0000259A 8A0D[58790000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  7524 000025A0 888F[65790000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  7525 000025A6 D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  7526 000025A8 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  7527 000025AA 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  7528 000025AC 808F[61790000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  7529                              <1> NO_DBL:
  7530 000025B3 F8                  <1> 	CLC				; CLEAR ERROR FLAG
  7531 000025B4 C3                  <1> 	RETn
  7532                              <1> 
  7533                              <1> ;-------------------------------------------------------------------------------
  7534                              <1> ; READ_ID
  7535                              <1> ;	READ ID FUNCTION.
  7536                              <1> ;
  7537                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  7538                              <1> ;
  7539                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  7540                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7541                              <1> ;-------------------------------------------------------------------------------
  7542                              <1> READ_ID:
  7543 000025B5 B8[D2250000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  7544 000025BA 50                  <1> 	PUSH	eAX
  7545 000025BB B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  7546 000025BD E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7547 000025C2 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  7548 000025C5 88C4                <1> 	MOV	AH,AL
  7549 000025C7 E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7550 000025CC E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  7551 000025D1 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  7552                              <1> ER_3:
  7553 000025D2 C3                  <1> 	RETn
  7554                              <1> 
  7555                              <1> ;-------------------------------------------------------------------------------
  7556                              <1> ; CMOS_TYPE
  7557                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  7558                              <1> ;
  7559                              <1> ; ON ENTRY:	DI = DRIVE #
  7560                              <1> ;
  7561                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  7562                              <1> ;-------------------------------------------------------------------------------
  7563                              <1> 
  7564                              <1> CMOS_TYPE: ; 11/12/2014
  7565 000025D3 8A87[AE750000]      <1> mov	al, [eDI+fd0_type]
  7566 000025D9 20C0                <1> and 	al, al ; 18/12/2014
  7567 000025DB C3                  <1> retn
  7568                              <1> 
  7569                              <1> ;CMOS_TYPE:
  7570                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  7571                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  7572                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  7573                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  7574                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  7575                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  7576                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  7577                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  7578                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  7579                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  7580                              <1> ;TB:
  7581                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  7582                              <1> ;BAD_CM:
  7583                              <1> ;	RETn				; CY, STATUS OF READ
  7584                              <1> 
  7585                              <1> ;-------------------------------------------------------------------------------
  7586                              <1> ; GET_PARM
  7587                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  7588                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  7589                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  7590                              <1> ;	THE PARAMETER IN DL.
  7591                              <1> ;
  7592                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  7593                              <1> ;
  7594                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  7595                              <1> ;		AL,DH DESTROYED
  7596                              <1> ;-------------------------------------------------------------------------------
  7597                              <1> GET_PARM:
  7598                              <1> 	;PUSH	DS
  7599 000025DC 56                  <1> 	PUSH	eSI
  7600                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  7601                              <1>     	;MOV	DS,AX
  7602                              <1> 	;;mov	ax, cs
  7603                              <1> 	;;mov	ds, ax
  7604                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  7605 000025DD 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  7606                              <1> 	;SUB	BH,BH			; BX = INDEX
  7607 000025DF 81E3FF000000        <1> 	and	ebx, 0FFh
  7608                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  7609                              <1> 	;
  7610                              <1> 	; 17/12/2014
  7611 000025E5 66A1[71730000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  7612 000025EB 38E0                <1> 	cmp	al, ah
  7613 000025ED 7425                <1> 	je	short gpndc
  7614 000025EF A2[72730000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  7615 000025F4 53                  <1> 	push	ebx ; 08/02/2015
  7616 000025F5 88C3                <1> 	mov	bl, al 
  7617                              <1> 	; 11/12/2014
  7618 000025F7 8A83[AE750000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  7619                              <1> 	; 18/12/2014
  7620 000025FD 20C0                <1> 	and	al, al
  7621 000025FF 7507                <1> 	jnz	short gpdtc
  7622 00002601 BB[5B730000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  7623 00002606 EB05                <1>         jmp     short gpdpu
  7624                              <1> gpdtc:	
  7625 00002608 E818F9FFFF          <1> 	call	DR_TYPE_CHECK
  7626                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  7627                              <1> gpdpu:
  7628 0000260D 891D[F8720000]      <1> 	mov	[DISK_POINTER], ebx
  7629 00002613 5B                  <1> 	pop	ebx
  7630                              <1> gpndc:
  7631 00002614 8B35[F8720000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  7632 0000261A 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  7633 0000261D 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  7634 0000261F 5E                  <1> 	POP	eSI
  7635                              <1> 	;POP	DS
  7636 00002620 C3                  <1> 	RETn
  7637                              <1> 
  7638                              <1> ;-------------------------------------------------------------------------------
  7639                              <1> ; MOTOR_ON
  7640                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  7641                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  7642                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  7643                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  7644                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  7645                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  7646                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  7647                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  7648                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  7649                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  7650                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  7651                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  7652                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  7653                              <1> ;
  7654                              <1> ; ON ENTRY:	DI = DRIVE #
  7655                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  7656                              <1> ;-------------------------------------------------------------------------------
  7657                              <1> MOTOR_ON:
  7658 00002621 53                  <1> 	PUSH	eBX			; SAVE REG.
  7659 00002622 E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  7660 00002627 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  7661 00002629 E89CF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7662 0000262E E866F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  7663                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  7664                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  7665                              <1> M_WAIT:
  7666 00002633 B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  7667 00002635 E8A2FFFFFF          <1> 	CALL	GET_PARM
  7668                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  7669                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  7670                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  7671 0000263A 80FC08              <1> 	cmp	ah, 8
  7672                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  7673 0000263D 7702                <1> 	ja	short J13
  7674                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  7675 0000263F B408                <1> 	mov	ah, 8
  7676                              <1> 
  7677                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  7678                              <1> GP2:	
  7679                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  7680                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  7681 00002641 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  7682 00002646 E817F3FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  7683                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  7684 0000264B FECC                <1> 	dec	ah
  7685 0000264D 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  7686                              <1> MOT_IS_ON:
  7687 0000264F 5B                  <1> 	POP	eBX			; RESTORE REG.
  7688 00002650 C3                  <1> 	RETn
  7689                              <1> 
  7690                              <1> ;-------------------------------------------------------------------------------
  7691                              <1> ; TURN_ON
  7692                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  7693                              <1> ;
  7694                              <1> ; ON ENTRY:	DI = DRIVE #
  7695                              <1> ;
  7696                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  7697                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  7698                              <1> ;		AX,BX,CX,DX DESTROYED
  7699                              <1> ;-------------------------------------------------------------------------------
  7700                              <1> TURN_ON:
  7701 00002651 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7702 00002653 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  7703 00002655 C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  7704 00002658 FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  7705 00002659 C605[53790000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  7706 00002660 A0[52790000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7707 00002665 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  7708 00002667 B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  7709 00002669 D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  7710                              <1> 
  7711                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  7712                              <1> ;  BL = DRIVE SELECT DESIRED
  7713                              <1> ;  AH = MOTOR ON MASK DESIRED
  7714                              <1> 
  7715 0000266B 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  7716 0000266D 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  7717 0000266F 8425[52790000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  7718 00002675 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  7719                              <1> 
  7720                              <1> TURN_IT_ON:
  7721 00002677 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  7722 00002679 8A3D[52790000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  7723 0000267F 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  7724 00002682 8025[52790000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  7725 00002689 0825[52790000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  7726 0000268F A0[52790000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7727 00002694 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  7728 00002696 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  7729 00002699 FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  7730 0000269A 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  7731 0000269C C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  7732 0000269F 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  7733 000026A1 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  7734 000026A5 EE                  <1> 	OUT	DX,AL
  7735 000026A6 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  7736                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  7737 000026A8 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  7738 000026AA F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  7739 000026AB C3                  <1> 	RETn
  7740                              <1> 
  7741                              <1> NO_MOT_WAIT:
  7742 000026AC FB                  <1> 	sti
  7743                              <1> no_mot_w1: ; 27/02/2015
  7744 000026AD F9                  <1> 	STC				; SET NO WAIT REQUIRED
  7745                              <1> 	;STI				; INTERRUPTS BACK ON
  7746 000026AE C3                  <1> 	RETn
  7747                              <1> 
  7748                              <1> ;-------------------------------------------------------------------------------
  7749                              <1> ; HD_WAIT
  7750                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  7751                              <1> ;
  7752                              <1> ; ON ENTRY:	DI = DRIVE #
  7753                              <1> ;
  7754                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  7755                              <1> ;-------------------------------------------------------------------------------
  7756                              <1> HD_WAIT:
  7757 000026AF B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  7758 000026B1 E826FFFFFF          <1> 	CALL	GET_PARM
  7759 000026B6 08E4                <1> 	or	ah, ah	; 17/12/2014
  7760 000026B8 7519                <1> 	jnz	short DO_WAT
  7761 000026BA F605[52790000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  7762                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  7763                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  7764                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  7765 000026C1 741E                <1> 	jz	short HW_DONE
  7766 000026C3 B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  7767 000026C5 8A87[61790000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  7768 000026CB 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  7769 000026CD 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  7770 000026CF 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  7771                              <1> ;GP3:
  7772 000026D1 B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  7773                              <1> ;	JMP	SHORT DO_WAT
  7774                              <1> 
  7775                              <1> ;ISNT_WRITE:
  7776                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  7777                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  7778                              <1> 
  7779                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  7780                              <1> DO_WAT:
  7781                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  7782                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  7783                              <1> J29:					; 	1 MILLISECOND LOOP
  7784                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  7785 000026D3 B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  7786 000026D8 E885F2FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  7787                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  7788 000026DD FECC                <1> 	dec	ah
  7789 000026DF 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  7790                              <1> HW_DONE:
  7791 000026E1 C3                  <1> 	RETn
  7792                              <1> 
  7793                              <1> ;-------------------------------------------------------------------------------
  7794                              <1> ; NEC_OUTPUT
  7795                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  7796                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  7797                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  7798                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  7799                              <1> ; 
  7800                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  7801                              <1> ;
  7802                              <1> ; ON EXIT:	CY = 0  SUCCESS
  7803                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  7804                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  7805                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  7806                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  7807                              <1> ;		AX,CX,DX DESTROYED
  7808                              <1> ;-------------------------------------------------------------------------------
  7809                              <1> 
  7810                              <1> ; 09/12/2014 [Erdogan Tan] 
  7811                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  7812                              <1> ; Diskette Drive Controller Status Register (3F4h)
  7813                              <1> ;	This read only register facilitates the transfer of data between
  7814                              <1> ;	the system microprocessor and the controller.
  7815                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  7816                              <1> ;	  with the system micrprocessor.
  7817                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  7818                              <1> ;	  the transfer is to the controller.
  7819                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  7820                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  7821                              <1> ; Bit 3 - Reserved.
  7822                              <1> ; Bit 2 - Reserved.
  7823                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7824                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7825                              <1> 
  7826                              <1> ; Data Register (3F5h)
  7827                              <1> ; This read/write register passes data, commands and parameters, and provides
  7828                              <1> ; diskette status information.
  7829                              <1>   		
  7830                              <1> NEC_OUTPUT:
  7831                              <1> 	;PUSH	BX			; SAVE REG.
  7832 000026E2 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  7833                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  7834                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  7835                              <1> 	; 16/12/2014
  7836                              <1> 	; waiting for (max.) 0.5 seconds
  7837                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  7838                              <1> 	;
  7839                              <1> 	; 17/12/2014
  7840                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  7841                              <1> 	;
  7842                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  7843                              <1> 	;		go on.
  7844                              <1> 	;INPUT:
  7845                              <1> 	;	AH=Mask for isolation bits.
  7846                              <1> 	;	AL=pattern to look for.
  7847                              <1> 	;	DX=Port to test for
  7848                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7849                              <1> 	;	     (normally 30 microseconds per period.)
  7850                              <1> 	;
  7851                              <1> 	;WFP_SHORT:  
  7852                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  7853                              <1> 	;
  7854                              <1> 
  7855                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  7856                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  7857 000026E6 B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  7858                              <1> ;
  7859                              <1> ;WFPS_OUTER_LP:
  7860                              <1> ;	;
  7861                              <1> ;WFPS_CHECK_PORT:
  7862                              <1> J23:
  7863 000026EB EC                  <1> 	IN	AL,DX			; GET STATUS
  7864 000026EC 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7865 000026EE 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7866 000026F0 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  7867                              <1> WFPS_HI:
  7868 000026F2 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  7869 000026F4 A810                <1> 	TEST	AL,010H			; transition on memory
  7870 000026F6 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  7871                              <1> WFPS_LO:
  7872 000026F8 E461                <1> 	IN	AL, PORT_B		; SYS1
  7873 000026FA A810                <1> 	TEST	AL,010H
  7874 000026FC 74FA                <1> 	JZ	SHORT WFPS_LO
  7875                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  7876 000026FE E2EB                <1> 	loop	J23	; 27/02/2015
  7877                              <1> ;	;
  7878                              <1> ;	dec	bl
  7879                              <1> ;	jnz	short WFPS_OUTER_LP
  7880                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  7881                              <1> ;J23:
  7882                              <1> ;	IN	AL,DX			; GET STATUS
  7883                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7884                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7885                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  7886                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  7887                              <1> 	;DEC	BL			; DECREMENT COUNTER
  7888                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  7889                              <1>    
  7890                              <1> 	;;27/02/2015
  7891                              <1> 	;16/12/2014
  7892                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  7893                              <1> 	;;jb	short J23
  7894                              <1> 
  7895                              <1> ;WFPS_TIMEOUT:
  7896                              <1> 
  7897                              <1> ;-----	FALL THRU TO ERROR RETURN
  7898                              <1> 
  7899 00002700 800D[54790000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  7900                              <1> 	;POP	BX			; RESTORE REG.
  7901 00002707 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  7902 00002708 F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  7903 00002709 C3                  <1> 	RETn
  7904                              <1> 
  7905                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  7906                              <1> 
  7907                              <1> J27:	
  7908 0000270A 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  7909 0000270C 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  7910 0000270E EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  7911                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  7912                              <1> 	; 27/02/2015
  7913 0000270F 9C                  <1> 	PUSHF				; SAVE FLAGS
  7914 00002710 B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  7915 00002715 E848F2FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  7916 0000271A 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  7917                              <1> 	;POP	BX			; RESTORE REG
  7918 0000271B C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  7919                              <1> 
  7920                              <1> ;-------------------------------------------------------------------------------
  7921                              <1> ; SEEK
  7922                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  7923                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  7924                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  7925                              <1> ;
  7926                              <1> ; ON ENTRY:	DI = DRIVE #
  7927                              <1> ;		CH = TRACK #
  7928                              <1> ;
  7929                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7930                              <1> ;		AX,BX,CX DX DESTROYED
  7931                              <1> ;-------------------------------------------------------------------------------
  7932                              <1> SEEK:
  7933 0000271C 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7934 0000271E B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  7935 00002720 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  7936 00002722 D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  7937 00002724 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  7938 00002726 8405[51790000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  7939 0000272C 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  7940                              <1> 
  7941 0000272E 0805[51790000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  7942 00002734 E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7943 00002739 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  7944                              <1> 
  7945                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  7946                              <1> 
  7947 0000273B C605[54790000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  7948 00002742 E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7949 00002747 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  7950                              <1> 
  7951                              <1> AFT_RECAL:
  7952 00002749 C687[65790000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  7953 00002750 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  7954 00002752 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  7955                              <1> 
  7956                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  7957                              <1> 
  7958 00002754 F687[61790000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  7959 0000275B 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  7960 0000275D D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  7961                              <1> 
  7962 0000275F 3AAF[65790000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  7963 00002765 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  7964                              <1> 
  7965 00002767 BA[9A270000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  7966 0000276C 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  7967 0000276D 88AF[65790000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  7968 00002773 B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  7969 00002775 E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  7970 0000277A 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7971 0000277C 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  7972 0000277E E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  7973 00002783 8AA7[65790000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  7974 00002789 E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  7975 0000278E E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  7976                              <1> 
  7977                              <1> ;-----	WAIT FOR HEAD SETTLE
  7978                              <1> 
  7979                              <1> DO_WAIT:
  7980 00002793 9C                  <1> 	PUSHF				; SAVE STATUS
  7981 00002794 E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  7982 00002799 9D                  <1> 	POPF				; RESTORE STATUS
  7983                              <1> RB:
  7984                              <1> NEC_ERR:
  7985                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  7986                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  7987 0000279A C3                  <1> 	RETn				; RETURN TO CALLER
  7988                              <1> 
  7989                              <1> ;-------------------------------------------------------------------------------
  7990                              <1> ; RECAL
  7991                              <1> ;	RECALIBRATE DRIVE
  7992                              <1> ;
  7993                              <1> ; ON ENTRY:	DI = DRIVE #
  7994                              <1> ;
  7995                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  7996                              <1> ;-------------------------------------------------------------------------------
  7997                              <1> RECAL:
  7998 0000279B 6651                <1> 	PUSH	CX
  7999 0000279D B8[B9270000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  8000 000027A2 50                  <1> 	PUSH	eAX
  8001 000027A3 B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  8002 000027A5 E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  8003 000027AA 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  8004 000027AC 88DC                <1> 	MOV	AH,BL
  8005 000027AE E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  8006 000027B3 E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  8007 000027B8 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  8008                              <1> RC_BACK:
  8009 000027B9 6659                <1> 	POP	CX
  8010 000027BB C3                  <1> 	RETn
  8011                              <1> 
  8012                              <1> ;-------------------------------------------------------------------------------
  8013                              <1> ; CHK_STAT_2
  8014                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  8015                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  8016                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  8017                              <1> ;
  8018                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  8019                              <1> ;-------------------------------------------------------------------------------
  8020                              <1> CHK_STAT_2:
  8021 000027BC B8[E4270000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  8022 000027C1 50                  <1> 	PUSH	eAX
  8023 000027C2 E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  8024 000027C7 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  8025 000027C9 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  8026 000027CB E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  8027 000027D0 E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  8028 000027D5 720C                <1> 	JC	short J34
  8029 000027D7 A0[55790000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  8030 000027DC 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  8031 000027DE 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  8032 000027E0 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  8033 000027E2 F8                  <1> 	CLC				; GOOD RETURN
  8034                              <1> J34:
  8035 000027E3 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  8036                              <1> CS_BACK:
  8037 000027E4 C3                  <1> 	RETn
  8038                              <1> J35:
  8039 000027E5 800D[54790000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  8040 000027EC F9                  <1> 	STC				; ERROR RETURN CODE
  8041 000027ED EBF4                <1> 	JMP	SHORT J34
  8042                              <1> 
  8043                              <1> ;-------------------------------------------------------------------------------
  8044                              <1> ; WAIT_INT
  8045                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  8046                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  8047                              <1> ;	IF THE DRIVE IS NOT READY.
  8048                              <1> ;
  8049                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  8050                              <1> ;-------------------------------------------------------------------------------
  8051                              <1> 
  8052                              <1> ; 17/12/2014
  8053                              <1> ; 2.5 seconds waiting !
  8054                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  8055                              <1> ; amount of time to wait for completion interrupt from NEC.
  8056                              <1> 
  8057                              <1> 
  8058                              <1> WAIT_INT:
  8059 000027EF FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  8060 000027F0 F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  8061                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  8062                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  8063                              <1> 
  8064                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  8065                              <1> 	;
  8066                              <1> 	;WAIT_FOR_MEM:	
  8067                              <1> 	;	Waits for a bit at a specified memory location pointed
  8068                              <1> 	;	to by ES:[DI] to become set.
  8069                              <1> 	;INPUT:
  8070                              <1> 	;	AH=Mask to test with.
  8071                              <1> 	;	ES:[DI] = memory location to watch.
  8072                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  8073                              <1> 	;	     (normally 30 microseconds per period.)
  8074                              <1> 
  8075                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  8076                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  8077                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  8078                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  8079                              <1> 	; 27/02/2015
  8080 000027F1 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  8081                              <1> WFMS_CHECK_MEM:
  8082 000027F6 F605[51790000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  8083 000027FD 7516                <1>         jnz     short J37
  8084                              <1> WFMS_HI:
  8085 000027FF E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  8086 00002801 A810                <1> 	TEST	AL,010H			; transition on memory
  8087 00002803 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  8088                              <1> WFMS_LO:
  8089 00002805 E461                <1> 	IN	AL,PORT_B		;SYS1
  8090 00002807 A810                <1> 	TEST	AL,010H
  8091 00002809 74FA                <1> 	JZ	SHORT WFMS_LO
  8092 0000280B E2E9                <1>         LOOP    WFMS_CHECK_MEM
  8093                              <1> ;WFMS_OUTER_LP:
  8094                              <1> ;;	or	bl, bl			; check outer counter
  8095                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  8096                              <1> ;	dec	bl
  8097                              <1> ;	jz	short J36A	
  8098                              <1> ;	jmp	short WFMS_CHECK_MEM
  8099                              <1> 
  8100                              <1> 	;17/12/2014
  8101                              <1> 	;16/12/2014
  8102                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  8103                              <1> ;J36:
  8104                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  8105                              <1> ;	JNZ	short J37
  8106                              <1> 	;16/12/2014
  8107                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  8108                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  8109                              <1> 	;JNZ	short J36
  8110                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  8111                              <1> ;	jb	short J36
  8112                              <1> 
  8113                              <1> ;WFMS_TIMEOUT:
  8114                              <1> ;J36A:
  8115 0000280D 800D[54790000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  8116 00002814 F9                  <1> 	STC				; ERROR RETURN
  8117                              <1> J37:
  8118 00002815 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  8119 00002816 8025[51790000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  8120 0000281D 9D                  <1> 	POPF				; RECOVER CARRY
  8121 0000281E C3                  <1> 	RETn				; GOOD RETURN CODE
  8122                              <1> 
  8123                              <1> ;-------------------------------------------------------------------------------
  8124                              <1> ; RESULTS
  8125                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  8126                              <1> ;	FOLLOWING AN INTERRUPT.
  8127                              <1> ;
  8128                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  8129                              <1> ;		AX,BX,CX,DX DESTROYED
  8130                              <1> ;-------------------------------------------------------------------------------
  8131                              <1> RESULTS:
  8132 0000281F 57                  <1> 	PUSH	eDI
  8133 00002820 BF[55790000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  8134 00002825 B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  8135 00002827 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  8136                              <1> 
  8137                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  8138                              <1> 
  8139                              <1> _R10: 
  8140                              <1> 	; 16/12/2014
  8141                              <1> 	; wait for (max) 0.5 seconds
  8142                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  8143                              <1> 	;XOR	CX,CX			; COUNTER
  8144                              <1> 
  8145                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  8146                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  8147                              <1> 	; 27/02/2015
  8148 0000282B B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  8149                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  8150                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  8151                              <1> 
  8152                              <1> WFPSR_OUTER_LP:
  8153                              <1> 	;
  8154                              <1> WFPSR_CHECK_PORT:
  8155                              <1> J39:					; WAIT FOR MASTER
  8156 00002830 EC                  <1> 	IN	AL,DX			; GET STATUS
  8157 00002831 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  8158 00002833 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  8159 00002835 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  8160                              <1> WFPSR_HI:
  8161 00002837 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  8162 00002839 A810                <1> 	TEST	AL,010H			; transition on memory
  8163 0000283B 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  8164                              <1> WFPSR_LO:
  8165 0000283D E461                <1> 	IN	AL, PORT_B		; SYS1
  8166 0000283F A810                <1> 	TEST	AL,010H
  8167 00002841 74FA                <1> 	JZ	SHORT WFPSR_LO
  8168 00002843 E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  8169                              <1> 	;; 27/02/2015
  8170                              <1> 	;;dec	bh
  8171                              <1> 	;;jnz	short WFPSR_OUTER_LP
  8172                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  8173                              <1> 
  8174                              <1> 	;;mov	byte [wait_count], 0
  8175                              <1> ;J39:					; WAIT FOR MASTER
  8176                              <1> ;	IN	AL,DX			; GET STATUS
  8177                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  8178                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  8179                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  8180                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  8181                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  8182                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  8183                              <1> 	;
  8184                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  8185                              <1> 	;;jb	short J39	
  8186                              <1> 
  8187                              <1> ;WFPSR_TIMEOUT:
  8188 00002845 800D[54790000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  8189 0000284C F9                  <1> 	STC				; SET ERROR RETURN
  8190 0000284D EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  8191                              <1> 
  8192                              <1> ;-----	READ IN THE STATUS
  8193                              <1> 
  8194                              <1> J42:
  8195 0000284F EB00                <1> 	JMP	$+2			; I/O DELAY
  8196 00002851 6642                <1> 	INC	DX			; POINT AT DATA PORT
  8197 00002853 EC                  <1> 	IN	AL,DX			; GET THE DATA
  8198                              <1> 	; 16/12/2014
  8199                              <1> 	NEWIODELAY
  8200 00002854 E6EB                <2>  out 0ebh,al
  8201 00002856 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  8202 00002858 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  8203                              <1> 	; 16/12/2014
  8204                              <1> ;	push	cx
  8205                              <1> ;	mov	cx, 30
  8206                              <1> ;wdw2:
  8207                              <1> ;	NEWIODELAY
  8208                              <1> ;	loop	wdw2
  8209                              <1> ;	pop	cx
  8210                              <1> 
  8211 00002859 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  8212 0000285E E8FFF0FFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  8213 00002863 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  8214 00002865 EC                  <1> 	IN	AL,DX			; GET STATUS
  8215                              <1> 	; 16/12/2014
  8216                              <1> 	NEWIODELAY
  8217 00002866 E6EB                <2>  out 0ebh,al
  8218                              <1> 	;
  8219 00002868 A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  8220 0000286A 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  8221                              <1> 
  8222 0000286C FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  8223 0000286E 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  8224 00002870 800D[54790000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  8225 00002877 F9                  <1> 	STC				; SET ERROR FLAG
  8226                              <1> 
  8227                              <1> ;-----	RESULT OPERATION IS DONE
  8228                              <1> POPRES:
  8229 00002878 5F                  <1> 	POP	eDI
  8230 00002879 C3                  <1> 	RETn				; RETURN WITH CARRY SET
  8231                              <1> 
  8232                              <1> ;-------------------------------------------------------------------------------
  8233                              <1> ; READ_DSKCHNG
  8234                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  8235                              <1> ;
  8236                              <1> ; ON ENTRY:	DI = DRIVE #
  8237                              <1> ;
  8238                              <1> ; ON EXIT:	DI = DRIVE #
  8239                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  8240                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  8241                              <1> ;		AX,CX,DX DESTROYED
  8242                              <1> ;-------------------------------------------------------------------------------
  8243                              <1> READ_DSKCHNG:
  8244 0000287A E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  8245 0000287F 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  8246 00002883 EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  8247 00002884 A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  8248 00002886 C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  8249                              <1> 
  8250                              <1> ;-------------------------------------------------------------------------------
  8251                              <1> ; DRIVE_DET
  8252                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  8253                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  8254                              <1> ; ON ENTRY:	DI = DRIVE #
  8255                              <1> ;-------------------------------------------------------------------------------
  8256                              <1> DRIVE_DET:
  8257 00002887 E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  8258 0000288C E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  8259 00002891 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  8260 00002893 B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  8261 00002895 E882FEFFFF          <1> 	CALL	SEEK
  8262 0000289A 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  8263 0000289C B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  8264                              <1> SK_GIN:
  8265 0000289E FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  8266 000028A0 6651                <1> 	PUSH	CX			; SAVE TRACK
  8267 000028A2 E875FEFFFF          <1> 	CALL	SEEK
  8268 000028A7 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  8269 000028A9 B8[E5280000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  8270 000028AE 50                  <1> 	PUSH	eAX
  8271 000028AF B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  8272 000028B1 E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  8273 000028B6 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  8274 000028B9 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  8275 000028BB E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  8276 000028C0 E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  8277 000028C5 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  8278 000028C6 6659                <1> 	POP	CX			; RESTORE TRACK
  8279 000028C8 F605[55790000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  8280 000028CF 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  8281 000028D1 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  8282 000028D3 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  8283                              <1> 
  8284                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  8285                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  8286                              <1> 
  8287 000028D5 808F[61790000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  8288 000028DC C3                  <1> 	RETn				; ALL INFORMATION SET
  8289                              <1> IS_80:
  8290 000028DD 808F[61790000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  8291                              <1> DD_BAC:
  8292 000028E4 C3                  <1> 	RETn
  8293                              <1> POP_BAC:
  8294 000028E5 6659                <1> 	POP	CX			; THROW AWAY
  8295 000028E7 C3                  <1> 	RETn
  8296                              <1> 
  8297                              <1> fdc_int:  
  8298                              <1> 	  ; 30/07/2015	
  8299                              <1> 	  ; 16/02/2015
  8300                              <1> ;int_0Eh: ; 11/12/2014
  8301                              <1> 
  8302                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  8303                              <1> ; DISK_INT
  8304                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  8305                              <1> ;
  8306                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  8307                              <1> ;-------------------------------------------------------------------------------
  8308                              <1> DISK_INT_1:
  8309                              <1> 
  8310 000028E8 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  8311 000028EA 1E                  <1> 	push	ds
  8312 000028EB 66B81000            <1> 	mov	ax, KDATA
  8313 000028EF 8ED8                <1> 	mov 	ds, ax
  8314 000028F1 800D[51790000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  8315 000028F8 B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  8316 000028FA E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  8317 000028FC 1F                  <1> 	pop	ds
  8318 000028FD 6658                <1> 	POP	AX			; RECOVER REGISTER
  8319 000028FF CF                  <1> 	IRET				; RETURN FROM INTERRUPT
  8320                              <1> 
  8321                              <1> ;-------------------------------------------------------------------------------
  8322                              <1> ; DSKETTE_SETUP
  8323                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  8324                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  8325                              <1> ;-------------------------------------------------------------------------------
  8326                              <1> DSKETTE_SETUP:
  8327                              <1> 	;PUSH	AX			; SAVE REGISTERS
  8328                              <1> 	;PUSH	BX
  8329                              <1> 	;PUSH	CX
  8330 00002900 52                  <1> 	PUSH	eDX
  8331                              <1> 	;PUSH	DI
  8332                              <1> 	;;PUSH	DS
  8333                              <1> 	; 14/12/2014
  8334                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  8335                              <1> 	;mov	[DISK_POINTER+2], cs
  8336                              <1> 	;
  8337                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  8338 00002901 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  8339 00002903 66C705[61790000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  8340 0000290B 00                  <1>
  8341 0000290C 8025[5C790000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  8342 00002913 800D[5C790000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  8343 0000291A C605[51790000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  8344 00002921 C605[53790000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  8345 00002928 C605[52790000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  8346 0000292F C605[54790000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  8347                              <1> 	;
  8348                              <1> 	; 28/02/2015
  8349                              <1> 	;mov	word [cfd], 100h 
  8350 00002936 E860F2FFFF          <1> 	call	DSK_RESET
  8351 0000293B 5A                  <1> 	pop	edx
  8352 0000293C C3                  <1> 	retn
  8353                              <1> 
  8354                              <1> ;SUP0:
  8355                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  8356                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  8357                              <1> ;	; 02/01/2015
  8358                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  8359                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  8360                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  8361                              <1> ;       cmp     byte [fd1_type], 0	
  8362                              <1> ;	jna	short sup1
  8363                              <1> ;	or	di, di
  8364                              <1> ;	jnz	short sup1
  8365                              <1> ;	inc	di
  8366                              <1> ;       jmp     short SUP0
  8367                              <1> ;sup1:
  8368                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  8369                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  8370                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  8371                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  8372                              <1> ;	;POP	DI
  8373                              <1> ;	POP	eDX
  8374                              <1> ;	;POP	CX
  8375                              <1> ;	;POP	BX
  8376                              <1> ;	;POP	AX
  8377                              <1> ;	RETn
  8378                              <1> 
  8379                              <1> ;//////////////////////////////////////////////////////
  8380                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8381                              <1> ;
  8382                              <1> 
  8383                              <1> int13h: ; 21/02/2015
  8384 0000293D 9C                  <1> 	pushfd
  8385 0000293E 0E                  <1> 	push 	cs
  8386 0000293F E859000000          <1> 	call 	DISK_IO
  8387 00002944 C3                  <1> 	retn
  8388                              <1> 
  8389                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  8390                              <1> ;/////////////////////////////////////////////////////////////////////
  8391                              <1> 
  8392                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  8393                              <1> ; 23/02/2015
  8394                              <1> ; 21/02/2015 (unix386.s)
  8395                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  8396                              <1> ;
  8397                              <1> ; Original Source Code:
  8398                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  8399                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  8400                              <1> ;
  8401                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  8402                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  8403                              <1> ;
  8404                              <1> 
  8405                              <1> 
  8406                              <1> ;The wait for controller to be not busy is 10 seconds.
  8407                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  8408                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  8409                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  8410                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  8411                              <1> 
  8412                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  8413                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  8414                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  8415                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  8416                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  8417                              <1> 
  8418                              <1> ;The wait for Data request on read and write longs is
  8419                              <1> ;2000 us. (?)
  8420                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  8421                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  8422                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  8423                              <1> 
  8424                              <1> ; Port 61h (PORT_B)
  8425                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  8426                              <1> 
  8427                              <1> ; 23/12/2014
  8428                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  8429                              <1> 
  8430                              <1> 
  8431                              <1> ;--- INT 13H -------------------------------------------------------------------
  8432                              <1> ;									       :
  8433                              <1> ; FIXED DISK I/O INTERFACE						       :
  8434                              <1> ;									       :
  8435                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  8436                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  8437                              <1> ;									       :
  8438                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  8439                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  8440                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  8441                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  8442                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  8443                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  8444                              <1> ;									       :
  8445                              <1> ;------------------------------------------------------------------------------:
  8446                              <1> ;									       :
  8447                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  8448                              <1> ;									       :
  8449                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  8450                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  8451                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  8452                              <1> ;			  DL > 80H - DISK				       :
  8453                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  8454                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  8455                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  8456                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  8457                              <1> ;	(AH)= 06H  UNUSED						       :
  8458                              <1> ;	(AH)= 07H  UNUSED						       :
  8459                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  8460                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  8461                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  8462                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  8463                              <1> ;	(AH)= 0AH  READ LONG						       :
  8464                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  8465                              <1> ;	(AH)= 0CH  SEEK 						       :
  8466                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  8467                              <1> ;	(AH)= 0EH  UNUSED						       :
  8468                              <1> ;	(AH)= 0FH  UNUSED						       :
  8469                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  8470                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  8471                              <1> ;	(AH)= 12H  UNUSED						       :
  8472                              <1> ;	(AH)= 13H  UNUSED						       :
  8473                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  8474                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  8475                              <1> ;									       :
  8476                              <1> ;-------------------------------------------------------------------------------
  8477                              <1> ;									       :
  8478                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  8479                              <1> ;									       :
  8480                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  8481                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  8482                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  8483                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  8484                              <1> ;									       :
  8485                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  8486                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  8487                              <1> ;				 (10 BITS TOTAL)			       :
  8488                              <1> ;									       :
  8489                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  8490                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  8491                              <1> ;									       :
  8492                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  8493                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  8494                              <1> ;									       :
  8495                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  8496                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  8497                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  8498                              <1> ;			       80H FOR A BAD SECTOR			       :
  8499                              <1> ;			   N = SECTOR NUMBER				       :
  8500                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  8501                              <1> ;			   THE TABLE SHOULD BE: 			       :
  8502                              <1> ;									       :
  8503                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  8504                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  8505                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  8506                              <1> ;									       :
  8507                              <1> ;-------------------------------------------------------------------------------
  8508                              <1> 
  8509                              <1> ;-------------------------------------------------------------------------------
  8510                              <1> ; OUTPUT								       :
  8511                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  8512                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  8513                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  8514                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  8515                              <1> ;									       :
  8516                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  8517                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  8518                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  8519                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  8520                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  8521                              <1> ;		REWRITTEN.						       :
  8522                              <1> ;									       :
  8523                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  8524                              <1> ;	   INPUT:							       :
  8525                              <1> ;	     (DL) = DRIVE NUMBER					       :
  8526                              <1> ;	   OUTPUT:							       :
  8527                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  8528                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  8529                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  8530                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  8531                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  8532                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  8533                              <1> ;									       :
  8534                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  8535                              <1> ;									       :
  8536                              <1> ;	AH = 0 - NOT PRESENT						       :
  8537                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  8538                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  8539                              <1> ;	     3 - FIXED DISK						       :
  8540                              <1> ;									       :
  8541                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  8542                              <1> ;									       :
  8543                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  8544                              <1> ;	INFORMATION.							       :
  8545                              <1> ;									       :
  8546                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  8547                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  8548                              <1> ;									       :
  8549                              <1> ;-------------------------------------------------------------------------------
  8550                              <1> 
  8551                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  8552                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  8553                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  8554                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  8555                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  8556                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  8557                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  8558                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  8559                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  8560                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  8561                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  8562                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  8563                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  8564                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  8565                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  8566                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  8567                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  8568                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  8569                              <1> 
  8570                              <1> ;--------------------------------------------------------
  8571                              <1> ;							:
  8572                              <1> ; FIXED DISK PARAMETER TABLE				:
  8573                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  8574                              <1> ;							:
  8575                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  8576                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  8577                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  8578                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  8579                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  8580                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  8581                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  8582                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  8583                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  8584                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  8585                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  8586                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  8587                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  8588                              <1> ;							:
  8589                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  8590                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  8591                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  8592                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  8593                              <1> ;							:
  8594                              <1> ;--------------------------------------------------------
  8595                              <1> 
  8596                              <1> ;--------------------------------------------------------
  8597                              <1> ;							:
  8598                              <1> ; HARDWARE SPECIFIC VALUES				:
  8599                              <1> ;							:
  8600                              <1> ;  -  CONTROLLER I/O PORT				:
  8601                              <1> ;							:
  8602                              <1> ;     > WHEN READ FROM: 				:
  8603                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  8604                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  8605                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  8606                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  8607                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  8608                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  8609                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  8610                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  8611                              <1> ;							:
  8612                              <1> ;     > WHEN WRITTEN TO:				:
  8613                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  8614                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  8615                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  8616                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  8617                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  8618                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  8619                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  8620                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  8621                              <1> ;							:
  8622                              <1> ;--------------------------------------------------------
  8623                              <1> 
  8624                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  8625                              <1> ;HF1_PORT	equ	0170h	
  8626                              <1> ;HF_REG_PORT	EQU	03F6H
  8627                              <1> ;HF1_REG_PORT	equ	0376h
  8628                              <1> 
  8629                              <1> HDC1_BASEPORT	equ	1F0h
  8630                              <1> HDC2_BASEPORT	equ	170h		
  8631                              <1> 
  8632 00002945 90                  <1> align 2
  8633                              <1> 
  8634                              <1> ;-----		STATUS REGISTER
  8635                              <1> 
  8636                              <1> ST_ERROR	EQU	00000001B	;
  8637                              <1> ST_INDEX	EQU	00000010B	;
  8638                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  8639                              <1> ST_DRQ		EQU	00001000B	;
  8640                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  8641                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  8642                              <1> ST_READY	EQU	01000000B	;
  8643                              <1> ST_BUSY 	EQU	10000000B	;
  8644                              <1> 
  8645                              <1> ;-----		ERROR REGISTER
  8646                              <1> 
  8647                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  8648                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  8649                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  8650                              <1> ;		EQU	00001000B	; NOT USED
  8651                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  8652                              <1> ;		EQU	00100000B	; NOT USED
  8653                              <1> ERR_DATA_ECC	EQU	01000000B
  8654                              <1> ERR_BAD_BLOCK	EQU	10000000B
  8655                              <1> 
  8656                              <1> 
  8657                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  8658                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  8659                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  8660                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  8661                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  8662                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  8663                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  8664                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  8665                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  8666                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  8667                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  8668                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  8669                              <1> 
  8670                              <1> ;MAX_FILE	EQU	2
  8671                              <1> ;S_MAX_FILE	EQU	2
  8672                              <1> MAX_FILE	equ	4		; 22/12/2014
  8673                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  8674                              <1> 
  8675                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  8676                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  8677                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  8678                              <1> 
  8679                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  8680                              <1> 
  8681                              <1> ;-----		COMMAND BLOCK REFERENCE
  8682                              <1> 
  8683                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  8684                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  8685                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  8686                              <1> ; 19/12/2014
  8687                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  8688                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  8689                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8690                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8691                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  8692                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  8693                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  8694                              <1> 
  8695                              <1> align 2
  8696                              <1> 
  8697                              <1> ;----------------------------------------------------------------
  8698                              <1> ; FIXED DISK I/O SETUP						:
  8699                              <1> ;								:
  8700                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  8701                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  8702                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  8703                              <1> ;								:
  8704                              <1> ;----------------------------------------------------------------
  8705                              <1> 
  8706                              <1> DISK_SETUP:
  8707                              <1> 	;CLI
  8708                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  8709                              <1> 	;xor	ax,ax
  8710                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  8711                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  8712                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  8713                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  8714                              <1> 	;MOV	[DISK_VECTOR+2],AX
  8715                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  8716                              <1> 	;MOV	[ORG_VECTOR+2],CS
  8717                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  8718                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  8719                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  8720                              <1> 	;;MOV	[HDISK_INT+2],CS
  8721                              <1> 	;mov	[HDISK_INT1+2],CS
  8722                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  8723                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  8724                              <1> 	;mov	[HDISK_INT2+2],CS
  8725                              <1> 	;
  8726                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  8727                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  8728                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  8729                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  8730                              <1> 	;push	cs
  8731                              <1> 	;pop	ds
  8732                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  8733                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  8734 00002946 C705[6C790000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  8735 0000294E 0900                <1>
  8736                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  8737                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  8738 00002950 C705[70790000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  8739 00002958 0900                <1>
  8740                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  8741                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  8742 0000295A C705[74790000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  8743 00002962 0900                <1>
  8744                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  8745                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  8746 00002964 C705[78790000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  8747 0000296C 0900                <1>
  8748                              <1> 	;
  8749                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  8750                              <1> 	;;;AND	AL,0BFH
  8751                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  8752                              <1> 	;;;JMP	$+2
  8753                              <1> 	;;IODELAY
  8754                              <1> 	;;OUT	INTB01,AL
  8755                              <1> 	;;IODELAY
  8756                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  8757                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  8758                              <1> 	;;;JMP	$+2
  8759                              <1> 	;;IODELAY
  8760                              <1> 	;;OUT	INTA01,AL
  8761                              <1> 	;
  8762                              <1> 	;STI
  8763                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  8764                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  8765                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  8766                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8767                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  8768                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  8769                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  8770                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  8771                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  8772                              <1> 	;mov	si, hd0_type
  8773 0000296E BE[B0750000]        <1> 	mov	esi, hd0_type
  8774                              <1> 	;mov	cx, 4
  8775 00002973 B904000000          <1> 	mov	ecx, 4
  8776                              <1> hde_l:
  8777 00002978 AC                  <1> 	lodsb
  8778 00002979 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  8779 0000297B 7206                <1> 	jb	short _L4
  8780 0000297D FE05[68790000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  8781                              <1> _L4: ; 26/02/2015
  8782 00002983 E2F3                <1> 	loop	hde_l	
  8783                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  8784                              <1> ;L4:
  8785                              <1> 	; 
  8786                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  8787                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  8788                              <1> 	;;mov 	cl, 3
  8789                              <1> 	;;
  8790                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  8791                              <1> ;;hdc_dl:
  8792                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  8793                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  8794                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  8795                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  8796                              <1> 	;;jnc	short hdc_reset0
  8797                              <1> 	;;loop	hdc_dl
  8798                              <1> 	;;; 27/12/2014
  8799                              <1> 	;;stc
  8800                              <1> 	;;retn
  8801                              <1> 	;
  8802                              <1> ;;hdc_reset0:
  8803                              <1> 	; 18/01/2015
  8804 00002985 8A0D[68790000]      <1> 	mov	cl, [HF_NUM]
  8805 0000298B 20C9                <1> 	and	cl, cl
  8806 0000298D 740D                <1> 	jz	short POD_DONE
  8807                              <1> 	;
  8808 0000298F B27F                <1> 	mov	dl, 7Fh
  8809                              <1> hdc_reset1:
  8810 00002991 FEC2                <1> 	inc	dl
  8811                              <1> 	;; 31/12/2015
  8812                              <1> 	;;push	dx
  8813                              <1> 	;;push	cx
  8814                              <1> 	;;push	ds
  8815                              <1> 	;;sub	ax, ax
  8816                              <1> 	;;mov	ds, ax
  8817                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  8818                              <1> 	;;pop	ds
  8819                              <1> 	;;MOV	BX,AX
  8820                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  8821                              <1> 	;;MOV	CX,AX
  8822                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  8823                              <1> 	;;
  8824                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  8825                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  8826                              <1> 	;;pop	cx
  8827                              <1> 	;;pop	dx
  8828                              <1> 	;;
  8829                              <1> 	; 18/01/2015
  8830 00002993 B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  8831                              <1> 	;int	13h
  8832 00002995 E8A3FFFFFF          <1> 	call	int13h
  8833 0000299A E2F5                <1> 	loop	hdc_reset1
  8834                              <1> POD_DONE:
  8835 0000299C C3                  <1> 	RETn
  8836                              <1> 
  8837                              <1> ;;-----	POD_ERROR
  8838                              <1> 
  8839                              <1> ;;CTL_ERRX:
  8840                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  8841                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  8842                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8843                              <1> ;	;JMP	short POD_DONE
  8844                              <1> 
  8845                              <1> ;;HD_RESET_1:
  8846                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  8847                              <1> ;;	;PUSH	CX
  8848                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  8849                              <1> ;;	INT	13H
  8850                              <1> ;;	JC	short RES_2
  8851                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  8852                              <1> ;;	INT	13H
  8853                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  8854                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  8855                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8856                              <1> ;;					; (30 seconds)		
  8857                              <1> ;;	;cmc
  8858                              <1> ;;	;JNC	short RES_1
  8859                              <1> ;;	jb	short RES_1
  8860                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  8861                              <1> ;;	;TEST	DL,1
  8862                              <1> ;;	;JNZ	RES_E1
  8863                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  8864                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  8865                              <1> ;;	;JMP	SHORT RES_E1
  8866                              <1> ;;RES_ER: ; 22/12/2014
  8867                              <1> ;;RES_OK:
  8868                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8869                              <1> ;;	;POP	BX
  8870                              <1> ;;	RETn
  8871                              <1> ;;
  8872                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  8873                              <1> ;;	INT	13H
  8874                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  8875                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  8876                              <1> ;;	INT	13H
  8877                              <1> ;;	JC	short RES_ER
  8878                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  8879                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  8880                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  8881                              <1> ;;	INT	13H
  8882                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  8883                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  8884                              <1> ;;	JE	short RES_OK
  8885                              <1> ;;	CMP	AH,DATA_CORRECTED
  8886                              <1> ;;	JE	short RES_OK
  8887                              <1> ;;	CMP	AH,BAD_ECC
  8888                              <1> ;;	JE	short RES_OK
  8889                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  8890                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8891                              <1> ;;					; (60 seconds)		
  8892                              <1> ;;	cmc
  8893                              <1> ;;	JC	short RES_ER		; FAILED
  8894                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  8895                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  8896                              <1> ;;	AND	AL,3FH
  8897                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  8898                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  8899                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  8900                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  8901                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  8902                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  8903                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  8904                              <1> ;;	;TEST	DL,1
  8905                              <1> ;;	;JNZ	short RES_E1
  8906                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  8907                              <1> ;;;RES_E1:
  8908                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8909                              <1> ;;;RES_OK:
  8910                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8911                              <1> ;;	;POP	BX
  8912                              <1> ;;	;RETn
  8913                              <1> ;
  8914                              <1> ;;SET_FAIL:
  8915                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  8916                              <1> ;	;CALL	CMOS_READ
  8917                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  8918                              <1> ;	;XCHG	AH,AL			; SAVE IT
  8919                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  8920                              <1> ;	;RETn
  8921                              <1> ;
  8922                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  8923                              <1> ;	;POP	AX			; SAVE RETURN
  8924                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  8925                              <1> ;	;POP	BX
  8926                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  8927                              <1> ;	;PUSH	CX
  8928                              <1> ;	;PUSH	AX
  8929                              <1> ;	;push	ds
  8930                              <1> ;	;xor	ax, ax
  8931                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  8932                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  8933                              <1> ;	;				; BX = START TIME
  8934                              <1> ;	;				; CX = END TIME
  8935                              <1> ;	;pop	ds
  8936                              <1> ;	;CMP	BX,CX
  8937                              <1> ;	;JB	short TCHK1		; START < END
  8938                              <1> ;	;CMP	BX,AX
  8939                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  8940                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  8941                              <1> ;;TCHK1: CMP	AX,BX
  8942                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  8943                              <1> ;;TCHK2: CMP	AX,CX
  8944                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  8945                              <1> ;;					; OR CURRENT < END < START
  8946                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  8947                              <1> ;;	RETn
  8948                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  8949                              <1> ;;	RETn
  8950                              <1> ;;
  8951                              <1> ;;int_13h:
  8952                              <1> 
  8953                              <1> ;----------------------------------------
  8954                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  8955                              <1> ;----------------------------------------
  8956                              <1> 
  8957                              <1> DISK_IO:
  8958 0000299D 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  8959                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  8960                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  8961                              <1> 	;;call	int40h
  8962 000029A0 0F8225F1FFFF        <1> 	jb	DISKETTE_IO_1
  8963                              <1> ;RET_2:
  8964                              <1> 	;RETf	2			; BACK TO CALLER
  8965                              <1> ;	retf	4
  8966                              <1> A1:
  8967 000029A6 FB                  <1> 	STI				; ENABLE INTERRUPTS
  8968                              <1> 	;; 04/01/2015
  8969                              <1> 	;;OR	AH,AH
  8970                              <1> 	;;JNZ	short A2
  8971                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  8972                              <1> 	;;SUB	AH,AH
  8973 000029A7 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  8974 000029AA 772C                <1> 	JA	short RET_2
  8975                              <1> 	; 18/01/2015
  8976 000029AC 08E4                <1> 	or	ah,ah
  8977 000029AE 742B                <1> 	jz	short A4
  8978 000029B0 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  8979 000029B3 7504                <1> 	jne	short A2
  8980 000029B5 28E4                <1> 	sub	ah,ah	; Reset
  8981 000029B7 EB22                <1> 	jmp	short A4
  8982                              <1> A2:
  8983 000029B9 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  8984                              <1> 	;JNZ	short A3
  8985                              <1>         ;JMP    GET_PARM_N
  8986 000029BC 0F841C030000        <1> 	je	GET_PARM_N
  8987 000029C2 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  8988                              <1> 	;JNZ	short A4
  8989                              <1>         ;JMP    READ_DASD_TYPE
  8990 000029C5 0F84C7020000        <1>         je      READ_DASD_TYPE
  8991                              <1> 	; 02/02/2015
  8992 000029CB 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  8993                              <1> 	; 12/01/2015
  8994 000029CE F5                  <1> 	cmc
  8995 000029CF 730A                <1> 	jnc	short A4
  8996                              <1> 	; 30/01/2015
  8997                              <1> 	;mov     byte [CS:DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  8998 000029D1 C605[67790000]01    <1>         mov     byte [DISK_STATUS1], BAD_CMD
  8999                              <1> 	;jmp	short RET_2
  9000                              <1> RET_2:
  9001 000029D8 CA0400              <1> 	retf	4
  9002                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  9003 000029DB C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  9004 000029DF 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  9005 000029E0 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  9006 000029E1 52                  <1> 	PUSH	eDX
  9007 000029E2 1E                  <1> 	PUSH	DS
  9008 000029E3 06                  <1> 	PUSH	ES
  9009 000029E4 56                  <1> 	PUSH	eSI
  9010 000029E5 57                  <1> 	PUSH	eDI
  9011                              <1> 	;;04/01/2015
  9012                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  9013                              <1> 	;;JNZ	short A5
  9014                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  9015                              <1> ;;A5:	
  9016                              <1> 	;push	cs
  9017                              <1> 	;pop	ds
  9018                              <1> 	; 21/02/2015
  9019 000029E6 6650                <1> 	push	ax
  9020 000029E8 66B81000            <1> 	mov	ax, KDATA
  9021 000029EC 8ED8                <1> 	mov	ds, ax
  9022 000029EE 8EC0                <1> 	mov	es, ax	
  9023 000029F0 6658                <1> 	pop	ax
  9024 000029F2 E889000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  9025                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  9026 000029F7 8A25[67790000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  9027 000029FD 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  9028 00002A00 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  9029 00002A01 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  9030 00002A02 5E                  <1> 	POP	eSI
  9031 00002A03 07                  <1>         POP     ES
  9032 00002A04 1F                  <1>         POP     DS
  9033 00002A05 5A                  <1> 	POP	eDX
  9034 00002A06 59                  <1> 	POP	eCX
  9035 00002A07 5B                  <1> 	POP	eBX
  9036 00002A08 C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  9037                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  9038 00002A09 CA0400              <1> 	retf	4
  9039                              <1> 
  9040                              <1> ; 21/02/2015
  9041                              <1> ;       dw --> dd
  9042                              <1> D1:					; FUNCTION TRANSFER TABLE
  9043 00002A0C [CE2B0000]          <1> 	dd	DISK_RESET		; 000H
  9044 00002A10 [452C0000]          <1> 	dd	RETURN_STATUS		; 001H
  9045 00002A14 [522C0000]          <1> 	dd	DISK_READ		; 002H
  9046 00002A18 [5B2C0000]          <1> 	dd	DISK_WRITE		; 003H
  9047 00002A1C [642C0000]          <1> 	dd	DISK_VERF		; 004H
  9048 00002A20 [7C2C0000]          <1> 	dd	FMT_TRK 		; 005H
  9049 00002A24 [C42B0000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  9050 00002A28 [C42B0000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  9051 00002A2C [C42B0000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  9052 00002A30 [432D0000]          <1> 	dd	INIT_DRV		; 009H
  9053 00002A34 [A22D0000]          <1> 	dd	RD_LONG 		; 00AH
  9054 00002A38 [AB2D0000]          <1> 	dd	WR_LONG 		; 00BH
  9055 00002A3C [B42D0000]          <1> 	dd	DISK_SEEK		; 00CH
  9056 00002A40 [CE2B0000]          <1> 	dd	DISK_RESET		; 00DH
  9057 00002A44 [C42B0000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  9058 00002A48 [C42B0000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  9059 00002A4C [DC2D0000]          <1> 	dd	TST_RDY 		; 010H
  9060 00002A50 [002E0000]          <1> 	dd	HDISK_RECAL		; 011H
  9061 00002A54 [C42B0000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  9062 00002A58 [C42B0000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  9063 00002A5C [362E0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  9064                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  9065 00002A60 [C42B0000]          <1> 	dd	BAD_COMMAND		; 015h
  9066 00002A64 [C42B0000]          <1> 	dd	BAD_COMMAND		; 016h
  9067 00002A68 [C42B0000]          <1> 	dd	BAD_COMMAND		; 017h
  9068 00002A6C [C42B0000]          <1> 	dd	BAD_COMMAND		; 018h
  9069 00002A70 [C42B0000]          <1> 	dd	BAD_COMMAND		; 019h
  9070 00002A74 [C42B0000]          <1> 	dd	BAD_COMMAND		; 01Ah
  9071 00002A78 [522C0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  9072 00002A7C [5B2C0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  9073                              <1> D1L     EQU    $ - D1
  9074                              <1> 
  9075                              <1> DISK_IO_CONT:
  9076                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  9077 00002A80 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  9078                              <1> 	;;JNZ	short SU0
  9079                              <1>         ;;JMP    RETURN_STATUS
  9080 00002A83 0F84BC010000        <1> 	je	RETURN_STATUS
  9081                              <1> SU0:
  9082 00002A89 C605[67790000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  9083                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  9084                              <1> 	;mov	si, bx ;; 14/02/2015
  9085 00002A90 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  9086 00002A92 8A1D[68790000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  9087                              <1> 	;; 04/01/2015
  9088                              <1> 	;;PUSH	AX
  9089 00002A98 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  9090                              <1> 					; (get drive number as 0 to 3)
  9091 00002A9B 38D3                <1> 	CMP	BL,DL
  9092                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  9093 00002A9D 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  9094                              <1>         ;
  9095                              <1> 	;;03/01/2015
  9096 00002AA3 29DB                <1> 	sub	ebx, ebx
  9097 00002AA5 88D3                <1> 	mov	bl, dl
  9098                              <1> 	;sub	bh, bh
  9099 00002AA7 883D[7C790000]      <1> 	mov	[LBAMode], bh 	; 0
  9100                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  9101                              <1> 	;test	byte [ebx+hd0_type], 1
  9102                              <1> 	;jz	short su1		; no
  9103                              <1> 	;inc	byte [LBAMode]
  9104                              <1> ;su1:
  9105                              <1> 	; 21/02/2015 (32 bit modification)
  9106                              <1> 	;04/01/2015
  9107 00002AAD 6650                <1> 	push	ax ; ***
  9108                              <1> 	;PUSH	ES ; **
  9109 00002AAF 6652                <1> 	PUSH	DX ; *
  9110 00002AB1 6650                <1> 	push	ax
  9111 00002AB3 E85C060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  9112                              <1> 	; 02/02/2015
  9113                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  9114 00002AB8 668B4310            <1> 	mov	ax, [ebx+16]
  9115 00002ABC 66A3[74730000]      <1> 	mov	[HF_PORT], ax
  9116                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  9117 00002AC2 668B5312            <1> 	mov	dx, [ebx+18]
  9118 00002AC6 668915[76730000]    <1> 	mov	[HF_REG_PORT], dx
  9119                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  9120 00002ACD 8A4314              <1> 	mov	al, [ebx+20]
  9121                              <1> 	; 23/02/2015
  9122 00002AD0 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  9123 00002AD2 7406                <1> 	jz 	short su1
  9124 00002AD4 FE05[7C790000]      <1> 	inc	byte [LBAMode] ; 1 
  9125                              <1> su1: 	 
  9126 00002ADA C0E804              <1> 	shr 	al, 4
  9127 00002ADD 2401                <1> 	and	al, 1			
  9128 00002ADF A2[78730000]        <1> 	mov	[hf_m_s], al 
  9129                              <1> 	;
  9130                              <1> 	; 03/01/2015
  9131                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  9132 00002AE4 8A4308              <1> 	mov	al, [ebx+8]
  9133                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  9134 00002AE7 EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  9135                              <1> 					; Control Byte:  (= 08h, here)
  9136                              <1> 					; bit 0 - 0
  9137                              <1> 					; bit 1 - nIEN (1 = disable irq)
  9138                              <1> 					; bit 2 - SRST (software RESET)
  9139                              <1> 					; bit 3 - use extra heads (8 to 15)
  9140                              <1> 					;         -always set to 1-	
  9141                              <1> 					; (bits 3 to 7 are reserved
  9142                              <1> 					;          for ATA devices)
  9143 00002AE8 8A25[69790000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  9144 00002AEE 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  9145 00002AF1 08C4                <1> 	OR	AH,AL
  9146 00002AF3 8825[69790000]      <1> 	MOV	[CONTROL_BYTE],AH	
  9147                              <1> 	; 04/01/2015
  9148 00002AF9 6658                <1> 	pop	ax
  9149 00002AFB 665A                <1> 	pop	dx ; * ;; 14/02/2015
  9150 00002AFD 20E4                <1> 	and	ah, ah	; Reset function ?
  9151 00002AFF 7507                <1> 	jnz	short su2
  9152                              <1> 	;;pop	dx ; * ;; 14/02/2015
  9153                              <1> 	;pop	es ; **
  9154 00002B01 6658                <1> 	pop	ax ; ***
  9155                              <1> 	;;pop	bx
  9156 00002B03 E9C6000000          <1>         jmp     DISK_RESET
  9157                              <1> su2:
  9158 00002B08 803D[7C790000]00    <1> 	cmp	byte [LBAMode], 0
  9159 00002B0F 7661                <1> 	jna	short su3
  9160                              <1> 	;
  9161                              <1> 	; 02/02/2015 (LBA read/write function calls)
  9162 00002B11 80FC1B              <1> 	cmp	ah, 1Bh
  9163 00002B14 720B                <1> 	jb	short lbarw1
  9164 00002B16 80FC1C              <1> 	cmp	ah, 1Ch
  9165 00002B19 775C                <1> 	ja 	short invldfnc
  9166                              <1> 	;;pop	dx ; * ; 14/02/2015
  9167                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  9168 00002B1B 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  9169                              <1> 	;; 14/02/2015
  9170 00002B1D 88D1                <1> 	mov	cl, dl ; 14/02/2015
  9171                              <1> 	;;mov	dx, bx
  9172                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  9173                              <1> 	;;mov	bx, di
  9174                              <1> 	;mov	si, di ; Buffer offset
  9175 00002B1F EB31                <1> 	jmp	short lbarw2
  9176                              <1> lbarw1:
  9177                              <1> 	; convert CHS to LBA
  9178                              <1> 	;
  9179                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  9180                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  9181                              <1> 	;	+ Sector - 1
  9182 00002B21 6652                <1> 	push	dx ; * ;; 14/02/2015
  9183                              <1> 	;xor	dh, dh
  9184 00002B23 31D2                <1> 	xor	edx, edx
  9185                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  9186 00002B25 8A530E              <1> 	mov	dl, [ebx+14]
  9187                              <1> 	;xor	ah, ah
  9188 00002B28 31C0                <1> 	xor	eax, eax
  9189                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  9190 00002B2A 8A4302              <1> 	mov	al, [ebx+2]
  9191 00002B2D FEC8                <1> 	dec	al
  9192 00002B2F 6640                <1> 	inc	ax		; 0 =  256
  9193 00002B31 66F7E2              <1> 	mul 	dx
  9194                              <1> 		; AX = # of Heads" * Sectors/Track
  9195 00002B34 6689CA              <1> 	mov	dx, cx
  9196                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  9197 00002B37 83E13F              <1> 	and	ecx, 3fh
  9198 00002B3A 86D6                <1> 	xchg	dl, dh
  9199 00002B3C C0EE06              <1> 	shr	dh, 6
  9200                              <1> 		; DX = cylinder (0 to 1023)
  9201                              <1> 	;mul 	dx
  9202                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  9203 00002B3F F7E2                <1> 	mul	edx
  9204 00002B41 FEC9                <1> 	dec	cl  ; sector - 1
  9205                              <1> 	;add	ax, cx
  9206                              <1> 	;adc	dx, 0
  9207                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  9208 00002B43 01C8                <1> 	add	eax, ecx
  9209 00002B45 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  9210                              <1> 	;push	dx
  9211                              <1> 	;push	ax
  9212 00002B47 50                  <1> 	push	eax
  9213                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  9214 00002B48 8A430E              <1> 	mov	al, [ebx+14]
  9215 00002B4B F6E5                <1> 	mul	ch
  9216                              <1> 		;  AX = Head * Sectors/Track
  9217 00002B4D 6699                <1>         cwd
  9218                              <1> 	;pop	dx
  9219 00002B4F 5A                  <1> 	pop	edx
  9220                              <1> 	;add	ax, dx
  9221                              <1> 	;pop	dx
  9222                              <1> 	;adc	dx, 0 ; add carry bit
  9223 00002B50 01D0                <1> 	add	eax, edx
  9224                              <1> lbarw2:
  9225 00002B52 29D2                <1> 	sub	edx, edx ; 21/02/2015
  9226 00002B54 88CA                <1> 	mov	dl, cl ; 21/02/2015
  9227 00002B56 C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  9228                              <1> 				; NOTE: Features register (1F1h, 171h)
  9229                              <1> 				; is not used for ATA device R/W functions. 
  9230                              <1> 				; It is old/obsolete 'write precompensation'
  9231                              <1> 				; register and error register
  9232                              <1> 				; for old ATA/IDE devices.
  9233                              <1> 	; 18/01/2014
  9234                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  9235 00002B5A 8A0D[78730000]      <1> 	mov	cl, [hf_m_s]
  9236                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  9237                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  9238                              <1> 				; bit 6 = 1 = LBA mode
  9239                              <1> 				; bit 7 = 1
  9240 00002B60 80C90E              <1> 	or	cl, 0Eh ; 1110b
  9241                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  9242 00002B63 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  9243 00002B68 C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  9244                              <1> 	;or	dh, ch
  9245 00002B6B 09C8                <1> 	or	eax, ecx	
  9246                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  9247                              <1> 				  ; (Sector Number Register)
  9248                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  9249                              <1> 				  ; (Cylinder Low Register)
  9250                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  9251                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  9252                              <1> 				  ; (Cylinder High Register)
  9253                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  9254                              <1> 				  ; (Drive/Head Register)
  9255                              <1> 	
  9256                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  9257 00002B6D 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  9258                              <1> 	;14/02/2015
  9259                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  9260 00002B70 EB38                <1> 	jmp	short su4
  9261                              <1> su3:
  9262                              <1> 	; 02/02/2015 
  9263                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  9264 00002B72 80FC14              <1> 	cmp 	ah, 14h
  9265 00002B75 7604                <1> 	jna 	short chsfnc
  9266                              <1> invldfnc:
  9267                              <1>         ; 14/02/2015  
  9268                              <1> 	;pop	es ; **
  9269 00002B77 6658                <1>         pop     ax ; ***
  9270                              <1>         ;jmp     short BAD_COMMAND_POP
  9271 00002B79 EB49                <1>         jmp     short BAD_COMMAND
  9272                              <1> chsfnc:	
  9273                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  9274 00002B7B 668B4305            <1> 	mov	ax, [ebx+5]
  9275 00002B7F 66C1E802            <1> 	SHR	AX,2
  9276 00002B83 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  9277                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  9278                              <1> 	;;PUSH	DX
  9279                              <1> 	;;MOV	DX,[HF_REG_PORT]
  9280                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  9281                              <1> 	;;POP	DX ; * 
  9282                              <1> 	;;POP	ES ; **
  9283                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  9284                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  9285                              <1> 	;;OR	AH,AL
  9286                              <1> 	;;MOV	[CONTROL_BYTE],AH
  9287                              <1> 	;
  9288 00002B86 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  9289 00002B88 243F                <1> 	AND	AL,3FH
  9290 00002B8A 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  9291 00002B8D 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  9292 00002B90 88C8                <1> 	MOV	AL,CL
  9293 00002B92 C0E806              <1> 	SHR	AL,6
  9294 00002B95 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  9295                              <1> 	;;05/01/2015
  9296                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  9297 00002B98 A0[78730000]        <1> 	mov	al, [hf_m_s]
  9298 00002B9D C0E004              <1> 	SHL	AL,4
  9299 00002BA0 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  9300 00002BA3 08F0                <1> 	OR	AL,DH
  9301                              <1> 	;OR	AL,80H or 20H
  9302 00002BA5 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  9303 00002BA7 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  9304                              <1> su4:
  9305                              <1> 	;POP	ES ; **
  9306                              <1>         ;; 14/02/2015
  9307                              <1>         ;;POP   AX
  9308                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  9309                              <1>         ;;PUSH  AX
  9310                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  9311                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  9312                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  9313 00002BAA 6658                <1>         pop     ax ; ***
  9314 00002BAC 8845F9              <1>         mov     [CMD_BLOCK+1], al
  9315 00002BAF 29DB                <1>         sub	ebx, ebx
  9316 00002BB1 88E3                <1> 	mov     bl, ah
  9317                              <1>         ;xor     bh, bh
  9318                              <1>         ;sal     bx, 1
  9319 00002BB3 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  9320                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  9321                              <1>         ;;CMP   AX,D1L                  ; TEST WITHIN RANGE
  9322                              <1>         ;;JNB   short BAD_COMMAND_POP
  9323                              <1>         ;cmp     bx, D1L
  9324 00002BB7 83FB74              <1> 	cmp	ebx, D1L
  9325 00002BBA 7308                <1> 	jnb	short BAD_COMMAND
  9326                              <1>         ;xchg    bx, si
  9327 00002BBC 87DE                <1>         xchg	ebx, esi
  9328                              <1> 	;;;POP	AX			; RESTORE AX
  9329                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  9330                              <1> 	
  9331                              <1> 	;;PUSH	CX
  9332                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  9333                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  9334                              <1> 	;SHR	CX,4
  9335                              <1> 	;MOV	AX,ES
  9336                              <1> 	;ADD	AX,CX
  9337                              <1> 	;MOV	ES,AX
  9338                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  9339                              <1> 	;;POP	AX
  9340                              <1> 	;;POP	CX
  9341                              <1> 	;;JMP	word [CS:SI+D1]
  9342                              <1> 	;jmp	word [SI+D1]
  9343 00002BBE FFA6[0C2A0000]      <1> 	jmp	dword [esi+D1]
  9344                              <1> ;;BAD_COMMAND_POP:
  9345                              <1> ;;	POP	AX
  9346                              <1> ;;	POP	BX
  9347                              <1> BAD_COMMAND:
  9348 00002BC4 C605[67790000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  9349 00002BCB B000                <1> 	MOV	AL,0
  9350 00002BCD C3                  <1> 	RETn
  9351                              <1> 
  9352                              <1> ;----------------------------------------
  9353                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  9354                              <1> ;----------------------------------------
  9355                              <1> 
  9356                              <1> ; 18-1-2015 : one controller reset (not other one)
  9357                              <1> 
  9358                              <1> DISK_RESET:
  9359 00002BCE FA                  <1> 	CLI
  9360 00002BCF E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  9361                              <1> 	;JMP	$+2
  9362                              <1> 	IODELAY
  9363 00002BD1 EB00                <2>  jmp short $+2
  9364 00002BD3 EB00                <2>  jmp short $+2
  9365                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  9366 00002BD5 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  9367 00002BD7 E6A1                <1> 	OUT	INTB01,AL
  9368 00002BD9 FB                  <1> 	STI				; START INTERRUPTS
  9369                              <1> 	; 14/02/2015
  9370 00002BDA 6689D7              <1> 	mov	di, dx	
  9371                              <1> 	; 04/01/2015
  9372                              <1> 	;xor	di,di
  9373                              <1> drst0:
  9374 00002BDD B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  9375                              <1> 	;MOV	DX,HF_REG_PORT
  9376 00002BDF 668B15[76730000]    <1> 	MOV	DX,[HF_REG_PORT]
  9377 00002BE6 EE                  <1> 	OUT	DX,AL			; RESET
  9378                              <1> ;	MOV	CX,10			; DELAY COUNT
  9379                              <1> ;DRD:	DEC	CX
  9380                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  9381                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  9382 00002BE7 B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  9383 00002BEC E871EDFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  9384                              <1>                                         ; 40 micro seconds)
  9385 00002BF1 A0[69790000]        <1> 	mov	al,[CONTROL_BYTE]
  9386 00002BF6 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  9387 00002BF8 EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  9388 00002BF9 E80E040000          <1> 	CALL	NOT_BUSY
  9389 00002BFE 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  9390 00002C00 668B15[74730000]    <1> 	MOV	DX,[HF_PORT]
  9391 00002C07 FEC2                <1> 	inc	dl  ; HF_PORT+1
  9392                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  9393                              <1>         ;mov     cl, 10
  9394 00002C09 B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  9395                              <1> drst1:
  9396 00002C0E EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  9397 00002C0F 3C01                <1> 	CMP	AL,1
  9398                              <1> 	; 04/01/2015
  9399 00002C11 740A                <1> 	jz	short drst2
  9400                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  9401                              <1>         	; Drive/Head Register - bit 4
  9402 00002C13 E2F9                <1> 	loop	drst1
  9403                              <1> DRERR:	
  9404 00002C15 C605[67790000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  9405 00002C1C C3                  <1> 	RETn
  9406                              <1> drst2:
  9407                              <1> 	; 14/02/2015
  9408 00002C1D 6689FA              <1> 	mov	dx,di
  9409                              <1> ;drst3:
  9410                              <1> ;	; 05/01/2015
  9411                              <1> ;	shl 	di,1
  9412                              <1> ;	; 04/01/2015
  9413                              <1> ;	mov	ax,[di+hd_cports]
  9414                              <1> ;	cmp	ax,[HF_REG_PORT]
  9415                              <1> ;	je	short drst4
  9416                              <1> ;	mov	[HF_REG_PORT], ax
  9417                              <1> ;	; 03/01/2015
  9418                              <1> ;	mov	ax,[di+hd_ports]
  9419                              <1> ;       mov     [HF_PORT], ax
  9420                              <1> ;	; 05/01/2014
  9421                              <1> ;	shr	di,1
  9422                              <1> ;	; 04/01/2015
  9423                              <1> ;	jmp	short drst0	; reset other controller
  9424                              <1> ;drst4:
  9425                              <1> ;	; 05/01/2015
  9426                              <1> ;	shr	di,1
  9427                              <1> ;	mov	al,[di+hd_dregs]
  9428                              <1> ;	and	al,10h ; bit 4 only
  9429                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  9430                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  9431                              <1> 	;
  9432 00002C20 A0[78730000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  9433 00002C25 A801                <1> 	test	al,1
  9434                              <1> ;	jnz	short drst6
  9435 00002C27 7516                <1>         jnz     short drst4
  9436 00002C29 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  9437                              <1> ;drst5:
  9438                              <1> drst3:
  9439 00002C2D E811010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  9440                              <1> 	;mov	dx,di
  9441 00002C32 E8C9010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  9442                              <1> 	; 04/01/2014
  9443                              <1> ;	inc	di
  9444                              <1> ;	mov	dx,di
  9445                              <1> ;	cmp	dl,[HF_NUM]
  9446                              <1> ;	jb	short drst3
  9447                              <1> ;DRE:
  9448 00002C37 C605[67790000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  9449 00002C3E C3                  <1> 	RETn
  9450                              <1> ;drst6:
  9451                              <1> drst4:		; Drive/Head Register - bit 4
  9452 00002C3F 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  9453                              <1>         ;jmp    short drst5
  9454 00002C43 EBE8                <1>         jmp     short drst3
  9455                              <1> 
  9456                              <1> ;----------------------------------------
  9457                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  9458                              <1> ;----------------------------------------
  9459                              <1> 
  9460                              <1> RETURN_STATUS:
  9461 00002C45 A0[67790000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  9462 00002C4A C605[67790000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  9463 00002C51 C3                  <1> 	RETn
  9464                              <1> 
  9465                              <1> ;----------------------------------------
  9466                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  9467                              <1> ;----------------------------------------
  9468                              <1> 
  9469                              <1> DISK_READ:
  9470 00002C52 C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  9471 00002C56 E930020000          <1>         JMP     COMMANDI
  9472                              <1> 
  9473                              <1> ;----------------------------------------
  9474                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  9475                              <1> ;----------------------------------------
  9476                              <1> 
  9477                              <1> DISK_WRITE:
  9478 00002C5B C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  9479 00002C5F E97C020000          <1>         JMP     COMMANDO
  9480                              <1> 
  9481                              <1> ;----------------------------------------
  9482                              <1> ;	DISK VERIFY	     (AH = 04H) :
  9483                              <1> ;----------------------------------------
  9484                              <1> 
  9485                              <1> DISK_VERF:
  9486 00002C64 C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  9487 00002C68 E8EA020000          <1> 	CALL	COMMAND
  9488 00002C6D 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  9489 00002C6F E85C030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  9490 00002C74 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  9491 00002C76 E8E9030000          <1> 	CALL	CHECK_STATUS
  9492                              <1> VERF_EXIT:
  9493 00002C7B C3                  <1> 	RETn
  9494                              <1> 
  9495                              <1> ;----------------------------------------
  9496                              <1> ;	FORMATTING	     (AH = 05H) :
  9497                              <1> ;----------------------------------------
  9498                              <1> 
  9499                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  9500 00002C7C C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  9501                              <1> 	;PUSH	ES
  9502                              <1> 	;PUSH	BX
  9503 00002C80 53                  <1> 	push	ebx
  9504 00002C81 E88E040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  9505                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  9506 00002C86 8A430E              <1> 	mov	al, [ebx+14]
  9507 00002C89 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  9508 00002C8C 5B                  <1> 	pop	ebx
  9509                              <1> 	;POP	BX
  9510                              <1> 	;POP	ES
  9511 00002C8D E955020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  9512                              <1> 
  9513                              <1> ;----------------------------------------
  9514                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  9515                              <1> ;----------------------------------------
  9516                              <1> 
  9517                              <1> READ_DASD_TYPE:
  9518                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  9519 00002C92 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9520                              <1> 	;PUSH	ES
  9521 00002C93 53                  <1> 	PUSH	eBX
  9522                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  9523                              <1> 	;push	cs
  9524                              <1> 	;pop	ds
  9525 00002C94 66BB1000            <1>         mov	bx, KDATA
  9526 00002C98 8EDB                <1> 	mov	ds, bx
  9527                              <1> 	;mov	es, bx
  9528 00002C9A C605[67790000]00    <1> 	MOV     byte [DISK_STATUS1],0
  9529 00002CA1 8A1D[68790000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  9530 00002CA7 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  9531 00002CAA 38D3                <1> 	CMP	BL,DL
  9532 00002CAC 7625                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  9533 00002CAE E861040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  9534                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  9535 00002CB3 8A4302              <1> 	mov	al, [ebx+2]
  9536                              <1> 	;MOV	CL,[ES:BX+14]
  9537 00002CB6 8A4B0E              <1> 	mov	cl, [ebx+14]
  9538 00002CB9 F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  9539                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  9540 00002CBB 668B0B              <1> 	mov	cx ,[ebx]
  9541                              <1> 	;
  9542                              <1> 	; 02/01/2015 
  9543                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  9544                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  9545 00002CBE 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  9546                              <1> 	;
  9547 00002CC0 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  9548 00002CC3 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  9549 00002CC6 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  9550                              <1> 	;SUB	AX,AX
  9551 00002CC9 28C0                <1> 	sub	al, al
  9552 00002CCB B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  9553 00002CCD 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  9554                              <1> 	;POP	ES
  9555 00002CCE 1F                  <1> 	POP	DS
  9556 00002CCF F8                  <1> 	CLC				; CLEAR CARRY
  9557                              <1> 	;RETf	2
  9558 00002CD0 CA0400              <1> 	retf	4
  9559                              <1> RDT_NOT_PRESENT:
  9560 00002CD3 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  9561 00002CD6 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  9562 00002CD9 6689C2              <1> 	MOV	DX,AX
  9563 00002CDC EBEF                <1> 	JMP	short RDT2
  9564                              <1> 
  9565                              <1> ;----------------------------------------
  9566                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  9567                              <1> ;----------------------------------------
  9568                              <1> 
  9569                              <1> GET_PARM_N:
  9570                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  9571 00002CDE 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9572                              <1> 	;PUSH	ES
  9573 00002CDF 53                  <1> 	PUSH	eBX
  9574                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  9575                              <1> 	;MOV	DS,AX
  9576                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  9577                              <1> 	;JZ	short G0
  9578                              <1> 	;LES	BX,@HF1_TBL_VEC
  9579                              <1> 	;JMP	SHORT G1
  9580                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  9581                              <1> ;G1:
  9582                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  9583                              <1> 	; 22/12/2014
  9584                              <1> 	;push	cs
  9585                              <1> 	;pop	ds
  9586 00002CE0 66BB1000            <1> 	mov	bx, KDATA
  9587 00002CE4 8EDB                <1> 	mov	ds, bx
  9588                              <1> 	;mov	es, bx
  9589                              <1> 	;
  9590 00002CE6 80EA80              <1> 	SUB	DL,80H
  9591 00002CE9 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  9592 00002CEC 7341                <1> 	JAE	short G4
  9593                              <1> 	;
  9594 00002CEE 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  9595                              <1> 	; 22/12/2014
  9596 00002CF0 88D3                <1> 	mov	bl, dl
  9597                              <1> 	;xor	bh, bh  
  9598 00002CF2 C0E302              <1> 	shl	bl, 2			; convert index to offset
  9599                              <1> 	;add	bx, HF_TBL_VEC
  9600 00002CF5 81C3[6C790000]      <1> 	add	ebx, HF_TBL_VEC
  9601                              <1> 	;mov	ax, [bx+2]
  9602                              <1> 	;mov	es, ax			; dpt segment
  9603                              <1> 	;mov	bx, [bx]		; dpt offset
  9604 00002CFB 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  9605                              <1> 
  9606 00002CFD C605[67790000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9607                              <1>         ;MOV     AX,[ES:BX]              ; MAX NUMBER OF CYLINDERS
  9608 00002D04 668B03              <1> 	mov	ax, [ebx]
  9609                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  9610 00002D07 6648                <1> 	dec	ax			; max. cylinder number
  9611 00002D09 88C5                <1> 	MOV	CH,AL
  9612 00002D0B 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  9613 00002D0F 66D1E8              <1> 	SHR	AX,1
  9614 00002D12 66D1E8              <1> 	SHR	AX,1
  9615                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  9616 00002D15 0A430E              <1> 	or	al, [ebx+14]
  9617 00002D18 88C1                <1> 	MOV	CL,AL
  9618                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  9619 00002D1A 8A7302              <1> 	mov	dh, [ebx+2]
  9620 00002D1D FECE                <1> 	DEC	DH			; 0-N RANGE
  9621 00002D1F 8A15[68790000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  9622 00002D25 6629C0              <1> 	SUB	AX,AX
  9623                              <1>         ;27/12/2014 
  9624                              <1> 	; ES:DI = Address of disk parameter table from BIOS
  9625                              <1> 	;(Programmer's Guide to the AMIBIOS - 1993)
  9626                              <1> 	;mov	di, bx			; HDPT offset
  9627 00002D28 89DF                <1> 	mov	edi, ebx
  9628                              <1> G5:
  9629 00002D2A 5B                  <1> 	POP	eBX			; RESTORE REGISTERS
  9630                              <1> 	;POP	ES
  9631 00002D2B 1F                  <1> 	POP	DS
  9632                              <1> 	;RETf	2
  9633 00002D2C CA0400              <1> 	retf	4
  9634                              <1> G4:
  9635 00002D2F C605[67790000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  9636 00002D36 B407                <1> 	MOV	AH,INIT_FAIL
  9637 00002D38 28C0                <1> 	SUB	AL,AL
  9638 00002D3A 6629D2              <1> 	SUB	DX,DX
  9639 00002D3D 6629C9              <1> 	SUB	CX,CX
  9640 00002D40 F9                  <1> 	STC				; SET ERROR FLAG
  9641 00002D41 EBE7                <1> 	JMP	short G5
  9642                              <1> 
  9643                              <1> ;----------------------------------------
  9644                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  9645                              <1> ;----------------------------------------
  9646                              <1> 	; 03/01/2015
  9647                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  9648                              <1> 	; logical sector per logical track
  9649                              <1> 	; and logical heads - 1 would be set but
  9650                              <1> 	; it is seen as it will be good
  9651                              <1> 	; if physical parameters will be set here
  9652                              <1> 	; because, number of heads <= 16.
  9653                              <1> 	; (logical heads usually more than 16)
  9654                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  9655                              <1> 	;	== INT 13h physical parameters
  9656                              <1> 
  9657                              <1> ;INIT_DRV:
  9658                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  9659                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  9660                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  9661                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  9662                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  9663                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  9664                              <1> ;	OR	AH,AL			; TO MAX HEAD
  9665                              <1> ;	MOV	[CMD_BLOCK+5],AH
  9666                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  9667                              <1> ;	MOV	[CMD_BLOCK+1],AL
  9668                              <1> ;	SUB	AX,AX
  9669                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  9670                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  9671                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  9672                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  9673                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  9674                              <1> ;	CALL	CHECK_STATUS
  9675                              <1> ;INIT_EXIT:
  9676                              <1> ;	RETn
  9677                              <1> 
  9678                              <1> ; 04/01/2015
  9679                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  9680                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  9681                              <1> INIT_DRV:
  9682                              <1> 	;xor	ah,ah
  9683 00002D43 31C0                <1> 	xor	eax, eax ; 21/02/2015
  9684 00002D45 B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  9685 00002D47 3825[7C790000]      <1>         cmp     [LBAMode], ah   ; 0
  9686 00002D4D 7702                <1> 	ja	short idrv0
  9687 00002D4F B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  9688                              <1> idrv0:
  9689                              <1> 	; DL = drive number (0 based)
  9690 00002D51 E8BE030000          <1> 	call	GET_VEC
  9691                              <1> 	;push	bx
  9692 00002D56 53                  <1> 	push	ebx ; 21/02/2015
  9693                              <1> 	;add	bx,ax
  9694 00002D57 01C3                <1> 	add	ebx, eax
  9695                              <1> 	;; 05/01/2015
  9696 00002D59 8A25[78730000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  9697                              <1> 	;;and 	ah,1 
  9698 00002D5F C0E404              <1> 	shl	ah,4
  9699 00002D62 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  9700                              <1> 	;mov	al,[es:bx]
  9701 00002D65 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  9702 00002D67 FEC8                <1> 	dec	al	 ; last head number 
  9703                              <1> 	;and	al,0Fh
  9704 00002D69 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  9705                              <1> 	;
  9706 00002D6B C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  9707 00002D6F 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  9708                              <1> 	;pop	bx
  9709 00002D72 5B                  <1> 	pop	ebx
  9710 00002D73 29C0                <1> 	sub	eax, eax ; 21/02/2015
  9711 00002D75 B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  9712 00002D77 803D[7C790000]00    <1> 	cmp	byte [LBAMode], 0
  9713 00002D7E 7702                <1> 	ja	short idrv1
  9714 00002D80 B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  9715                              <1> idrv1:
  9716                              <1> 	;xor	ah,ah
  9717                              <1> 	;add	bx,ax
  9718 00002D82 01C3                <1> 	add	ebx, eax ; 21/02/2015
  9719                              <1> 	;mov	al,[es:bx]
  9720                              <1> 			; sector number
  9721 00002D84 8A03                <1> 	mov	al, [ebx]
  9722 00002D86 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  9723 00002D89 28C0                <1> 	sub	al,al
  9724 00002D8B 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  9725 00002D8E E8C4010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  9726 00002D93 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  9727 00002D95 E872020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  9728 00002D9A 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  9729 00002D9C E8C3020000          <1> 	call	CHECK_STATUS
  9730                              <1> INIT_EXIT:
  9731 00002DA1 C3                  <1> 	RETn
  9732                              <1> 
  9733                              <1> ;----------------------------------------
  9734                              <1> ;	READ LONG	     (AH = 0AH) :
  9735                              <1> ;----------------------------------------
  9736                              <1> 
  9737                              <1> RD_LONG:
  9738                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  9739 00002DA2 C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  9740 00002DA6 E9E0000000          <1>         JMP     COMMANDI
  9741                              <1> 
  9742                              <1> ;----------------------------------------
  9743                              <1> ;	WRITE LONG	     (AH = 0BH) :
  9744                              <1> ;----------------------------------------
  9745                              <1> 
  9746                              <1> WR_LONG:
  9747                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  9748 00002DAB C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  9749 00002DAF E92C010000          <1>         JMP     COMMANDO
  9750                              <1> 
  9751                              <1> ;----------------------------------------
  9752                              <1> ;	SEEK		     (AH = 0CH) :
  9753                              <1> ;----------------------------------------
  9754                              <1> 
  9755                              <1> DISK_SEEK:
  9756 00002DB4 C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  9757 00002DB8 E89A010000          <1> 	CALL	COMMAND
  9758 00002DBD 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  9759 00002DBF E80C020000          <1> 	CALL	_WAIT
  9760 00002DC4 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  9761 00002DC6 E899020000          <1> 	CALL	CHECK_STATUS
  9762 00002DCB 803D[67790000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  9763 00002DD2 7507                <1> 	JNE	short DS_EXIT
  9764 00002DD4 C605[67790000]00    <1>         MOV     byte [DISK_STATUS1],0
  9765                              <1> DS_EXIT:
  9766 00002DDB C3                  <1> 	RETn
  9767                              <1> 
  9768                              <1> ;----------------------------------------
  9769                              <1> ;	TEST DISK READY      (AH = 10H) :
  9770                              <1> ;----------------------------------------
  9771                              <1> 
  9772                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  9773 00002DDC E82B020000          <1> 	CALL	NOT_BUSY
  9774 00002DE1 751C                <1> 	JNZ	short TR_EX
  9775 00002DE3 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  9776 00002DE6 668B15[74730000]    <1> 	MOV	DX,[HF_PORT]
  9777 00002DED 80C206              <1> 	add	dl,6
  9778 00002DF0 EE                  <1> 	OUT	DX,AL
  9779 00002DF1 E886020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  9780 00002DF6 7507                <1> 	JNZ	short TR_EX
  9781 00002DF8 C605[67790000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  9782                              <1> TR_EX:	
  9783 00002DFF C3                  <1> 	RETn
  9784                              <1> 
  9785                              <1> ;----------------------------------------
  9786                              <1> ;	RECALIBRATE	     (AH = 11H) :
  9787                              <1> ;----------------------------------------
  9788                              <1> 
  9789                              <1> HDISK_RECAL:
  9790 00002E00 C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  9791 00002E04 E84E010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  9792 00002E09 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  9793 00002E0B E8C0010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  9794 00002E10 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  9795 00002E12 E8B9010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  9796 00002E17 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  9797                              <1> RECAL_X:
  9798 00002E19 E846020000          <1> 	CALL	CHECK_STATUS
  9799 00002E1E 803D[67790000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  9800 00002E25 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  9801 00002E27 C605[67790000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9802                              <1> RECAL_EXIT:
  9803 00002E2E 803D[67790000]00    <1>         CMP     byte [DISK_STATUS1],0
  9804 00002E35 C3                  <1> 	RETn
  9805                              <1> 
  9806                              <1> ;----------------------------------------
  9807                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  9808                              <1> ;----------------------------------------
  9809                              <1> 
  9810                              <1> CTLR_DIAGNOSTIC:
  9811 00002E36 FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  9812 00002E37 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9813                              <1> 	;AND	AL,0BFH
  9814 00002E39 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  9815                              <1> 	;JMP	$+2
  9816                              <1> 	IODELAY
  9817 00002E3B EB00                <2>  jmp short $+2
  9818 00002E3D EB00                <2>  jmp short $+2
  9819 00002E3F E6A1                <1> 	OUT	INTB01,AL
  9820                              <1> 	IODELAY
  9821 00002E41 EB00                <2>  jmp short $+2
  9822 00002E43 EB00                <2>  jmp short $+2
  9823 00002E45 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9824 00002E47 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9825                              <1> 	;JMP	$+2
  9826                              <1> 	IODELAY
  9827 00002E49 EB00                <2>  jmp short $+2
  9828 00002E4B EB00                <2>  jmp short $+2
  9829 00002E4D E621                <1> 	OUT	INTA01,AL
  9830 00002E4F FB                  <1> 	STI
  9831 00002E50 E8B7010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  9832 00002E55 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  9833                              <1> 	;MOV	DX, HF_PORT+7
  9834 00002E57 668B15[74730000]    <1> 	mov	dx, [HF_PORT]
  9835 00002E5E 80C207              <1> 	add	dl, 7
  9836 00002E61 B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  9837 00002E63 EE                  <1> 	OUT	DX,AL
  9838 00002E64 E8A3010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  9839 00002E69 B480                <1> 	MOV	AH,TIME_OUT
  9840 00002E6B 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  9841                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  9842 00002E6D 668B15[74730000]    <1> 	mov	dx, [HF_PORT]
  9843 00002E74 FEC2                <1> 	inc	dl
  9844 00002E76 EC                  <1> 	IN	AL,DX
  9845 00002E77 A2[5E790000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  9846 00002E7C B400                <1> 	MOV	AH,0
  9847 00002E7E 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  9848 00002E80 7402                <1> 	JE	SHORT CD_EXIT
  9849 00002E82 B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  9850                              <1> CD_EXIT:
  9851 00002E84 8825[67790000]      <1> 	MOV	[DISK_STATUS1],AH
  9852 00002E8A C3                  <1> 	RETn
  9853                              <1> 
  9854                              <1> ;----------------------------------------
  9855                              <1> ; COMMANDI				:
  9856                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  9857                              <1> ;	NSECTOR RETURNS ZERO		:
  9858                              <1> ;----------------------------------------
  9859                              <1> COMMANDI:
  9860 00002E8B E85A020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9861 00002E90 724D                <1> 	JC	short CMD_ABORT
  9862                              <1> 	;MOV	DI,BX
  9863 00002E92 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  9864 00002E94 E8BE000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9865 00002E99 7544                <1> 	JNZ	short CMD_ABORT
  9866                              <1> CMD_I1:
  9867 00002E9B E830010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  9868 00002EA0 753D                <1> 	JNZ	short TM_OUT		; TIME OUT
  9869                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  9870 00002EA2 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  9871                              <1> 	;MOV	DX,HF_PORT
  9872 00002EA7 668B15[74730000]    <1> 	mov	dx,[HF_PORT]
  9873 00002EAE FA                  <1> 	CLI
  9874 00002EAF FC                  <1> 	CLD
  9875 00002EB0 F3666D              <1> 	REP	INSW			; GET THE SECTOR
  9876 00002EB3 FB                  <1> 	STI
  9877 00002EB4 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  9878 00002EB8 7419                <1> 	JZ	CMD_I3
  9879 00002EBA E87A010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9880 00002EBF 721E                <1> 	JC	short TM_OUT
  9881                              <1> 	;MOV	DX,HF_PORT
  9882 00002EC1 668B15[74730000]    <1> 	mov	dx,[HF_PORT]
  9883                              <1> 	;MOV	CX,4			; GET ECC BYTES
  9884 00002EC8 B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  9885 00002ECD EC                  <1> CMD_I2: IN	AL,DX
  9886                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  9887 00002ECE 8807                <1> 	mov 	[edi], al ; 21/02/2015
  9888 00002ED0 47                  <1> 	INC	eDI
  9889 00002ED1 E2FA                <1> 	LOOP	CMD_I2
  9890 00002ED3 E88C010000          <1> CMD_I3: CALL	CHECK_STATUS
  9891 00002ED8 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  9892 00002EDA FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  9893 00002EDD 75BC                <1> 	JNZ	SHORT CMD_I1
  9894                              <1> CMD_ABORT:
  9895 00002EDF C3                  <1> TM_OUT: RETn
  9896                              <1> 
  9897                              <1> ;----------------------------------------
  9898                              <1> ; COMMANDO				:
  9899                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  9900                              <1> ;	NSECTOR RETURNS ZERO		:
  9901                              <1> ;----------------------------------------
  9902                              <1> COMMANDO:
  9903 00002EE0 E805020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9904 00002EE5 72F8                <1> 	JC	short CMD_ABORT
  9905 00002EE7 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  9906 00002EE9 E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9907 00002EEE 75EF                <1> 	JNZ	short CMD_ABORT
  9908 00002EF0 E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9909 00002EF5 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  9910                              <1> CMD_O1: ;PUSH	DS
  9911                              <1> 	;PUSH	ES			; MOVE ES TO DS
  9912                              <1> 	;POP	DS
  9913                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  9914                              <1> 	;MOV	DX,HF_PORT
  9915                              <1> 	; 01/02/2015
  9916 00002EF7 668B15[74730000]    <1> 	mov	dx, [HF_PORT]
  9917                              <1> 	;push	es
  9918                              <1> 	;pop	ds
  9919                              <1> 	;mov	cx, 256
  9920 00002EFE B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  9921 00002F03 FA                  <1> 	CLI
  9922 00002F04 FC                  <1> 	CLD
  9923 00002F05 F3666F              <1> 	REP	OUTSW
  9924 00002F08 FB                  <1> 	STI
  9925                              <1> 	;POP	DS			; RESTORE DS
  9926 00002F09 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  9927 00002F0D 7419                <1> 	JZ	short CMD_O3
  9928 00002F0F E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9929 00002F14 72C9                <1> 	JC	short TM_OUT
  9930                              <1> 	;MOV	DX,HF_PORT
  9931 00002F16 668B15[74730000]    <1> 	mov	dx, [HF_PORT]
  9932                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  9933 00002F1D B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  9934                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  9935 00002F22 8A06                <1> 	mov	al, [esi]
  9936 00002F24 EE                  <1> 	OUT	DX,AL
  9937 00002F25 46                  <1> 	INC	eSI
  9938 00002F26 E2FA                <1> 	LOOP	CMD_O2
  9939                              <1> CMD_O3:
  9940 00002F28 E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  9941 00002F2D 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  9942 00002F2F E830010000          <1> 	CALL	CHECK_STATUS
  9943 00002F34 75A9                <1> 	JNZ	short CMD_ABORT
  9944 00002F36 F605[5D790000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  9945 00002F3D 75B8                <1> 	JNZ	SHORT CMD_O1
  9946                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  9947 00002F3F 668B15[74730000]    <1> 	mov	dx, [HF_PORT]
  9948                              <1> 	;add	dl, 2
  9949 00002F46 FEC2                <1> 	inc	dl
  9950 00002F48 FEC2                <1> 	inc	dl
  9951 00002F4A EC                  <1> 	IN	AL,DX			;
  9952 00002F4B A8FF                <1> 	TEST	AL,0FFH 		;
  9953 00002F4D 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  9954 00002F4F C605[67790000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  9955                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  9956                              <1> CMD_O4:
  9957 00002F56 C3                  <1> 	RETn
  9958                              <1> 
  9959                              <1> ;--------------------------------------------------------
  9960                              <1> ; COMMAND						:
  9961                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  9962                              <1> ; OUTPUT						:
  9963                              <1> ;	BL = STATUS					:
  9964                              <1> ;	BH = ERROR REGISTER				:
  9965                              <1> ;--------------------------------------------------------
  9966                              <1> 
  9967                              <1> COMMAND:
  9968 00002F57 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  9969                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  9970                              <1> COMMAND1:
  9971                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  9972 00002F58 E87FFEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  9973                              <1> 	;;POP	CX
  9974 00002F5D 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  9975 00002F5F 803D[67790000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  9976                              <1> 	;JZ	short CMD_TIMEOUT
  9977                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  9978                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  9979 00002F66 7507                <1> 	jne	short COMMAND4
  9980                              <1> CMD_TIMEOUT:
  9981 00002F68 C605[67790000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9982                              <1> COMMAND4:
  9983 00002F6F 5B                  <1> 	POP	eBX
  9984 00002F70 803D[67790000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  9985 00002F77 C3                  <1> 	RETn
  9986                              <1> COMMAND2:
  9987 00002F78 5B                  <1> 	POP	eBX
  9988 00002F79 57                  <1> 	PUSH	eDI
  9989 00002F7A C605[5F790000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  9990 00002F81 FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  9991 00002F82 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9992                              <1> 	;AND	AL,0BFH
  9993 00002F84 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  9994                              <1> 	;JMP	$+2
  9995                              <1> 	IODELAY
  9996 00002F86 EB00                <2>  jmp short $+2
  9997 00002F88 EB00                <2>  jmp short $+2
  9998 00002F8A E6A1                <1> 	OUT	INTB01,AL
  9999 00002F8C E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
 10000 00002F8E 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
 10001                              <1> 	;JMP	$+2
 10002                              <1> 	IODELAY
 10003 00002F90 EB00                <2>  jmp short $+2
 10004 00002F92 EB00                <2>  jmp short $+2
 10005 00002F94 E621                <1> 	OUT	INTA01,AL
 10006 00002F96 FB                  <1> 	STI
 10007 00002F97 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
 10008                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
 10009 00002F99 668B15[74730000]    <1> 	mov	dx, [HF_PORT]
 10010 00002FA0 FEC2                <1> 	inc	dl
 10011 00002FA2 F605[69790000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
 10012 00002FA9 7411                <1> 	JZ	short COMMAND3
 10013 00002FAB 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
 10014 00002FAE 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
 10015 00002FB0 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
 10016 00002FB2 7208                <1> 	JB	short COMMAND3
 10017 00002FB4 3C40                <1> 	CMP	AL,40H
 10018 00002FB6 7704                <1> 	JA	short COMMAND3
 10019 00002FB8 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
 10020                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
 10021                              <1> COMMAND3:
 10022 00002FBC 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
 10023 00002FC0 EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
 10024                              <1> 	IODELAY
 10025 00002FC1 EB00                <2>  jmp short $+2
 10026 00002FC3 EB00                <2>  jmp short $+2
 10027 00002FC5 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
 10028 00002FC6 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
 10029 00002FC8 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
 10030 00002FCC 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
 10031 00002FCE 5F                  <1> 	POP	eDI
 10032 00002FCF C3                  <1> 	RETn				; ZERO FLAG IS SET
 10033                              <1> 
 10034                              <1> ;CMD_TIMEOUT:
 10035                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
 10036                              <1> ;COMMAND4:
 10037                              <1> ;	POP	BX
 10038                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
 10039                              <1> ;	RETn
 10040                              <1> 
 10041                              <1> ;----------------------------------------
 10042                              <1> ;	WAIT FOR INTERRUPT		:
 10043                              <1> ;----------------------------------------
 10044                              <1> ;WAIT:
 10045                              <1> _WAIT:
 10046 00002FD0 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
 10047                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
 10048                              <1> 	;CLC
 10049                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
 10050                              <1> 	;INT	15H
 10051                              <1> 	;JC	WT2			; DEVICE TIMED OUT
 10052                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
 10053                              <1> 
 10054                              <1> 	;mov	bl, WAIT_HDU_INT_HI
 10055                              <1> 	;; 21/02/2015
 10056                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
 10057                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
 10058 00002FD1 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
 10059                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
 10060                              <1> ;-----	WAIT LOOP
 10061                              <1> 
 10062                              <1> WT1:	
 10063                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
 10064 00002FD6 F605[5F790000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
 10065                              <1> 	;LOOPZ	WT1
 10066 00002FDD 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
 10067                              <1> 	;DEC	BL
 10068                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
 10069                              <1> 
 10070                              <1> WT1_hi:
 10071 00002FDF E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
 10072 00002FE1 A810                <1> 	test	al, 10h			; transition on memory
 10073 00002FE3 75FA                <1> 	jnz	short WT1_hi		; refresh.
 10074                              <1> WT1_lo:
 10075 00002FE5 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
 10076 00002FE7 A810                <1> 	test	al, 10h			
 10077 00002FE9 74FA                <1> 	jz	short WT1_lo
 10078 00002FEB E2E9                <1> 	loop	WT1
 10079                              <1> 	;;or	bl, bl
 10080                              <1> 	;;jz	short WT2	
 10081                              <1> 	;;dec	bl
 10082                              <1> 	;;jmp	short WT1
 10083                              <1> 	;dec	bl
 10084                              <1> 	;jnz	short WT1	
 10085                              <1> 
 10086 00002FED C605[67790000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
 10087 00002FF4 EB0E                <1> 	JMP	SHORT WT4
 10088 00002FF6 C605[67790000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
 10089 00002FFD C605[5F790000]00    <1> 	MOV	byte [HF_INT_FLAG],0
 10090 00003004 803D[67790000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
 10091 0000300B C3                  <1> 	RETn
 10092                              <1> 
 10093                              <1> ;----------------------------------------
 10094                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
 10095                              <1> ;----------------------------------------
 10096                              <1> NOT_BUSY:
 10097 0000300C FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
 10098                              <1> 	;PUSH	eBX
 10099                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
 10100 0000300D 668B15[74730000]    <1> 	mov	DX, [HF_PORT]
 10101 00003014 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
 10102                              <1> 	;MOV	BL,DELAY_1
 10103                              <1> 					; wait for 10 seconds
 10104                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
 10105                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
 10106                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
 10107 00003017 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
 10108                              <1> 	;
 10109                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
 10110                              <1> NB1:	
 10111 0000301C EC                  <1> 	IN	AL,DX			; CHECK STATUS
 10112                              <1> 	;TEST	AL,ST_BUSY
 10113 0000301D 2480                <1> 	and	al, ST_BUSY
 10114                              <1> 	;LOOPNZ	NB1
 10115 0000301F 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
 10116                              <1> 	;DEC	BL			
 10117                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
 10118                              <1> 
 10119 00003021 E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
 10120 00003023 A810                <1> 	TEST	AL,010H			; transition on memory
 10121 00003025 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
 10122 00003027 E461                <1> NB1_lo: IN	AL,SYS1
 10123 00003029 A810                <1> 	TEST	AL,010H
 10124 0000302B 74FA                <1> 	JZ	short NB1_lo
 10125 0000302D E2ED                <1> 	LOOP	NB1
 10126                              <1> 	;dec	bl
 10127                              <1> 	;jnz	short NB1
 10128                              <1> 	;
 10129                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
 10130                              <1> ;;	jb	short NB1
 10131                              <1> 	;
 10132                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
 10133                              <1> 	;JMP	SHORT NB3
 10134 0000302F B080                <1> 	mov	al, TIME_OUT
 10135                              <1> NB2:	
 10136                              <1> 	;MOV	byte [DISK_STATUS1],0
 10137                              <1> ;NB3:	
 10138                              <1> 	;POP	eBX
 10139 00003031 A2[67790000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
 10140                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
 10141 00003036 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
 10142 00003038 C3                  <1> 	RETn
 10143                              <1> 
 10144                              <1> ;----------------------------------------
 10145                              <1> ;	WAIT FOR DATA REQUEST		:
 10146                              <1> ;----------------------------------------
 10147                              <1> WAIT_DRQ:
 10148                              <1> 	;MOV	CX,DELAY_3
 10149                              <1> 	;MOV	DX,HF_PORT+7
 10150 00003039 668B15[74730000]    <1> 	mov	dx, [HF_PORT]
 10151 00003040 80C207              <1> 	add	dl, 7
 10152                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
 10153                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
 10154                              <1> 					; (but it is written as 2000
 10155                              <1> 					; micro seconds in ATORGS.ASM file
 10156                              <1> 					; of Award Bios - 1999, D1A0622)
 10157 00003043 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
 10158 00003048 EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
 10159 00003049 A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
 10160 0000304B 7516                <1> 	JNZ	short WQ_OK
 10161                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
 10162                              <1> WQ_hi:	
 10163 0000304D E461                <1> 	IN	AL,SYS1			; wait for hi to lo
 10164 0000304F A810                <1> 	TEST	AL,010H			; transition on memory
 10165 00003051 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
 10166 00003053 E461                <1> WQ_lo:  IN      AL,SYS1
 10167 00003055 A810                <1> 	TEST	AL,010H
 10168 00003057 74FA                <1> 	JZ	SHORT WQ_lo
 10169 00003059 E2ED                <1> 	LOOP	WQ_1
 10170                              <1> 
 10171 0000305B C605[67790000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
 10172 00003062 F9                  <1> 	STC
 10173                              <1> WQ_OK:
 10174 00003063 C3                  <1> 	RETn
 10175                              <1> ;WQ_OK:	;CLC
 10176                              <1> ;	RETn
 10177                              <1> 
 10178                              <1> ;----------------------------------------
 10179                              <1> ;	CHECK FIXED DISK STATUS 	:
 10180                              <1> ;----------------------------------------
 10181                              <1> CHECK_STATUS:
 10182 00003064 E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
 10183 00003069 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
 10184 0000306B A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
 10185 0000306D 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
 10186 0000306F E847000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
 10187                              <1> CHECK_S1:
 10188 00003074 803D[67790000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
 10189 0000307B C3                  <1> 	RETn
 10190                              <1> 
 10191                              <1> ;----------------------------------------
 10192                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
 10193                              <1> ;----------------------------------------
 10194                              <1> CHECK_ST:
 10195                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
 10196 0000307C 668B15[74730000]    <1> 	mov	dx, [HF_PORT]
 10197 00003083 80C207              <1> 	add	dl, 7
 10198 00003086 EC                  <1> 	IN	AL,DX
 10199 00003087 A2[5D790000]        <1> 	MOV	[HF_STATUS],AL
 10200 0000308C B400                <1> 	MOV	AH,0
 10201 0000308E A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
 10202 00003090 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
 10203 00003092 B4CC                <1> 	MOV	AH,WRITE_FAULT
 10204 00003094 A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
 10205 00003096 7514                <1> 	JNZ	short CKST_EXIT
 10206 00003098 B4AA                <1> 	MOV	AH,NOT_RDY
 10207 0000309A A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
 10208 0000309C 740E                <1> 	JZ	short CKST_EXIT
 10209 0000309E B440                <1> 	MOV	AH,BAD_SEEK
 10210 000030A0 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
 10211 000030A2 7408                <1> 	JZ	short CKST_EXIT
 10212 000030A4 B411                <1> 	MOV	AH,DATA_CORRECTED
 10213 000030A6 A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
 10214 000030A8 7502                <1> 	JNZ	short CKST_EXIT
 10215 000030AA B400                <1> 	MOV	AH,0
 10216                              <1> CKST_EXIT:
 10217 000030AC 8825[67790000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
 10218 000030B2 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
 10219 000030B5 7403                <1> 	JZ	short CKST_EX1
 10220 000030B7 80FC00              <1> 	CMP	AH,0
 10221                              <1> CKST_EX1:
 10222 000030BA C3                  <1> 	RETn
 10223                              <1> 
 10224                              <1> ;----------------------------------------
 10225                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
 10226                              <1> ;----------------------------------------
 10227                              <1> CHECK_ER:
 10228                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
 10229 000030BB 668B15[74730000]    <1> 	mov	dx, [HF_PORT]		;
 10230 000030C2 FEC2                <1> 	inc	dl
 10231 000030C4 EC                  <1> 	IN	AL,DX
 10232 000030C5 A2[5E790000]        <1> 	MOV	[HF_ERROR],AL
 10233 000030CA 53                  <1> 	PUSH	eBX ; 21/02/2015
 10234 000030CB B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
 10235 000030D0 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
 10236 000030D2 7202                <1> 	JC	short CK2		; FOUND THE ERROR
 10237 000030D4 E2FA                <1> 	LOOP	CK1			; KEEP TRYING
 10238 000030D6 BB[68730000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
 10239 000030DB 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
 10240                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
 10241                              <1> 	;mov	ah, [bx]
 10242 000030DD 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
 10243 000030DF 8825[67790000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
 10244 000030E5 5B                  <1> 	POP	eBX
 10245 000030E6 80FC00              <1> 	CMP	AH,0
 10246 000030E9 C3                  <1> 	RETn
 10247                              <1> 
 10248                              <1> ;--------------------------------------------------------
 10249                              <1> ; CHECK_DMA						:
 10250                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
 10251                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
 10252                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
 10253                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
 10254                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
 10255                              <1> ;  -ERROR OTHERWISE					:
 10256                              <1> ;--------------------------------------------------------
 10257                              <1> CHECK_DMA:
 10258 000030EA 6650                <1> 	PUSH	AX			; SAVE REGISTERS
 10259 000030EC 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
 10260 000030F0 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
 10261 000030F4 7404                <1> 	JZ	short CKD1
 10262 000030F6 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
 10263 000030FA 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
 10264 000030FD 7706                <1> 	JA	short CKDOK		; IT WILL FIT
 10265 000030FF 7208                <1> 	JB	short CKDERR		; TOO MANY
 10266 00003101 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
 10267 00003103 7204                <1> 	JB	short CKDERR		; ERROR
 10268 00003105 F8                  <1> CKDOK:	CLC				; CLEAR CARRY
 10269 00003106 6658                <1> 	POP	AX
 10270 00003108 C3                  <1> 	RETn				; NORMAL RETURN
 10271 00003109 F9                  <1> CKDERR: STC				; INDICATE ERROR
 10272 0000310A C605[67790000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
 10273 00003111 6658                <1> 	POP	AX
 10274 00003113 C3                  <1> 	RETn
 10275                              <1> 
 10276                              <1> ;----------------------------------------
 10277                              <1> ;	SET UP ES:BX-> DISK PARMS	:
 10278                              <1> ;----------------------------------------
 10279                              <1> 					
 10280                              <1> ; INPUT -> DL = 0 based drive number
 10281                              <1> ; OUTPUT -> ES:BX = disk parameter table address
 10282                              <1> 
 10283                              <1> GET_VEC:
 10284                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
 10285                              <1> 	;MOV	ES,AX
 10286                              <1> 	;TEST	DL,1
 10287                              <1> 	;JZ	short GV_0
 10288                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
 10289                              <1> ;	JMP	SHORT GV_EXIT
 10290                              <1> ;GV_0:
 10291                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
 10292                              <1> ;
 10293                              <1> 	;xor	bh, bh
 10294 00003114 31DB                <1> 	xor	ebx, ebx
 10295 00003116 88D3                <1> 	mov	bl, dl
 10296                              <1> 	;;02/01/2015
 10297                              <1> 	;;shl	bl, 1			; port address offset
 10298                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
 10299                              <1> 	;;shl	bl, 1			; dpt pointer offset
 10300 00003118 C0E302              <1> 	shl	bl, 2	;;
 10301                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
 10302 0000311B 81C3[6C790000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
 10303                              <1> 	;push	word [bx+2]		; dpt segment
 10304                              <1> 	;pop	es
 10305                              <1> 	;mov	bx, [bx]		; dpt offset
 10306 00003121 8B1B                <1> 	mov	ebx, [ebx]		
 10307                              <1> ;GV_EXIT:
 10308 00003123 C3                  <1> 	RETn
 10309                              <1> 
 10310                              <1> hdc1_int: ; 21/02/2015
 10311                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
 10312                              <1> ;								:
 10313                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
 10314                              <1> ;								:
 10315                              <1> ;----------------------------------------------------------------
 10316                              <1> 
 10317                              <1> ; 22/12/2014
 10318                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
 10319                              <1> ;	 '11/15/85'
 10320                              <1> ; AWARD BIOS 1999 (D1A0622) 
 10321                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
 10322                              <1> 
 10323                              <1> ;int_76h:
 10324                              <1> HD_INT:
 10325 00003124 6650                <1> 	PUSH	AX
 10326 00003126 1E                  <1> 	PUSH	DS
 10327                              <1> 	;CALL	DDS
 10328                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
 10329 00003127 66B81000            <1> 	mov	ax, KDATA
 10330 0000312B 8ED8                <1> 	mov 	ds, ax
 10331                              <1> 	;
 10332                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
 10333                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
 10334 0000312D C605[5F790000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
 10335                              <1> 	;
 10336 00003134 6652                <1> 	push	dx
 10337 00003136 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
 10338                              <1> 					; Clear Controller
 10339                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
 10340 0000313A EC                  <1> 	in	al, dx			;
 10341 0000313B 665A                <1> 	pop	dx
 10342                              <1> 	NEWIODELAY
 10343 0000313D E6EB                <2>  out 0ebh,al
 10344                              <1> 	;
 10345 0000313F B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
 10346 00003141 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
 10347                              <1> 	;JMP	$+2			; WAIT
 10348                              <1> 	NEWIODELAY
 10349 00003143 E6EB                <2>  out 0ebh,al
 10350 00003145 E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
 10351 00003147 1F                  <1> 	POP	DS
 10352                              <1> 	;STI				; RE-ENABLE INTERRUPTS
 10353                              <1> 	;MOV	AX,9100H		; DEVICE POST
 10354                              <1> 	;INT	15H			;  INTERRUPT
 10355                              <1> irq15_iret: ; 25/02/2015
 10356 00003148 6658                <1> 	POP	AX
 10357 0000314A CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
 10358                              <1> 
 10359                              <1> hdc2_int: ; 21/02/2015
 10360                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
 10361                              <1> ;								:
 10362                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
 10363                              <1> ;								:
 10364                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 10365                              <1> 
 10366                              <1> ;int_77h:
 10367                              <1> HD1_INT:
 10368 0000314B 6650                <1> 	PUSH	AX
 10369                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
 10370                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 10371 0000314D B00B                <1> 	mov	al, 0Bh  ; In-Service Register
 10372 0000314F E6A0                <1> 	out	0A0h, al
 10373 00003151 EB00                <1>         jmp short $+2
 10374 00003153 EB00                <1> 	jmp short $+2
 10375 00003155 E4A0                <1> 	in	al, 0A0h
 10376 00003157 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
 10377 00003159 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
 10378                              <1> 	;
 10379 0000315B 1E                  <1> 	PUSH	DS
 10380                              <1> 	;CALL	DDS
 10381                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
 10382 0000315C 66B81000            <1> 	mov	ax, KDATA
 10383 00003160 8ED8                <1> 	mov 	ds, ax
 10384                              <1> 	;
 10385                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
 10386                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
 10387 00003162 800D[5F790000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
 10388                              <1> 	;
 10389 00003169 6652                <1> 	push	dx
 10390 0000316B 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
 10391                              <1> 					; Clear Controller (Award BIOS 1999)
 10392 0000316F EBC9                <1> 	jmp	short Clear_IRQ1415
 10393                              <1> 
 10394                              <1> 
 10395                              <1> ;%include 'diskdata.inc' ; 11/03/2015
 10396                              <1> ;%include 'diskbss.inc' ; 11/03/2015
 10397                              <1> 
 10398                              <1> 
 10399                              <1> ;////////////////////////////////////////////////////////////////////
 10400                              <1> ;; END OF DISK I/O SYTEM ///
 10401                                  %include 'memory.s'  ; 09/03/2015
 10402                              <1> ; ****************************************************************************
 10403                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - memory.s
 10404                              <1> ; ----------------------------------------------------------------------------
 10405                              <1> ; Last Update: 24/01/2016
 10406                              <1> ; ----------------------------------------------------------------------------
 10407                              <1> ; Beginning: 24/01/2016
 10408                              <1> ; ----------------------------------------------------------------------------
 10409                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 10410                              <1> ; ----------------------------------------------------------------------------
 10411                              <1> ; Turkish Rational DOS
 10412                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
 10413                              <1> ;
 10414                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 10415                              <1> ; memory.inc (18/10/2015)
 10416                              <1> ; ****************************************************************************
 10417                              <1> 
 10418                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
 10419                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
 10420                              <1> ; Last Modification: 18/10/2015
 10421                              <1> 
 10422                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
 10423                              <1> 
 10424                              <1> ;;04/11/2014 (unix386.s)	
 10425                              <1> ;PDE_A_PRESENT	equ	1		; Present flag for PDE
 10426                              <1> ;PDE_A_WRITE	equ 	2		; Writable (write permission) flag
 10427                              <1> ;PDE_A_USER	equ	4		; User (non-system/kernel) page flag
 10428                              <1> ;;
 10429                              <1> ;PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
 10430                              <1> ;PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
 10431                              <1> ;PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
 10432                              <1> ;PTE_A_ACCESS   equ	32		; Accessed flag (bit 5) ; 09/03/2015
 10433                              <1> 
 10434                              <1> ; 27/04/2015
 10435                              <1> ; 09/03/2015
 10436                              <1> PAGE_SIZE 	equ 4096		; page size in bytes
 10437                              <1> PAGE_SHIFT 	equ 12			; page table shift count
 10438                              <1> PAGE_D_SHIFT 	equ 22	; 12 + 10	; page directory shift count
 10439                              <1> PAGE_OFF	equ 0FFFh		; 12 bit byte offset in page frame
 10440                              <1> PTE_MASK 	equ 03FFh		; page table entry mask
 10441                              <1> PTE_DUPLICATED  equ 200h		; duplicated page sign (AVL bit 0)
 10442                              <1> PDE_A_CLEAR	equ 0F000h		; to clear PDE attribute bits
 10443                              <1> PTE_A_CLEAR	equ 0F000h		; to clear PTE attribute bits
 10444                              <1> LOGIC_SECT_SIZE equ 512			; logical sector size
 10445                              <1> ERR_MAJOR_PF	equ 0E0h		; major error: page fault
 10446                              <1> ERR_MINOR_IM	equ 1			; insufficient (out of) memory
 10447                              <1> ERR_MINOR_DSK	equ 2			; disk read/write error
 10448                              <1> ERR_MINOR_PV	equ 3			; protection violation
 10449                              <1> SWP_DISK_READ_ERR equ 4
 10450                              <1> SWP_DISK_NOT_PRESENT_ERR equ 5
 10451                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 6
 10452                              <1> SWP_NO_FREE_SPACE_ERR equ 7
 10453                              <1> SWP_DISK_WRITE_ERR equ 8
 10454                              <1> SWP_NO_PAGE_TO_SWAP_ERR equ 9
 10455                              <1> PTE_A_ACCESS_BIT equ 5  ; Bit 5 (accessed flag)        
 10456                              <1> SECTOR_SHIFT    equ 3   ; sector shift (to convert page block number)
 10457                              <1> 
 10458                              <1> ;
 10459                              <1> ;; Retro Unix 386 v1 - paging method/principles
 10460                              <1> ;;
 10461                              <1> ;; 10/10/2014
 10462                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
 10463                              <1> ;;
 10464                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
 10465                              <1> ;;	(virtual address = physical address)
 10466                              <1> ;; KERNEL PAGE TABLES:
 10467                              <1> ;;	Kernel page directory and all page tables are
 10468                              <1> ;;	on memory as initialized, as equal to physical memory
 10469                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
 10470                              <1> ;;
 10471                              <1> ;;	what for: User pages may be swapped out, when accessing
 10472                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
 10473                              <1> ;;	kernel would have to swap it in! But it is also may be
 10474                              <1> ;;	in use by a user process. (In system/kernel mode
 10475                              <1> ;;	kernel can access all memory pages even if they are
 10476                              <1> ;;	reserved/allocated for user processes. Swap out/in would
 10477                              <1> ;;	cause conflicts.) 
 10478                              <1> ;;	
 10479                              <1> ;;	As result of these conditions,
 10480                              <1> ;;	all kernel pages must be initialized as equal to 
 10481                              <1> ;;	physical layout for preventing page faults. 
 10482                              <1> ;;	Also, calling "allocate page" procedure after
 10483                              <1> ;;	a page fault can cause another page fault (double fault)
 10484                              <1> ;;	if all kernel page tables would not be initialized.
 10485                              <1> ;;
 10486                              <1> ;;	[first_page] = Beginning of users space, as offset to 
 10487                              <1> ;;	memory allocation table. (double word aligned)
 10488                              <1> ;;
 10489                              <1> ;;	[next_page] = first/next free space to be searched
 10490                              <1> ;;	as offset to memory allocation table. (dw aligned)
 10491                              <1> ;;
 10492                              <1> ;;	[last_page] = End of memory (users space), as offset
 10493                              <1> ;;	to memory allocation table. (double word aligned)
 10494                              <1> ;;
 10495                              <1> ;; USER PAGE TABLES:
 10496                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
 10497                              <1> ;;		'ready only' marked copies of the 
 10498                              <1> ;;		parent process's page table entries (for
 10499                              <1> ;;		same physical memory).
 10500                              <1> ;;		(A page will be copied to a new page after
 10501                              <1> ;;		 if it causes R/W page fault.)
 10502                              <1> ;;
 10503                              <1> ;;	Every user process has own (different)
 10504                              <1> ;;	page directory and page tables.	
 10505                              <1> ;;
 10506                              <1> ;;	Code starts at virtual address 0, always.
 10507                              <1> ;;	(Initial value of EIP is 0 in user mode.)
 10508                              <1> ;;	(Programs can be written/developed as simple
 10509                              <1> ;;	 flat memory programs.)
 10510                              <1> ;;
 10511                              <1> ;; MEMORY ALLOCATION STRATEGY:
 10512                              <1> ;;	Memory page will be allocated by kernel only 
 10513                              <1> ;;		(in kernel/system mode only).
 10514                              <1> ;;	* After a
 10515                              <1> ;;	  - 'not present' page fault
 10516                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
 10517                              <1> ;;	* For loading (opening, reading) a file or disk/drive
 10518                              <1> ;;	* As responce to 'allocate additional memory blocks' 
 10519                              <1> ;;	  request by running process.
 10520                              <1> ;;	* While creating a process, allocating a new buffer,
 10521                              <1> ;;	  new page tables etc.
 10522                              <1> ;;
 10523                              <1> ;;	At first,
 10524                              <1> ;;	- 'allocate page' procedure will be called;
 10525                              <1> ;,	   if it will return with a valid (>0) physical address
 10526                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
 10527                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
 10528                              <1> ;;	- 'allocate page' will be called for allocating page
 10529                              <1> ;;	   directory, page table and running space (data/code).
 10530                              <1> ;;	- every successful 'allocate page' call will decrease
 10531                              <1> ;;	  'free_pages' count (pointer).
 10532                              <1> ;;	- 'out of (insufficient) memory error' will be returned
 10533                              <1> ;;	  if 'free_pages' points to a ZERO.
 10534                              <1> ;;	- swapping out and swapping in (if it is not a new page)
 10535                              <1> ;;	  procedures will be called as responce to 'out of memory'
 10536                              <1> ;;	  error except errors caused by attribute conflicts.
 10537                              <1> ;;	 (swapper functions)	 
 10538                              <1> ;;					
 10539                              <1> ;;	At second,
 10540                              <1> ;;	- page directory entry will be updated then page table
 10541                              <1> ;;	  entry will be updated.		
 10542                              <1> ;;
 10543                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
 10544                              <1> ;;	- M.A.T. has a size according to available memory as
 10545                              <1> ;;	  follows:
 10546                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
 10547                              <1> ;;		  - a bit with value of 0 means allocated page
 10548                              <1> ;;		  - a bit with value of 1 means a free page
 10549                              <1> ;,	- 'free_pages' pointer holds count of free pages
 10550                              <1> ;;	  depending on M.A.T.
 10551                              <1> ;;		(NOTE: Free page count will not be checked
 10552                              <1> ;;		again -on M.A.T.- after initialization. 
 10553                              <1> ;;		Kernel will trust on initial count.)
 10554                              <1> ;,	- 'free_pages' count will be decreased by allocation
 10555                              <1> ;;	  and it will be increased by deallocation procedures.
 10556                              <1> ;;	
 10557                              <1> ;;	- Available memory will be calculated during
 10558                              <1> ;;	  the kernel's initialization stage (in real mode).
 10559                              <1> ;;	  Memory allocation table and kernel page tables 
 10560                              <1> ;;	  will be formatted/sized as result of available
 10561                              <1> ;;	  memory calculation before paging is enabled.
 10562                              <1> ;;
 10563                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
 10564                              <1> ;;	- Memory Allocation Table size will be 128 KB.
 10565                              <1> ;;	- Memory allocation for kernel page directory size 
 10566                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10567                              <1> ;;	  for page tables)
 10568                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
 10569                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
 10570                              <1> ;;	- User (available) space will be started 
 10571                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
 10572                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10573                              <1> ;;	  memory allocation table and kernel's page directory
 10574                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10575                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10576                              <1> ;; 	  for buffers.
 10577                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10578                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10579                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
 10580                              <1> ;;
 10581                              <1> ;; For 1GB Available Memory:
 10582                              <1> ;;	- Memory Allocation Table size will be 32 KB.
 10583                              <1> ;;	- Memory allocation for kernel page directory size 
 10584                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10585                              <1> ;;	  for page tables)
 10586                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
 10587                              <1> ;;	  is 1 MB (256*4*1024 bytes).
 10588                              <1> ;;	- User (available) space will be started 
 10589                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
 10590                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10591                              <1> ;;	  memory allocation table and kernel's page directory
 10592                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10593                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10594                              <1> ;; 	  for buffers.
 10595                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10596                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10597                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
 10598                              <1> ;;
 10599                              <1> ;;
 10600                              <1> 
 10601                              <1> 
 10602                              <1> ;;************************************************************************************
 10603                              <1> ;; 
 10604                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
 10605                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
 10606                              <1> 
 10607                              <1> ;; Main factor: "sys fork" system call 
 10608                              <1> ;;	
 10609                              <1> ;; 		FORK
 10610                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
 10611                              <1> ;;  writable pages ---->|
 10612                              <1> ;;                      |----> child - duplicated PTEs, read only pages
 10613                              <1> ;; 
 10614                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
 10615                              <1> ;; 
 10616                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
 10617                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
 10618                              <1> ;;       -while R/W bit is 0-. 
 10619                              <1> ;; 
 10620                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
 10621                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
 10622                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
 10623                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
 10624                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
 10625                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
 10626                              <1> ;; 
 10627                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
 10628                              <1> ;; # Parent's read only pages are copied to new child pages. 
 10629                              <1> ;;   Parent's PTE attributes are not changed.
 10630                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
 10631                              <1> ;;    destroy/mix previous fork result).
 10632                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
 10633                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
 10634                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
 10635                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
 10636                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
 10637                              <1> ;;   as Child's Page Table Entries without copying actual page.
 10638                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
 10639                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
 10640                              <1> ;; 
 10641                              <1> ;; !? WHAT FOR (duplication after duplication):
 10642                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
 10643                              <1> ;; program/executable code continues from specified location as child process, 
 10644                              <1> ;; returns back previous code location as parent process, every child after 
 10645                              <1> ;; every sys fork uses last image of code and data just prior the fork.
 10646                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
 10647                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
 10648                              <1> ;; was copied to child's process segment (all of code and data) according to
 10649                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
 10650                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
 10651                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
 10652                              <1> ;; (complete running image of parent process) to the child process; 
 10653                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
 10654                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
 10655                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
 10656                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
 10657                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
 10658                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
 10659                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
 10660                              <1> ;; new/fresh pages will be used to load and run new executable/program.
 10661                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
 10662                              <1> ;; for sharing same read only pages between parent and child processes.
 10663                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
 10664                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
 10665                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
 10666                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
 10667                              <1> ;; -deallocation problem-.
 10668                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
 10669                              <1> ;; 
 10670                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10671                              <1> ;; # Page fault handler will do those:
 10672                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10673                              <1> ;;   - If it is reset/clear, there is a child uses same page.
 10674                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
 10675                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
 10676                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
 10677                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
 10678                              <1> ;;     read only page will be converted to writable and unique page which belongs
 10679                              <1> ;;     to child process.)	
 10680                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10681                              <1> ;; # Page fault handler will do those:
 10682                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10683                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
 10684                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
 10685                              <1> ;;     address or not. 
 10686                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
 10687                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
 10688                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
 10689                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
 10690                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
 10691                              <1> ;; 
 10692                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
 10693                              <1> ;;       will be set as writable (and unique) in case of child process was using 
 10694                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
 10695                              <1> ;;       duplication method details, it is not possible multiple child processes
 10696                              <1> ;;       were using same page with duplicated PTEs.
 10697                              <1> ;; 
 10698                              <1> ;;************************************************************************************   
 10699                              <1> 
 10700                              <1> ;; 08/10/2014
 10701                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
 10702                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
 10703                              <1> 
 10704                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
 10705                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
 10706                              <1> ;; (25/08/2014, Revision: 5057) file 
 10707                              <1> ;; by KolibriOS Team (2004-2012)
 10708                              <1> 
 10709                              <1> allocate_page:
 10710                              <1> 	; 01/07/2015
 10711                              <1> 	; 05/05/2015
 10712                              <1> 	; 30/04/2015
 10713                              <1> 	; 16/10/2014
 10714                              <1> 	; 08/10/2014
 10715                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
 10716                              <1> 	;
 10717                              <1> 	; INPUT -> none
 10718                              <1> 	;
 10719                              <1> 	; OUTPUT ->
 10720                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10721                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
 10722                              <1> 	;
 10723                              <1> 	;	CF = 1 and EAX = 0 
 10724                              <1> 	; 		   if there is not a free page to be allocated	
 10725                              <1> 	;
 10726                              <1> 	; Modified Registers -> none (except EAX)
 10727                              <1> 	;
 10728 00003171 A1[D0780000]        <1> 	mov	eax, [free_pages]
 10729 00003176 21C0                <1> 	and	eax, eax
 10730 00003178 7438                <1> 	jz	short out_of_memory
 10731                              <1> 	;
 10732 0000317A 53                  <1> 	push	ebx
 10733 0000317B 51                  <1> 	push	ecx
 10734                              <1> 	;
 10735 0000317C BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
 10736 00003181 89D9                <1> 	mov	ecx, ebx
 10737                              <1>  				     ; NOTE: 32 (first_page) is initial
 10738                              <1> 				     ; value of [next_page].
 10739                              <1> 				     ; It points to the first available
 10740                              <1> 				     ; page block for users (ring 3) ...	
 10741                              <1> 				     ; (MAT offset 32 = 1024/32)	
 10742                              <1> 				     ; (at the of the first 4 MB)		
 10743 00003183 031D[D4780000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
 10744                              <1> 				 ; next_free_page >> 5
 10745 00003189 030D[D8780000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
 10746                              <1> 				 ; (total_pages - 1) >> 5
 10747                              <1> al_p_scan:
 10748 0000318F 39CB                <1> 	cmp	ebx, ecx
 10749 00003191 770A                <1> 	ja	short al_p_notfound
 10750                              <1> 	;
 10751                              <1> 	; 01/07/2015
 10752                              <1> 	; AMD64 Architecture Programmers Manual
 10753                              <1> 	; Volume 3:
 10754                              <1> 	; General-Purpose and System Instructions
 10755                              <1> 	;
 10756                              <1> 	; BSF - Bit Scan Forward
 10757                              <1> 	;
 10758                              <1> 	;   Searches the value in a register or a memory location
 10759                              <1> 	;   (second operand) for the least-significant set bit. 
 10760                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
 10761                              <1> 	;   and stores the index of the least-significant set bit in a destination
 10762                              <1> 	;   register (first operand). If the second operand contains 0, 
 10763                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
 10764                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
 10765                              <1> 	;   of the searched value
 10766                              <1> 	;
 10767 00003193 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 10768                              <1> 			   ; Clear ZF if a bit is found set (1) and 
 10769                              <1> 			   ; loads the destination with an index to
 10770                              <1> 			   ; first set bit. (0 -> 31) 
 10771                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 10772 00003196 7525                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
 10773                              <1> 			 ;
 10774                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
 10775                              <1> 			 ;	  with value of 1 means 
 10776                              <1> 			 ;	  the corresponding page is free 
 10777                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
 10778 00003198 83C304              <1> 	add	ebx, 4
 10779                              <1> 			 ; We return back for searching next page block
 10780                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
 10781                              <1> 			 ;	 we always will find at least 1 free page here.
 10782 0000319B EBF2                <1>         jmp     short al_p_scan
 10783                              <1> 	;
 10784                              <1> al_p_notfound:
 10785 0000319D 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10786 000031A3 890D[D4780000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
 10787                              <1> 				 ; (deallocate_page procedure will change it)
 10788 000031A9 31C0                <1> 	xor	eax, eax
 10789 000031AB A3[D0780000]        <1> 	mov	[free_pages], eax ; 0
 10790 000031B0 59                  <1> 	pop	ecx
 10791 000031B1 5B                  <1> 	pop	ebx
 10792                              <1> 	;
 10793                              <1> out_of_memory:
 10794 000031B2 E857040000          <1> 	call	swap_out
 10795 000031B7 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
 10796                              <1> 	;
 10797 000031B9 29C0                <1> 	sub 	eax, eax ; 0
 10798 000031BB F9                  <1> 	stc
 10799 000031BC C3                  <1> 	retn
 10800                              <1> 
 10801                              <1> al_p_found:
 10802 000031BD 89D9                <1> 	mov	ecx, ebx
 10803 000031BF 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10804 000031C5 890D[D4780000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
 10805                              <1> 				 ; address/offset (to the next)
 10806 000031CB FF0D[D0780000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
 10807                              <1> 	;
 10808 000031D1 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 10809                              <1> 				 ; is copied into the Carry Flag and then cleared
 10810                              <1> 				 ; in the destination.
 10811                              <1> 				 ;
 10812                              <1> 				 ; Reset the bit which is corresponding to the 
 10813                              <1> 				 ; (just) allocated page.
 10814                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
 10815 000031D4 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
 10816 000031D7 01C8                <1> 	add	eax, ecx	 ; = page number
 10817 000031D9 C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
 10818                              <1> 	; EAX = physical address of memory page
 10819                              <1> 	;
 10820                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
 10821                              <1> 	;       according to this EAX value...
 10822 000031DC 59                  <1> 	pop	ecx
 10823 000031DD 5B                  <1> 	pop	ebx
 10824                              <1> al_p_ok:
 10825 000031DE C3                  <1> 	retn
 10826                              <1> 
 10827                              <1> 
 10828                              <1> make_page_dir:
 10829                              <1> 	; 18/04/2015
 10830                              <1> 	; 12/04/2015
 10831                              <1> 	; 23/10/2014
 10832                              <1> 	; 16/10/2014
 10833                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10834                              <1> 	;
 10835                              <1> 	; INPUT ->
 10836                              <1> 	;	none
 10837                              <1> 	; OUTPUT ->
 10838                              <1> 	;	(EAX = 0)
 10839                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10840                              <1> 	;	cf = 0 ->
 10841                              <1> 	;	u.pgdir = page directory (physical) address of the current
 10842                              <1> 	;		  process/user.
 10843                              <1> 	;
 10844                              <1> 	; Modified Registers -> EAX
 10845                              <1> 	;
 10846 000031DF E88DFFFFFF          <1> 	call	allocate_page
 10847 000031E4 7216                <1> 	jc	short mkpd_error
 10848                              <1> 	;
 10849 000031E6 A3[B1850000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
 10850                              <1> 				  ; (Physical address)
 10851                              <1> clear_page:
 10852                              <1> 	; 18/04/2015
 10853                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10854                              <1> 	;
 10855                              <1> 	; INPUT ->
 10856                              <1> 	;	EAX = physical address of the page
 10857                              <1> 	; OUTPUT ->
 10858                              <1> 	;	all bytes of the page will be cleared
 10859                              <1> 	;
 10860                              <1> 	; Modified Registers -> none
 10861                              <1> 	;
 10862 000031EB 57                  <1> 	push	edi
 10863 000031EC 51                  <1> 	push	ecx
 10864 000031ED 50                  <1> 	push	eax
 10865 000031EE B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 10866 000031F3 89C7                <1> 	mov	edi, eax
 10867 000031F5 31C0                <1> 	xor	eax, eax
 10868 000031F7 F3AB                <1> 	rep	stosd
 10869 000031F9 58                  <1> 	pop	eax
 10870 000031FA 59                  <1> 	pop	ecx
 10871 000031FB 5F                  <1> 	pop	edi
 10872                              <1> mkpd_error:
 10873                              <1> mkpt_error:
 10874 000031FC C3                  <1> 	retn
 10875                              <1> 
 10876                              <1> make_page_table:
 10877                              <1> 	; 23/06/2015
 10878                              <1> 	; 18/04/2015
 10879                              <1> 	; 12/04/2015
 10880                              <1> 	; 16/10/2014
 10881                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10882                              <1> 	;
 10883                              <1> 	; INPUT ->
 10884                              <1> 	;	EBX = virtual (linear) address
 10885                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10886                              <1> 	;	      (higher 20 bits must be ZERO)
 10887                              <1> 	;	      (bit 0 must be 1)	 
 10888                              <1> 	;	u.pgdir = page directory (physical) address
 10889                              <1> 	; OUTPUT ->
 10890                              <1> 	;	EDX = Page directory entry address
 10891                              <1> 	;	EAX = Page table address
 10892                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10893                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
 10894                              <1> 	;
 10895                              <1> 	; Modified Registers -> EAX, EDX
 10896                              <1> 	;
 10897 000031FD E86FFFFFFF          <1> 	call	allocate_page
 10898 00003202 72F8                <1> 	jc	short mkpt_error
 10899 00003204 E811000000          <1> 	call	set_pde	
 10900 00003209 EBE0                <1> 	jmp	short clear_page
 10901                              <1> 
 10902                              <1> make_page:
 10903                              <1> 	; 24/07/2015
 10904                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
 10905                              <1> 	;
 10906                              <1> 	; INPUT ->
 10907                              <1> 	;	EBX = virtual (linear) address
 10908                              <1> 	;	ECX = page attributes (lower 12 bits)
 10909                              <1> 	;	      (higher 20 bits must be ZERO)
 10910                              <1> 	;	      (bit 0 must be 1)	 
 10911                              <1> 	;	u.pgdir = page directory (physical) address
 10912                              <1> 	; OUTPUT ->
 10913                              <1> 	;	EBX = Virtual address
 10914                              <1> 	;	(EDX = PTE value)
 10915                              <1> 	;	EAX = Physical address
 10916                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10917                              <1> 	;
 10918                              <1> 	; Modified Registers -> EAX, EDX
 10919                              <1> 	;
 10920 0000320B E861FFFFFF          <1> 	call	allocate_page
 10921 00003210 7207                <1> 	jc	short mkp_err
 10922 00003212 E821000000          <1> 	call	set_pte	
 10923 00003217 73D2                <1> 	jnc	short clear_page ; 18/04/2015
 10924                              <1> mkp_err:
 10925 00003219 C3                  <1> 	retn
 10926                              <1> 
 10927                              <1> 
 10928                              <1> set_pde:	; Set page directory entry (PDE)
 10929                              <1> 	; 20/07/2015
 10930                              <1> 	; 18/04/2015
 10931                              <1> 	; 12/04/2015
 10932                              <1> 	; 23/10/2014
 10933                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10934                              <1> 	;
 10935                              <1> 	; INPUT ->
 10936                              <1> 	;	EAX = physical address
 10937                              <1> 	;	      (use present value if EAX = 0)
 10938                              <1> 	;	EBX = virtual (linear) address
 10939                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10940                              <1> 	;	      (higher 20 bits must be ZERO)
 10941                              <1> 	;	      (bit 0 must be 1)	 
 10942                              <1> 	;	u.pgdir = page directory (physical) address
 10943                              <1> 	; OUTPUT ->
 10944                              <1> 	;	EDX = PDE address
 10945                              <1> 	;	EAX = page table address (physical)
 10946                              <1> 	;	;(CF=1 -> Invalid page address)
 10947                              <1> 	;
 10948                              <1> 	; Modified Registers -> EDX
 10949                              <1> 	;
 10950 0000321A 89DA                <1> 	mov	edx, ebx
 10951 0000321C C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
 10952 0000321F C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
 10953 00003222 0315[B1850000]      <1> 	add	edx, [u.pgdir]
 10954                              <1> 	;
 10955 00003228 21C0                <1> 	and	eax, eax
 10956 0000322A 7506                <1> 	jnz	short spde_1
 10957                              <1> 	;
 10958 0000322C 8B02                <1> 	mov	eax, [edx]  ; old PDE value
 10959                              <1> 	;test	al, 1
 10960                              <1> 	;jz	short spde_2
 10961 0000322E 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
 10962                              <1> spde_1:
 10963                              <1> 	;and	cx, 0FFFh
 10964 00003232 8902                <1> 	mov	[edx], eax
 10965 00003234 66090A              <1> 	or	[edx], cx
 10966 00003237 C3                  <1> 	retn
 10967                              <1> ;spde_2: ; error
 10968                              <1> ;	stc
 10969                              <1> ;	retn
 10970                              <1> 
 10971                              <1> set_pte:	; Set page table entry (PTE)
 10972                              <1> 	; 24/07/2015
 10973                              <1> 	; 20/07/2015
 10974                              <1> 	; 23/06/2015
 10975                              <1> 	; 18/04/2015
 10976                              <1> 	; 12/04/2015
 10977                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10978                              <1> 	;
 10979                              <1> 	; INPUT ->
 10980                              <1> 	;	EAX = physical page address
 10981                              <1> 	;	      (use present value if EAX = 0)
 10982                              <1> 	;	EBX = virtual (linear) address
 10983                              <1> 	;	ECX = page attributes (lower 12 bits)
 10984                              <1> 	;	      (higher 20 bits must be ZERO)
 10985                              <1> 	;	      (bit 0 must be 1)	 
 10986                              <1> 	;	u.pgdir = page directory (physical) address
 10987                              <1> 	; OUTPUT ->
 10988                              <1> 	;	EAX = physical page address
 10989                              <1> 	;	(EDX = PTE value)
 10990                              <1> 	;	EBX = virtual address
 10991                              <1> 	;
 10992                              <1> 	;	CF = 1 -> error
 10993                              <1> 	;
 10994                              <1> 	; Modified Registers -> EAX, EDX
 10995                              <1> 	;
 10996 00003238 50                  <1> 	push	eax
 10997 00003239 A1[B1850000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
 10998 0000323E E837000000          <1> 	call 	get_pde
 10999                              <1> 		; EDX = PDE address
 11000                              <1> 		; EAX = PDE value
 11001 00003243 5A                  <1> 	pop	edx ; physical page address
 11002 00003244 722A                <1> 	jc	short spte_err ; PDE not present
 11003                              <1> 	;
 11004 00003246 53                  <1> 	push	ebx ; 24/07/2015
 11005 00003247 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 11006                              <1> 			    ; EDX = PT address (physical)	
 11007 0000324B C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
 11008 0000324E 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
 11009                              <1> 			 ; clear higher 10 bits (PD bits)
 11010 00003254 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
 11011 00003257 01C3                <1> 	add	ebx, eax
 11012                              <1> 	;
 11013 00003259 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
 11014 0000325B A801                <1> 	test	al, 1
 11015 0000325D 740C                <1> 	jz	short spte_0
 11016 0000325F 09D2                <1> 	or	edx, edx
 11017 00003261 750F                <1> 	jnz	short spte_1
 11018 00003263 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
 11019 00003267 89C2                <1> 	mov	edx, eax
 11020 00003269 EB09                <1> 	jmp	short spte_2	
 11021                              <1> spte_0:
 11022                              <1> 	; If this PTE contains a swap (disk) address,
 11023                              <1> 	; it can be updated by using 'swap_in' procedure
 11024                              <1> 	; only!
 11025 0000326B 21C0                <1> 	and	eax, eax
 11026 0000326D 7403                <1> 	jz	short spte_1
 11027                              <1> 	; 24/07/2015
 11028                              <1> 	; swapped page ! (on disk)
 11029 0000326F 5B                  <1> 	pop	ebx
 11030                              <1> spte_err:
 11031 00003270 F9                  <1> 	stc
 11032 00003271 C3                  <1> 	retn
 11033                              <1> spte_1: 
 11034 00003272 89D0                <1> 	mov	eax, edx
 11035                              <1> spte_2:
 11036 00003274 09CA                <1> 	or	edx, ecx
 11037                              <1> 	; 23/06/2015
 11038 00003276 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
 11039                              <1> 	; 24/07/2015
 11040 00003278 5B                  <1> 	pop	ebx
 11041 00003279 C3                  <1> 	retn
 11042                              <1> 
 11043                              <1> get_pde:	; Get present value of the relevant PDE
 11044                              <1> 	; 20/07/2015
 11045                              <1> 	; 18/04/2015
 11046                              <1> 	; 12/04/2015
 11047                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 11048                              <1> 	;
 11049                              <1> 	; INPUT ->
 11050                              <1> 	;	EBX = virtual (linear) address
 11051                              <1> 	;	EAX = page directory (physical) address
 11052                              <1> 	; OUTPUT ->
 11053                              <1> 	;	EDX = Page directory entry address
 11054                              <1> 	;	EAX = Page directory entry value
 11055                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 11056                              <1> 	; Modified Registers -> EDX, EAX
 11057                              <1> 	;
 11058 0000327A 89DA                <1> 	mov	edx, ebx
 11059 0000327C C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
 11060 0000327F C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
 11061 00003282 01C2                <1> 	add	edx, eax ; page directory address (physical)
 11062 00003284 8B02                <1> 	mov	eax, [edx]
 11063 00003286 A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
 11064 00003288 751F                <1> 	jnz	short gpte_retn
 11065 0000328A F9                  <1> 	stc
 11066                              <1> gpde_retn:	
 11067 0000328B C3                  <1> 	retn
 11068                              <1> 
 11069                              <1> get_pte:
 11070                              <1> 		; Get present value of the relevant PTE
 11071                              <1> 	; 29/07/2015
 11072                              <1> 	; 20/07/2015
 11073                              <1> 	; 18/04/2015
 11074                              <1> 	; 12/04/2015
 11075                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 11076                              <1> 	;
 11077                              <1> 	; INPUT ->
 11078                              <1> 	;	EBX = virtual (linear) address
 11079                              <1> 	;	EAX = page directory (physical) address
 11080                              <1> 	; OUTPUT ->
 11081                              <1> 	;	EDX = Page table entry address (if CF=0)
 11082                              <1> 	;	      Page directory entry address (if CF=1)
 11083                              <1> 	;            (Bit 0 value is 0 if PT is not present)
 11084                              <1> 	;	EAX = Page table entry value (page address)
 11085                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 11086                              <1> 	; Modified Registers -> EAX, EDX
 11087                              <1> 	;
 11088 0000328C E8E9FFFFFF          <1> 	call 	get_pde
 11089 00003291 72F8                <1> 	jc	short gpde_retn	; page table is not present
 11090                              <1> 	;jnc	short gpte_1
 11091                              <1> 	;retn
 11092                              <1> ;gpte_1:
 11093 00003293 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 11094 00003297 89DA                <1> 	mov	edx, ebx
 11095 00003299 C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
 11096 0000329C 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
 11097                              <1> 			 ; clear higher 10 bits (PD bits)
 11098 000032A2 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
 11099 000032A5 01C2                <1> 	add	edx, eax
 11100 000032A7 8B02                <1> 	mov	eax, [edx]
 11101                              <1> gpte_retn:
 11102 000032A9 C3                  <1> 	retn
 11103                              <1> 
 11104                              <1> deallocate_page_dir:
 11105                              <1> 	; 15/09/2015
 11106                              <1> 	; 05/08/2015
 11107                              <1> 	; 30/04/2015
 11108                              <1> 	; 28/04/2015
 11109                              <1> 	; 17/10/2014
 11110                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 11111                              <1> 	;
 11112                              <1> 	; INPUT ->
 11113                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
 11114                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 11115                              <1> 	; OUTPUT ->
 11116                              <1> 	;	All of page tables in the page directory
 11117                              <1> 	;	and page dir's itself will be deallocated
 11118                              <1> 	;	except 'read only' duplicated pages (will be converted
 11119                              <1> 	;	to writable pages).
 11120                              <1> 	;
 11121                              <1> 	; Modified Registers -> EAX
 11122                              <1> 	;
 11123                              <1> 	;
 11124 000032AA 56                  <1> 	push	esi
 11125 000032AB 51                  <1> 	push	ecx
 11126 000032AC 50                  <1> 	push	eax
 11127 000032AD 89C6                <1> 	mov	esi, eax 
 11128 000032AF 31C9                <1> 	xor	ecx, ecx
 11129                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
 11130                              <1> 	; it must not be deallocated
 11131 000032B1 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
 11132                              <1> dapd_0:
 11133 000032B3 AD                  <1> 	lodsd
 11134 000032B4 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
 11135 000032B6 7409                <1> 	jz	short dapd_1	
 11136 000032B8 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 11137 000032BC E812000000          <1> 	call	deallocate_page_table			
 11138                              <1> dapd_1:
 11139 000032C1 41                  <1> 	inc	ecx ; page directory entry index
 11140 000032C2 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
 11141 000032C8 72E9                <1> 	jb	short dapd_0
 11142                              <1> dapd_2:
 11143 000032CA 58                  <1> 	pop	eax
 11144 000032CB E879000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
 11145 000032D0 59                  <1> 	pop	ecx
 11146 000032D1 5E                  <1> 	pop	esi
 11147 000032D2 C3                  <1> 	retn
 11148                              <1> 
 11149                              <1> deallocate_page_table:
 11150                              <1> 	; 19/09/2015
 11151                              <1> 	; 15/09/2015
 11152                              <1> 	; 05/08/2015
 11153                              <1> 	; 30/04/2015
 11154                              <1> 	; 28/04/2015
 11155                              <1> 	; 24/10/2014
 11156                              <1> 	; 23/10/2014
 11157                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 11158                              <1> 	;
 11159                              <1> 	; INPUT ->
 11160                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
 11161                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 11162                              <1> 	;	(ECX = page directory entry index)
 11163                              <1> 	; OUTPUT ->
 11164                              <1> 	;	All of pages in the page table and page table's itself
 11165                              <1> 	;	will be deallocated except 'read only' duplicated pages
 11166                              <1> 	;	(will be converted to writable pages).
 11167                              <1> 	;
 11168                              <1> 	; Modified Registers -> EAX
 11169                              <1> 	;
 11170 000032D3 56                  <1> 	push	esi
 11171 000032D4 57                  <1> 	push	edi
 11172 000032D5 52                  <1> 	push	edx
 11173 000032D6 50                  <1> 	push	eax ; *
 11174 000032D7 89C6                <1> 	mov	esi, eax 
 11175 000032D9 31FF                <1> 	xor	edi, edi ; 0
 11176                              <1> dapt_0:
 11177 000032DB AD                  <1> 	lodsd
 11178 000032DC A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
 11179 000032DE 7441                <1> 	jz	short dapt_1
 11180                              <1> 	;
 11181 000032E0 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
 11182                              <1> 				  ; (must be 1)
 11183 000032E2 754C                <1> 	jnz	short dapt_3
 11184                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
 11185 000032E4 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
 11186                              <1> 				   ; as child's page ?
 11187 000032E8 744B                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
 11188                              <1> 	; check the parent's PTE value is read only & same page or not.. 
 11189                              <1> 	; ECX = page directory entry index (0-1023)
 11190 000032EA 53                  <1> 	push	ebx
 11191 000032EB 51                  <1> 	push	ecx
 11192 000032EC 66C1E102            <1> 	shl	cx, 2 ; *4 
 11193 000032F0 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
 11194 000032F2 8B0B                <1> 	mov	ecx, [ebx]
 11195 000032F4 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
 11196 000032F7 7435                <1> 	jz	short dapt_2	; parent process does not use this page
 11197 000032F9 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 11198                              <1> 	; EDI = page table entry index (0-1023)
 11199 000032FE 89FA                <1> 	mov	edx, edi 
 11200 00003300 66C1E202            <1> 	shl	dx, 2 ; *4 
 11201 00003304 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
 11202 00003306 8B1A                <1> 	mov	ebx, [edx]
 11203 00003308 F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
 11204 0000330B 7421                <1> 	jz	short dapt_2	; parent process does not use this page
 11205 0000330D 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
 11206 00003311 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
 11207 00003316 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
 11208 00003318 7514                <1> 	jne	short dapt_2	; not same page
 11209                              <1> 				; deallocate the child's page
 11210 0000331A 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
 11211 0000331D 59                  <1> 	pop	ecx
 11212 0000331E 5B                  <1> 	pop	ebx
 11213 0000331F EB14                <1> 	jmp	short dapt_4
 11214                              <1> dapt_1:
 11215 00003321 09C0                <1> 	or	eax, eax	; swapped page ?
 11216 00003323 7417                <1> 	jz	short dapt_5	; no
 11217                              <1> 				; yes
 11218 00003325 D1E8                <1> 	shr	eax, 1
 11219 00003327 E848040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
 11220                              <1> 				  ; on the swap disk (or in file)
 11221 0000332C EB0E                <1> 	jmp	short dapt_5
 11222                              <1> dapt_2:
 11223 0000332E 59                  <1> 	pop	ecx
 11224 0000332F 5B                  <1> 	pop	ebx
 11225                              <1> dapt_3:	
 11226                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 11227 00003330 E814000000          <1> 	call	deallocate_page
 11228                              <1> dapt_4:
 11229 00003335 C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
 11230                              <1> dapt_5:
 11231 0000333C 47                  <1> 	inc	edi ; page table entry index
 11232 0000333D 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
 11233 00003343 7296                <1> 	jb	short dapt_0
 11234                              <1> 	;
 11235 00003345 58                  <1> 	pop	eax ; *
 11236 00003346 5A                  <1> 	pop	edx
 11237 00003347 5F                  <1> 	pop	edi	
 11238 00003348 5E                  <1> 	pop	esi
 11239                              <1> 	;
 11240                              <1> 	;call	deallocate_page	; deallocate the page table's itself
 11241                              <1> 	;retn
 11242                              <1> 
 11243                              <1> deallocate_page:
 11244                              <1> 	; 15/09/2015
 11245                              <1> 	; 28/04/2015
 11246                              <1> 	; 10/03/2015
 11247                              <1> 	; 17/10/2014
 11248                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 11249                              <1> 	;
 11250                              <1> 	; INPUT -> 
 11251                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11252                              <1> 	; OUTPUT ->
 11253                              <1> 	;	[free_pages] is increased
 11254                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
 11255                              <1> 	;	CF = 1 if the page is already deallocated
 11256                              <1> 	; 	       (or not allocated) before.  
 11257                              <1> 	;
 11258                              <1> 	; Modified Registers -> EAX
 11259                              <1> 	;
 11260 00003349 53                  <1> 	push	ebx
 11261 0000334A 52                  <1> 	push	edx
 11262                              <1> 	;
 11263 0000334B C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
 11264                              <1> 				     ; 12 bits right
 11265                              <1> 				     ; to get page number
 11266 0000334E 89C2                <1> 	mov	edx, eax
 11267                              <1> 	; 15/09/2015
 11268 00003350 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
 11269                              <1> 				     ; (1 allocation bit = 1 page)
 11270                              <1> 				     ; (1 allocation bytes = 8 pages)
 11271 00003353 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 11272                              <1> 				     ; (to get 32 bit position)			
 11273                              <1> 	;
 11274 00003356 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
 11275 0000335B 01D3                <1> 	add	ebx, edx
 11276 0000335D 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 11277                              <1> 				     ; (allocation bit position)	 
 11278 00003360 3B15[D4780000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
 11279                              <1> 				     ; than the address in 'next_page' ?
 11280                              <1> 				     ; (next/first free page value)		
 11281 00003366 7306                <1> 	jnb	short dap_1	     ; no	
 11282 00003368 8915[D4780000]      <1> 	mov	[next_page], edx     ; yes
 11283                              <1> dap_1:
 11284 0000336E 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
 11285                              <1> 				     ; set relevant bit to 1.
 11286                              <1> 				     ; set CF to the previous bit value	
 11287                              <1> 	;cmc			     ; complement carry flag	
 11288                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
 11289                              <1> 				     ; if the page is already deallocated
 11290                              <1> 				     ; before.	
 11291 00003371 FF05[D0780000]      <1>         inc     dword [free_pages]
 11292                              <1> dap_2:
 11293 00003377 5A                  <1> 	pop	edx
 11294 00003378 5B                  <1> 	pop	ebx
 11295 00003379 C3                  <1> 	retn
 11296                              <1> 
 11297                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 11298                              <1> ;;                                                              ;;
 11299                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
 11300                              <1> ;; Distributed under terms of the GNU General Public License    ;;
 11301                              <1> ;;                                                              ;;
 11302                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 11303                              <1> 
 11304                              <1> ;;$Revision: 5057 $
 11305                              <1> 
 11306                              <1> 
 11307                              <1> ;;align 4
 11308                              <1> ;;proc alloc_page
 11309                              <1> 
 11310                              <1> ;;        pushfd
 11311                              <1> ;;        cli
 11312                              <1> ;;        push    ebx
 11313                              <1> ;;;//-
 11314                              <1> ;;        cmp     [pg_data.pages_free], 1
 11315                              <1> ;;        jle     .out_of_memory
 11316                              <1> ;;;//-
 11317                              <1> ;;
 11318                              <1> ;;        mov     ebx, [page_start]
 11319                              <1> ;;        mov     ecx, [page_end]
 11320                              <1> ;;.l1:
 11321                              <1> ;;        bsf     eax, [ebx];
 11322                              <1> ;;        jnz     .found
 11323                              <1> ;;        add     ebx, 4
 11324                              <1> ;;        cmp     ebx, ecx
 11325                              <1> ;;        jb      .l1
 11326                              <1> ;;        pop     ebx
 11327                              <1> ;;        popfd
 11328                              <1> ;;        xor     eax, eax
 11329                              <1> ;;        ret
 11330                              <1> ;;.found:
 11331                              <1> ;;;//-
 11332                              <1> ;;        dec     [pg_data.pages_free]
 11333                              <1> ;;        jz      .out_of_memory
 11334                              <1> ;;;//-
 11335                              <1> ;;        btr     [ebx], eax
 11336                              <1> ;;        mov     [page_start], ebx
 11337                              <1> ;;        sub     ebx, sys_pgmap
 11338                              <1> ;;        lea     eax, [eax+ebx*8]
 11339                              <1> ;;        shl     eax, 12
 11340                              <1> ;;;//-       dec [pg_data.pages_free]
 11341                              <1> ;;        pop     ebx
 11342                              <1> ;;        popfd
 11343                              <1> ;;        ret
 11344                              <1> ;;;//-
 11345                              <1> ;;.out_of_memory:
 11346                              <1> ;;        mov     [pg_data.pages_free], 1
 11347                              <1> ;;        xor     eax, eax
 11348                              <1> ;;        pop     ebx
 11349                              <1> ;;        popfd
 11350                              <1> ;;        ret
 11351                              <1> ;;;//-
 11352                              <1> ;;endp
 11353                              <1> 
 11354                              <1> duplicate_page_dir:
 11355                              <1> 	; 21/09/2015
 11356                              <1> 	; 31/08/2015
 11357                              <1> 	; 20/07/2015
 11358                              <1> 	; 28/04/2015
 11359                              <1> 	; 27/04/2015
 11360                              <1> 	; 18/04/2015
 11361                              <1> 	; 12/04/2015
 11362                              <1> 	; 18/10/2014
 11363                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 11364                              <1> 	;
 11365                              <1> 	; INPUT -> 
 11366                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 11367                              <1> 	;		    page directory.
 11368                              <1> 	; OUTPUT ->
 11369                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 11370                              <1> 	;	       page directory.
 11371                              <1> 	;	(New page directory with new page table entries.)
 11372                              <1> 	;	(New page tables with read only copies of the parent's
 11373                              <1> 	;	pages.)
 11374                              <1> 	;	EAX = 0 -> Error (CF = 1)
 11375                              <1> 	;
 11376                              <1> 	; Modified Registers -> none (except EAX)
 11377                              <1> 	;
 11378 0000337A E8F2FDFFFF          <1> 	call	allocate_page
 11379 0000337F 723E                <1> 	jc	short dpd_err
 11380                              <1> 	;
 11381 00003381 55                  <1> 	push	ebp ; 20/07/2015
 11382 00003382 56                  <1> 	push	esi
 11383 00003383 57                  <1> 	push	edi
 11384 00003384 53                  <1> 	push	ebx
 11385 00003385 51                  <1> 	push	ecx
 11386 00003386 8B35[B1850000]      <1> 	mov	esi, [u.pgdir]
 11387 0000338C 89C7                <1> 	mov	edi, eax
 11388 0000338E 50                  <1> 	push	eax ; save child's page directory address
 11389                              <1> 	; 31/08/2015
 11390                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 11391                              <1> 	; (use same system space for all user page tables) 
 11392 0000338F A5                  <1> 	movsd
 11393 00003390 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 11394 00003395 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 11395                              <1> dpd_0:	
 11396 0000339A AD                  <1> 	lodsd
 11397                              <1> 	;or	eax, eax
 11398                              <1>         ;jnz     short dpd_1
 11399 0000339B A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 11400 0000339D 7508                <1> 	jnz	short dpd_1
 11401                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
 11402 0000339F 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 11403 000033A5 EB0F                <1> 	jmp	short dpd_2
 11404                              <1> dpd_1:	
 11405 000033A7 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 11406 000033AB 89C3                <1> 	mov	ebx, eax
 11407                              <1> 	; EBX = Parent's page table address
 11408 000033AD E81F000000          <1> 	call	duplicate_page_table
 11409 000033B2 720C                <1> 	jc	short dpd_p_err
 11410                              <1> 	; EAX = Child's page table address
 11411 000033B4 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 11412                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 11413                              <1> 			 ; (present, writable, user)
 11414                              <1> dpd_2:
 11415 000033B6 AB                  <1> 	stosd
 11416 000033B7 E2E1                <1> 	loop	dpd_0
 11417                              <1> 	;
 11418 000033B9 58                  <1> 	pop	eax  ; restore child's page directory address
 11419                              <1> dpd_3:
 11420 000033BA 59                  <1> 	pop	ecx
 11421 000033BB 5B                  <1> 	pop	ebx
 11422 000033BC 5F                  <1> 	pop	edi
 11423 000033BD 5E                  <1> 	pop	esi
 11424 000033BE 5D                  <1> 	pop	ebp ; 20/07/2015
 11425                              <1> dpd_err:
 11426 000033BF C3                  <1> 	retn
 11427                              <1> dpd_p_err:
 11428                              <1> 	; release the allocated pages missing (recover free space)
 11429 000033C0 58                  <1> 	pop	eax  ; the new page directory address (physical)
 11430 000033C1 8B1D[B1850000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 11431 000033C7 E8DEFEFFFF          <1> 	call 	deallocate_page_dir
 11432 000033CC 29C0                <1> 	sub	eax, eax ; 0
 11433 000033CE F9                  <1> 	stc
 11434 000033CF EBE9                <1> 	jmp	short dpd_3	
 11435                              <1> 
 11436                              <1> duplicate_page_table:
 11437                              <1> 	; 21/09/2015
 11438                              <1> 	; 20/07/2015
 11439                              <1> 	; 05/05/2015
 11440                              <1> 	; 28/04/2015
 11441                              <1> 	; 27/04/2015
 11442                              <1> 	; 18/04/2015
 11443                              <1> 	; 18/10/2014
 11444                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 11445                              <1> 	;
 11446                              <1> 	; INPUT -> 
 11447                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 11448                              <1> 	;	EBP = page table entry index (from 'duplicate_page_dir')
 11449                              <1> 	; OUTPUT ->
 11450                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 11451                              <1> 	;	      (with 'read only' attribute of page table entries)
 11452                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 11453                              <1> 	;	CF = 1 -> error 
 11454                              <1> 	;
 11455                              <1> 	; Modified Registers -> EBP (except EAX)
 11456                              <1> 	;
 11457 000033D1 E89BFDFFFF          <1> 	call	allocate_page
 11458 000033D6 726A                <1> 	jc	short dpt_err
 11459                              <1> 	;
 11460 000033D8 50                  <1> 	push	eax ; *
 11461 000033D9 56                  <1> 	push	esi
 11462 000033DA 57                  <1> 	push	edi
 11463 000033DB 52                  <1> 	push	edx
 11464 000033DC 51                  <1> 	push	ecx
 11465                              <1> 	;
 11466 000033DD 89DE                <1> 	mov	esi, ebx
 11467 000033DF 89C7                <1> 	mov	edi, eax
 11468 000033E1 89C2                <1> 	mov	edx, eax
 11469 000033E3 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 11470                              <1> dpt_0:
 11471 000033E9 AD                  <1> 	lodsd
 11472 000033EA 21C0                <1> 	and	eax, eax
 11473 000033EC 7444                <1> 	jz	short dpt_3
 11474 000033EE A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 11475 000033F0 7507                <1> 	jnz	short dpt_1
 11476                              <1> 	; 20/07/2015
 11477                              <1> 	; ebp = virtual (linear) address of the memory page
 11478 000033F2 E887040000          <1> 	call	reload_page ; 28/04/2015
 11479 000033F7 7244                <1> 	jc	short dpt_p_err
 11480                              <1> dpt_1:
 11481                              <1> 	; 21/09/2015
 11482 000033F9 89C1                <1> 	mov	ecx, eax
 11483 000033FB 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11484 000033FF F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
 11485 00003402 7525                <1> 	jnz	short dpt_2
 11486                              <1> 	; Read only (parent) page
 11487                              <1> 	; 	- there is a third process which uses this page -
 11488                              <1> 	; Allocate a new page for the child process
 11489 00003404 E868FDFFFF          <1> 	call	allocate_page
 11490 00003409 7232                <1> 	jc	short dpt_p_err
 11491 0000340B 57                  <1> 	push	edi
 11492 0000340C 56                  <1> 	push	esi
 11493 0000340D 89CE                <1> 	mov	esi, ecx
 11494 0000340F 89C7                <1> 	mov	edi, eax
 11495 00003411 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 11496 00003416 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 11497 00003418 5E                  <1> 	pop	esi
 11498 00003419 5F                  <1> 	pop	edi
 11499                              <1> 	; 
 11500 0000341A 53                  <1> 	push	ebx
 11501 0000341B 50                  <1> 	push	eax
 11502                              <1> 	; 20/07/2015
 11503 0000341C 89EB                <1> 	mov	ebx, ebp
 11504                              <1> 	; ebx = virtual address of the memory page
 11505 0000341E E80B030000          <1> 	call	add_to_swap_queue
 11506 00003423 58                  <1> 	pop	eax
 11507 00003424 5B                  <1> 	pop	ebx
 11508                              <1> 	; 21/09/2015
 11509 00003425 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 11510                              <1> 		; user + writable + present page
 11511 00003427 EB09                <1> 	jmp	short dpt_3
 11512                              <1> dpt_2:
 11513                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 11514 00003429 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
 11515                              <1> 		    ; (read only page!)
 11516 0000342B 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
 11517 0000342E 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
 11518                              <1> dpt_3:
 11519 00003432 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 11520                              <1> 	;
 11521 00003433 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 11522                              <1> 	;
 11523 00003439 39D7                <1> 	cmp	edi, edx
 11524 0000343B 72AC                <1> 	jb	short dpt_0
 11525                              <1> dpt_p_err:
 11526 0000343D 59                  <1> 	pop	ecx
 11527 0000343E 5A                  <1> 	pop	edx
 11528 0000343F 5F                  <1> 	pop	edi
 11529 00003440 5E                  <1> 	pop	esi
 11530 00003441 58                  <1> 	pop	eax ; *
 11531                              <1> dpt_err:
 11532 00003442 C3                  <1> 	retn
 11533                              <1> 
 11534                              <1> page_fault_handler:	; CPU EXCEPTION 0Eh (14) : Page Fault !
 11535                              <1> 	; 21/09/2015
 11536                              <1> 	; 19/09/2015
 11537                              <1> 	; 17/09/2015
 11538                              <1> 	; 28/08/2015
 11539                              <1> 	; 20/07/2015
 11540                              <1> 	; 28/06/2015
 11541                              <1> 	; 03/05/2015
 11542                              <1> 	; 30/04/2015
 11543                              <1> 	; 18/04/2015
 11544                              <1> 	; 12/04/2015
 11545                              <1> 	; 30/10/2014
 11546                              <1> 	; 11/09/2014
 11547                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
 11548                              <1> 	;
 11549                              <1> 	; Note: This is not an interrupt/exception handler.
 11550                              <1> 	;	This is a 'page fault remedy' subroutine 
 11551                              <1> 	;	which will be called by standard/uniform
 11552                              <1> 	;	exception handler.
 11553                              <1> 	;
 11554                              <1> 	; INPUT -> 
 11555                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
 11556                              <1> 	;
 11557                              <1> 	;	cr2 = the virtual (linear) address 
 11558                              <1> 	;	      which has caused to page fault (19/09/2015)
 11559                              <1> 	;
 11560                              <1> 	; OUTPUT ->
 11561                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11562                              <1> 	;	EAX = 0 -> no error
 11563                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
 11564                              <1> 	;
 11565                              <1> 	; Modified Registers -> none (except EAX)
 11566                              <1> 	;	
 11567                              <1>         ;
 11568                              <1>         ; ERROR CODE:
 11569                              <1> 	;	 31  .....	4   3	2   1	0
 11570                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11571                              <1> 	;	|   Reserved  | I | R | U | W | P |
 11572                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11573                              <1> 	;
 11574                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
 11575                              <1>     	;		a page-protection violation. When not set,
 11576                              <1> 	;		it was caused by a non-present page.
 11577                              <1> 	; W : WRITE   -	When set, the page fault was caused by
 11578                              <1> 	;		a page write. When not set, it was caused
 11579                              <1> 	;		by a page read.
 11580                              <1> 	; U : USER    -	When set, the page fault was caused 
 11581                              <1> 	;		while CPL = 3. 
 11582                              <1> 	;		This does not necessarily mean that
 11583                              <1> 	;		the page fault was a privilege violation.
 11584                              <1> 	; R : RESERVD -	When set, the page fault was caused by
 11585                              <1> 	;     WRITE	reading a 1 in a reserved field.
 11586                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
 11587                              <1> 	;     FETCH	an instruction fetch
 11588                              <1> 	;
 11589                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
 11590                              <1> 	;  31               22                  12 11                    0
 11591                              <1> 	; +-------------------+-------------------+-----------------------+
 11592                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
 11593                              <1>        	; +-------------------+-------------------+-----------------------+
 11594                              <1> 	;
 11595                              <1> 
 11596                              <1> 	;; CR3 REGISTER (Control Register 3)
 11597                              <1> 	;  31                                   12             5 4 3 2   0
 11598                              <1> 	; +---------------------------------------+-------------+---+-----+
 11599                              <1>       	; |                                       |  		|P|P|     |
 11600                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
 11601                              <1>       	; |                                       | 		|D|T|     |
 11602                              <1>    	; +---------------------------------------+-------------+---+-----+
 11603                              <1> 	;
 11604                              <1> 	;	PWT    - WRITE THROUGH
 11605                              <1> 	;	PCD    - CACHE DISABLE		
 11606                              <1> 	;
 11607                              <1> 	;
 11608                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
 11609                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11610                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11611                              <1>       	; |                                       |     | | | | |P|P|U|R| |
 11612                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
 11613                              <1>       	; |                                       |     | | | | |D|T|S|W| |
 11614                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11615                              <1> 	;
 11616                              <1>         ;       P      - PRESENT
 11617                              <1>         ;       R/W    - READ/WRITE
 11618                              <1>         ;       U/S    - USER/SUPERVISOR
 11619                              <1> 	;	PWT    - WRITE THROUGH
 11620                              <1> 	;	PCD    - CACHE DISABLE	
 11621                              <1> 	;	A      - ACCESSED	
 11622                              <1>         ;       D      - DIRTY (IGNORED)
 11623                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11624                              <1> 	;	G      - GLOBAL	(IGNORED) 
 11625                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11626                              <1> 	;
 11627                              <1> 	;
 11628                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
 11629                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11630                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11631                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
 11632                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
 11633                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
 11634                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11635                              <1> 	;
 11636                              <1>         ;       P      - PRESENT
 11637                              <1>         ;       R/W    - READ/WRITE
 11638                              <1>         ;       U/S    - USER/SUPERVISOR
 11639                              <1> 	;	PWT    - WRITE THROUGH
 11640                              <1> 	;	PCD    - CACHE DISABLE	
 11641                              <1> 	;	A      - ACCESSED	
 11642                              <1>         ;       D      - DIRTY
 11643                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11644                              <1> 	;	G      - GLOBAL	 
 11645                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11646                              <1> 	;
 11647                              <1> 	;
 11648                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
 11649                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11650                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11651                              <1>       	; |                                       |     | | | | | | |U|R| |
 11652                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
 11653                              <1>       	; |                                       |     | | | | | | |S|W| |
 11654                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11655                              <1> 	;
 11656                              <1>         ;       P      - PRESENT
 11657                              <1>         ;       R/W    - READ/WRITE
 11658                              <1>         ;       U/S    - USER/SUPERVISOR
 11659                              <1>         ;       D      - DIRTY
 11660                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11661                              <1> 	;
 11662                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
 11663                              <1> 	;
 11664                              <1> 	;
 11665                              <1> 	;; Invalid Page Table Entry
 11666                              <1> 	; 31                                                           1 0
 11667                              <1>       	; +-------------------------------------------------------------+-+
 11668                              <1>       	; |                                                             | |
 11669                              <1>       	; |                          AVAILABLE                          |0|
 11670                              <1>       	; |                                                             | |
 11671                              <1>       	; +-------------------------------------------------------------+-+
 11672                              <1> 	;
 11673                              <1> 
 11674 00003443 53                  <1> 	push	ebx
 11675 00003444 52                  <1> 	push	edx
 11676 00003445 51                  <1> 	push	ecx
 11677                              <1> 	;
 11678                              <1> 	; 21/09/2015 (debugging)
 11679 00003446 FF05[C1850000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
 11680 0000344C FF05[2C920000]      <1> 	inc	dword [PF_Count] ; total page fault count	
 11681                              <1> 	; 28/06/2015
 11682                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
 11683 00003452 8A15[24920000]      <1> 	mov	dl, [error_code]
 11684                              <1> 	;
 11685 00003458 F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
 11686                              <1> 			; sign
 11687 0000345B 7422                <1> 	jz	short pfh_alloc_np
 11688                              <1> 	; 
 11689                              <1> 	; If it is not a 'write on read only page' type page fault
 11690                              <1> 	; major page fault error with minor reason must be returned without 
 11691                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
 11692                              <1> 	; after return here!
 11693                              <1> 	; Page fault will be remedied, by copying page contents
 11694                              <1> 	; to newly allocated page with write permission;
 11695                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
 11696                              <1> 	; used for working with minimum possible memory usage. 
 11697                              <1> 	; sys_fork will duplicate page directory and tables of parent  
 11698                              <1> 	; process with 'read only' flag. If the child process attempts to
 11699                              <1> 	; write on these read only pages, page fault will be directed here
 11700                              <1> 	; for allocating a new page with same data/content. 
 11701                              <1> 	;
 11702                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
 11703                              <1> 	; will not force to separate CODE and DATA space 
 11704                              <1> 	; in a process/program... 
 11705                              <1> 	; CODE segment/section may contain DATA!
 11706                              <1> 	; It is flat, smoth and simplest programming method already as in 
 11707                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
 11708                              <1> 	;	
 11709 0000345D F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
 11710                              <1> 			; sign
 11711 00003460 0F84AB000000        <1>         jz      pfh_p_err
 11712                              <1> 	; 31/08/2015
 11713 00003466 F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
 11714                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
 11715 00003469 0F84A2000000        <1>         jz	pfh_pv_err
 11716                              <1> 	;
 11717                              <1> 	; make a new page and copy the parent's page content
 11718                              <1> 	; as the child's new page content
 11719                              <1> 	;
 11720 0000346F 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
 11721                              <1> 			 ; which has caused to page fault
 11722 00003472 E8A2000000          <1> 	call 	copy_page
 11723 00003477 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
 11724                              <1> 	;
 11725 0000347D EB7D                <1>         jmp     pfh_cpp_ok
 11726                              <1> 	;
 11727                              <1> pfh_alloc_np:
 11728 0000347F E8EDFCFFFF          <1> 	call	allocate_page	; (allocate a new page)
 11729 00003484 0F8280000000        <1>         jc      pfh_im_err	; 'insufficient memory' error
 11730                              <1> pfh_chk_cpl:
 11731                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11732                              <1> 		; (Lower 12 bits are ZERO, because 
 11733                              <1> 		;	the address is on a page boundary)
 11734 0000348A 80E204              <1> 	and	dl, 4	; CPL = 3 ?
 11735 0000348D 7505                <1> 	jnz	short pfh_um
 11736                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
 11737 0000348F 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
 11738                              <1> 			 ; of the current/active page directory
 11739                              <1> 			 ; (Always kernel/system mode page directory, here!)
 11740                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
 11741 00003492 EB06                <1> 	jmp	short pfh_get_pde
 11742                              <1> 	;
 11743                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
 11744 00003494 8B1D[B1850000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
 11745                              <1> 			; Physical address of the USER's page directory
 11746                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
 11747                              <1> pfh_get_pde:
 11748 0000349A 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
 11749 0000349D 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
 11750                              <1> 			 ; which has been caused to page fault
 11751                              <1> 			 ;
 11752 000034A0 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
 11753 000034A3 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
 11754                              <1> 	;
 11755 000034A6 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
 11756 000034A8 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
 11757 000034AA F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
 11758 000034AD 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
 11759                              <1> 			  	  ; set/validate page directory entry
 11760 000034AF 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 11761 000034B4 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
 11762 000034B6 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
 11763 000034B8 EB16                <1> 	jmp	short pfh_get_pte
 11764                              <1> pfh_set_pde:
 11765                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
 11766                              <1> 	;;	 (So, we know this PDE is empty or invalid)
 11767                              <1> 	;
 11768 000034BA 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
 11769 000034BC 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
 11770 000034BE 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
 11771 000034C0 89C3                <1> 	mov	ebx, eax
 11772 000034C2 E8AAFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
 11773 000034C7 7241                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
 11774                              <1> pfh_spde_1:
 11775                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11776 000034C9 89C1                <1> 	mov	ecx, eax
 11777 000034CB E81BFDFFFF          <1> 	call	clear_page ; Clear page content
 11778                              <1> pfh_get_pte:
 11779 000034D0 0F20D0              <1> 	mov	eax, cr2 ; virtual address
 11780                              <1> 			 ; which has been caused to page fault
 11781 000034D3 89C7                <1> 	mov	edi, eax ; 20/07/2015
 11782 000034D5 C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
 11783                              <1> 			 ; higher 20 bits of the page fault address 
 11784 000034D8 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
 11785 000034DD C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
 11786 000034E0 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
 11787 000034E2 8B03                <1> 	mov	eax, [ebx] ; get previous value of pte
 11788                              <1> 		; bit 0 of EAX is always 0 (otherwise we would not be here)
 11789 000034E4 21C0                <1> 	and	eax, eax
 11790 000034E6 7410                <1> 	jz	short pfh_gpte_1
 11791                              <1> 	; 20/07/2015
 11792 000034E8 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
 11793 000034EA 55                  <1> 	push	ebp ; 20/07/2015
 11794 000034EB 0F20D5              <1> 	mov	ebp, cr2
 11795                              <1> 		; ECX = physical address of the page table entry
 11796                              <1> 		; EBX = Memory page address (physical!)
 11797                              <1> 		; EAX = Swap disk (offset) address
 11798                              <1> 		; EBP = virtual address (page fault address)
 11799 000034EE E8B7000000          <1> 	call	swap_in
 11800 000034F3 5D                  <1> 	pop	ebp
 11801 000034F4 7210                <1> 	jc      short pfh_err_retn
 11802 000034F6 87CB                <1> 	xchg	ecx, ebx
 11803                              <1> 		; EBX = physical address of the page table entry
 11804                              <1> 		; ECX = new page
 11805                              <1> pfh_gpte_1:
 11806 000034F8 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
 11807 000034FA 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
 11808                              <1> pfh_cpp_ok:
 11809                              <1> 	; 20/07/2015
 11810 000034FC 0F20D3              <1> 	mov	ebx, cr2
 11811 000034FF E82A020000          <1> 	call 	add_to_swap_queue
 11812                              <1> 	;
 11813                              <1> 	; The new PTE (which contains the new page) will be added to 
 11814                              <1> 	; the swap queue, here. 
 11815                              <1> 	; (Later, if memory will become insufficient, 
 11816                              <1> 	; one page will be swapped out which is at the head of 
 11817                              <1> 	; the swap queue by using FIFO and access check methods.)
 11818                              <1> 	;
 11819 00003504 31C0                <1> 	xor	eax, eax  ; 0
 11820                              <1> 	;
 11821                              <1> pfh_err_retn:
 11822 00003506 59                  <1> 	pop	ecx
 11823 00003507 5A                  <1> 	pop	edx
 11824 00003508 5B                  <1> 	pop	ebx
 11825 00003509 C3                  <1> 	retn 
 11826                              <1> 	
 11827                              <1> pfh_im_err:
 11828 0000350A B8E1000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
 11829                              <1> 			; Major (Primary) Error: Page Fault
 11830                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
 11831 0000350F EBF5                <1> 	jmp	short pfh_err_retn
 11832                              <1> 
 11833                              <1> 
 11834                              <1> pfh_p_err: ; 09/03/2015
 11835                              <1> pfh_pv_err:
 11836                              <1> 	; Page fault was caused by a protection-violation
 11837 00003511 B8E3000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
 11838                              <1> 			; Major (Primary) Error: Page Fault
 11839                              <1> 			; Minor (Secondary) Error: Protection violation !
 11840 00003516 F9                  <1> 	stc
 11841 00003517 EBED                <1> 	jmp	short pfh_err_retn
 11842                              <1> 
 11843                              <1> copy_page:
 11844                              <1> 	; 22/09/2015
 11845                              <1> 	; 21/09/2015
 11846                              <1> 	; 19/09/2015
 11847                              <1> 	; 07/09/2015
 11848                              <1> 	; 31/08/2015
 11849                              <1> 	; 20/07/2015
 11850                              <1> 	; 05/05/2015
 11851                              <1> 	; 03/05/2015
 11852                              <1> 	; 18/04/2015
 11853                              <1> 	; 12/04/2015
 11854                              <1> 	; 30/10/2014
 11855                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
 11856                              <1> 	;
 11857                              <1> 	; INPUT -> 
 11858                              <1> 	;	EBX = Virtual (linear) address of source page
 11859                              <1> 	;	     (Page fault address)
 11860                              <1> 	; OUTPUT ->
 11861                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11862                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11863                              <1> 	;	EAX = 0 (CF = 1) 
 11864                              <1> 	;		if there is not a free page to be allocated
 11865                              <1> 	;	(page content of the source page will be copied
 11866                              <1> 	;	onto the target/new page) 	
 11867                              <1> 	;
 11868                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
 11869                              <1> 	;	
 11870 00003519 56                  <1> 	push	esi
 11871 0000351A 57                  <1> 	push	edi
 11872                              <1> 	;push	ebx
 11873                              <1> 	;push	ecx
 11874 0000351B 31F6                <1> 	xor 	esi, esi
 11875 0000351D C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
 11876 00003520 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
 11877 00003522 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
 11878 00003525 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
 11879 00003528 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
 11880 0000352A 031D[B1850000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
 11881 00003530 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
 11882 00003532 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
 11883 00003536 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
 11884 00003538 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11885 0000353E 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
 11886 00003542 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
 11887                              <1> 	; 07/09/2015
 11888 00003544 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
 11889                              <1> 				     ; read only page as a child process?)	
 11890 00003549 7509                <1> 	jnz	short cpp_0 ; yes
 11891 0000354B 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
 11892 0000354D 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
 11893 00003552 EB32                <1> 	jmp	short cpp_1
 11894                              <1> cpp_0:
 11895 00003554 89FE                <1> 	mov	esi, edi
 11896 00003556 0335[B5850000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
 11897 0000355C 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
 11898 0000355E 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11899 00003562 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
 11900 00003564 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11901 0000356A 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
 11902 0000356E 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
 11903 00003570 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
 11904                              <1> 	; 21/09/2015
 11905 00003572 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
 11906 00003574 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
 11907                              <1> 	;
 11908 00003578 F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
 11909 0000357B 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
 11910                              <1> 	;
 11911 0000357D 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
 11912 00003582 39C8                <1> 	cmp	eax, ecx   ; Same page?	
 11913 00003584 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
 11914                              <1> 			    ; Convert child's page to writable page
 11915                              <1> cpp_1:
 11916 00003586 E8E6FBFFFF          <1> 	call	allocate_page
 11917 0000358B 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
 11918 0000358D 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
 11919 0000358F 7405                <1> 	jz	short cpp_2
 11920                              <1> 		; Convert read only page to writable page 
 11921                              <1> 		;(for the parent of the current process)
 11922                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
 11923                              <1> 	; 22/09/2015
 11924 00003591 890E                <1> 	mov	[esi], ecx
 11925 00003593 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
 11926                              <1> 				 ; 1+2+4 = 7
 11927                              <1> cpp_2:
 11928 00003596 89C7                <1> 	mov	edi, eax ; new page address of the child process
 11929                              <1> 	; 07/09/2015
 11930 00003598 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
 11931 0000359A B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 11932 0000359F F3A5                <1> 	rep	movsd ; 31/08/2015
 11933                              <1> cpp_3:		
 11934 000035A1 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
 11935 000035A3 8903                <1> 	mov	[ebx], eax ; Update PTE
 11936 000035A5 28C0                <1> 	sub	al, al ; clear attributes
 11937                              <1> cpp_4:
 11938                              <1> 	;pop	ecx
 11939                              <1> 	;pop	ebx
 11940 000035A7 5F                  <1> 	pop	edi
 11941 000035A8 5E                  <1> 	pop	esi
 11942 000035A9 C3                  <1> 	retn
 11943                              <1> 
 11944                              <1> ;; 28/04/2015
 11945                              <1> ;; 24/10/2014
 11946                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
 11947                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
 11948                              <1> ;;
 11949                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
 11950                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
 11951                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
 11952                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
 11953                              <1> ;;
 11954                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
 11955                              <1> ;;
 11956                              <1> ;; Method:
 11957                              <1> ;;	Swap page queue is a list of allocated pages with physical
 11958                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
 11959                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
 11960                              <1> ;;	When a new page is being allocated, swap queue is updated
 11961                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
 11962                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
 11963                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
 11964                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
 11965                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
 11966                              <1> ;;	offset value becomes it's previous offset value - 4.
 11967                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
 11968                              <1> ;;	the queue/list is not shifted.
 11969                              <1> ;;	After the queue/list shift, newly allocated page is added
 11970                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
 11971                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
 11972                              <1> ;;	will not be added to the tail of swap page queue.  		 
 11973                              <1> ;;	
 11974                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
 11975                              <1> ;;	the first non-accessed, writable page in the list, 
 11976                              <1> ;;	from the head to the tail. The list is shifted to left 
 11977                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
 11978                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
 11979                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
 11980                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
 11981                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
 11982                              <1> ;;	procedure will be failed)...
 11983                              <1> ;;
 11984                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
 11985                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
 11986                              <1> ;;	(PTE) will be added to the tail of the queue after
 11987                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
 11988                              <1> ;;	the queue will be rotated and the PTE in the head will be
 11989                              <1> ;;	added to the tail after resetting 'accessed' bit. 
 11990                              <1> ;;
 11991                              <1> ;;
 11992                              <1> ;;	
 11993                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
 11994                              <1> ;;
 11995                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
 11996                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
 11997                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
 11998                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
 11999                              <1> ;;
 12000                              <1> ;; [swpd_next] = the first free block address in swapped page records
 12001                              <1> ;;    		 for next free block search by 'swap_out' procedure.
 12002                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
 12003                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
 12004                              <1> ;; 		 (entire swap space must be accessed by using
 12005                              <1> ;;		 31 bit offset address) 
 12006                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
 12007                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
 12008                              <1> ;;		  0 for file, or beginning sector of the swap partition
 12009                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
 12010                              <1> ;;
 12011                              <1> ;; 					
 12012                              <1> ;; Method:
 12013                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
 12014                              <1> ;;	procedure swaps out a page from memory to the swap disk 
 12015                              <1> ;;	(partition) or swap file to get a new free page at the memory.
 12016                              <1> ;;	Swapping out is performed by using swap page queue.
 12017                              <1> ;;
 12018                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
 12019                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
 12020                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
 12021                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
 12022                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
 12023                              <1> ;;	Absolute physical (logical) address of the swapped page is 
 12024                              <1> ;;	calculated by adding offset value to the swap partition's 
 12025                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
 12026                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
 12027                              <1> ;;	and offset value is equal to absolute (physical or logical)
 12028                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
 12029                              <1> ;;	is in a partitioned virtual hard disk.) 
 12030                              <1> ;;
 12031                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
 12032                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
 12033                              <1> ;;
 12034                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
 12035                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
 12036                              <1> ;;
 12037                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
 12038                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
 12039                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
 12040                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
 12041                              <1> ;;	it means relevant (respective) block is in use, and, 
 12042                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
 12043                              <1> ;;      swap disk/file block is free.
 12044                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
 12045                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
 12046                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
 12047                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
 12048                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
 12049                              <1> ;;	------------------------------------------------------------
 12050                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
 12051                              <1> ;;	------------------------------------------------------------
 12052                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
 12053                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
 12054                              <1> ;;
 12055                              <1> ;;	..............................................................
 12056                              <1> ;;
 12057                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
 12058                              <1> ;;	then it searches Swap Allocation Table if free count is not
 12059                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
 12060                              <1> ;;	position with value of 1 on the table is converted to swap
 12061                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
 12062                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
 12063                              <1> ;;	number of physical swap disk or virtual swap disk)
 12064                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
 12065                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
 12066                              <1> ;;	(memory page). That will be a direct disk write procedure.
 12067                              <1> ;;	(for preventing late memory allocation, significant waiting). 
 12068                              <1> ;;	If disk write procedure returns with error or free count of 
 12069                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
 12070                              <1> ;;	'insufficient memory error' (cf=1). 
 12071                              <1> ;;
 12072                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
 12073                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
 12074                              <1> ;;	in other words, 'swap_out' will not check the table for other
 12075                              <1> ;;	free blocks after a disk write error. It will return to 
 12076                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
 12077                              <1> ;;
 12078                              <1> ;;	After writing the page on to swap disk/file address/sector,
 12079                              <1> ;;	'swap_out' procesure returns with that swap (offset) sector
 12080                              <1> ;;	address (cf=0). 
 12081                              <1> ;;
 12082                              <1> ;;	..............................................................
 12083                              <1> ;;
 12084                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
 12085                              <1> ;;	file sectors at specified memory page. Then page allocation
 12086                              <1> ;;	procedure updates relevant page table entry with 'present' 
 12087                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
 12088                              <1> ;;	to do, except to terminate the process which is the owner of
 12089                              <1> ;;	the swapped page.
 12090                              <1> ;;
 12091                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
 12092                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
 12093                              <1> ;;	updates [swpd_first] pointer if it is required.
 12094                              <1> ;;
 12095                              <1> ;;	..............................................................	 
 12096                              <1> ;;
 12097                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
 12098                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
 12099                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
 12100                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
 12101                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
 12102                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
 12103                              <1> ;;
 12104                              <1> 
 12105                              <1> swap_in:
 12106                              <1> 	; 31/08/2015
 12107                              <1> 	; 20/07/2015
 12108                              <1> 	; 28/04/2015
 12109                              <1> 	; 18/04/2015
 12110                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12111                              <1> 	;
 12112                              <1> 	; INPUT -> 
 12113                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
 12114                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
 12115                              <1> 	;	EAX = Offset Address for the swapped page on the
 12116                              <1> 	;	      swap disk or in the swap file.
 12117                              <1> 	;
 12118                              <1> 	; OUTPUT ->
 12119                              <1> 	;	EAX = 0 if loading at memory has been successful
 12120                              <1> 	;
 12121                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
 12122                              <1> 	;		  or sector not present or drive not ready
 12123                              <1> 	;	     EAX = Error code
 12124                              <1> 	;	     [u.error] = EAX 
 12125                              <1> 	;		       = The last error code for the process
 12126                              <1> 	;		         (will be reset after returning to user)	  
 12127                              <1> 	;
 12128                              <1> 	; Modified Registers -> EAX
 12129                              <1> 	;
 12130                              <1> 
 12131 000035AA 833D[0F920000]00    <1>         cmp     dword [swp_drv], 0
 12132 000035B1 7648                <1> 	jna	short swpin_dnp_err
 12133                              <1> 
 12134 000035B3 3B05[13920000]      <1> 	cmp	eax, [swpd_size]
 12135 000035B9 734C                <1> 	jnb	short swpin_snp_err
 12136                              <1> 
 12137 000035BB 56                  <1> 	push	esi
 12138 000035BC 53                  <1> 	push	ebx
 12139 000035BD 51                  <1> 	push	ecx
 12140 000035BE 8B35[0F920000]      <1> 	mov	esi, [swp_drv]	
 12141 000035C4 B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 12142                              <1> 		; Note: Even if corresponding physical disk's sector 
 12143                              <1> 		; size different than 512 bytes, logical disk sector
 12144                              <1> 		; size is 512 bytes and disk reading procedure
 12145                              <1> 		; will be performed for reading 4096 bytes
 12146                              <1> 		; (2*2048, 8*512). 
 12147                              <1> 	; ESI = Logical disk description table address
 12148                              <1> 	; EBX = Memory page (buffer) address (physical!)
 12149                              <1> 	; EAX = Sector adress (offset address, logical sector number)
 12150                              <1> 	; ECX = Sector count ; 8 sectors
 12151 000035C9 50                  <1> 	push	eax
 12152 000035CA E833020000          <1> 	call	logical_disk_read
 12153 000035CF 58                  <1> 	pop	eax
 12154 000035D0 730C                <1> 	jnc	short swpin_read_ok
 12155                              <1> 	;
 12156 000035D2 B804000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
 12157 000035D7 A3[AD850000]        <1> 	mov	[u.error], eax
 12158 000035DC EB19                <1> 	jmp	short swpin_retn
 12159                              <1> 	;
 12160                              <1> swpin_read_ok:
 12161                              <1> 	; EAX = Offset address (logical sector number)
 12162 000035DE E891010000          <1> 	call	unlink_swap_block  ; Deallocate swap block	
 12163                              <1> 	;
 12164                              <1> 	; EBX = Memory page (buffer) address (physical!)
 12165                              <1> 	; 20/07/2015
 12166 000035E3 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
 12167 000035E5 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 12168 000035EA 8A1D[A7850000]      <1> 	mov	bl, [u.uno] ; current process number
 12169                              <1> 	; EBX = Virtual address & process number combination
 12170 000035F0 E89E000000          <1> 	call	swap_queue_shift
 12171 000035F5 29C0                <1> 	sub	eax, eax  ; 0 ; Error Code = 0  (no error)
 12172                              <1> 	;
 12173                              <1> swpin_retn:
 12174 000035F7 59                  <1> 	pop	ecx
 12175 000035F8 5B                  <1> 	pop	ebx
 12176 000035F9 5E                  <1> 	pop	esi
 12177 000035FA C3                  <1> 	retn
 12178                              <1> 
 12179                              <1> swpin_dnp_err:
 12180 000035FB B805000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
 12181                              <1> swpin_err_retn:
 12182 00003600 A3[AD850000]        <1> 	mov	[u.error], eax
 12183 00003605 F9                  <1> 	stc
 12184 00003606 C3                  <1> 	retn
 12185                              <1> 
 12186                              <1> swpin_snp_err:
 12187 00003607 B806000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
 12188 0000360C EBF2                <1> 	jmp	short swpin_err_retn
 12189                              <1> 
 12190                              <1> swap_out:
 12191                              <1> 	; 31/08/2015
 12192                              <1> 	; 05/05/2015
 12193                              <1> 	; 30/04/2015
 12194                              <1> 	; 28/04/2015
 12195                              <1> 	; 18/04/2015
 12196                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12197                              <1> 	;
 12198                              <1> 	; INPUT -> 
 12199                              <1> 	;	none
 12200                              <1> 	;
 12201                              <1> 	; OUTPUT ->
 12202                              <1> 	;	EAX = Physical page address (which is swapped out
 12203                              <1> 	;	      for allocating a new page)
 12204                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
 12205                              <1> 	;		  or sector not present or drive not ready
 12206                              <1> 	;	     EAX = Error code
 12207                              <1> 	;	     [u.error] = EAX 
 12208                              <1> 	;		       = The last error code for the process
 12209                              <1> 	;		         (will be reset after returning to user)	  
 12210                              <1> 	;
 12211                              <1> 	; Modified Registers -> non (except EAX)
 12212                              <1> 	;
 12213 0000360E 66833D[0D920000]01  <1> 	cmp 	word [swpq_count], 1
 12214 00003616 7274                <1>         jc      short swpout_im_err ; 'insufficient memory'
 12215                              <1> 
 12216                              <1>         ;cmp     dword [swp_drv], 1
 12217                              <1> 	;jc	short swpout_dnp_err ; 'swap disk/file not present'
 12218                              <1> 
 12219 00003618 833D[17920000]01    <1>         cmp     dword [swpd_free], 1
 12220 0000361F 7258                <1> 	jc	short swpout_nfspc_err ; 'no free space on swap disk'
 12221                              <1> 
 12222 00003621 53                  <1> 	push	ebx
 12223                              <1> swpout_1:
 12224 00003622 31DB                <1> 	xor	ebx, ebx
 12225 00003624 E86A000000          <1> 	call	swap_queue_shift
 12226 00003629 21C0                <1> 	and	eax, eax	; entry count (before shifting)
 12227 0000362B 7457                <1> 	jz	short swpout_npts_err  ; There is no any PTE in
 12228                              <1> 				       ; the swap queue
 12229 0000362D BB00E00800          <1> 	mov	ebx, swap_queue	       ; Addres of the head of 
 12230                              <1> 				       ; the swap queue		
 12231 00003632 8B03                <1> 	mov	eax, [ebx]	       ; The PTE in the queue head	
 12232                              <1> 
 12233                              <1> 	;test	al, PTE_A_PRESENT      ; bit 0 = 1
 12234                              <1> 	;jz	short swpout_1	       ; non-present page already
 12235                              <1> 				       ; must not be in the queue
 12236                              <1> 
 12237                              <1> 	;test	al, PTE_A_WRITE	       ; bit 1 = 0
 12238                              <1> 	;jz	short swpout_1 	       ; read only page (must not be
 12239                              <1> 				       ; swapped out)
 12240                              <1> 	
 12241 00003634 A820                <1> 	test	al, PTE_A_ACCESS       ; bit 5 = 1 (Accessed)
 12242 00003636 75EA                <1> 	jnz	short swpout_1 	       ; accessed page (must not be
 12243                              <1> 				       ; swapped out, at this stage)
 12244                              <1> 	;
 12245 00003638 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 12246                              <1> 	;
 12247 0000363C 52                  <1> 	push	edx
 12248 0000363D 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
 12249 0000363F 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
 12250                              <1> 	;
 12251 00003641 E861010000          <1> 	call	link_swap_block
 12252 00003646 7304                <1> 	jnc	short swpout_2	       ; It may not be needed here	
 12253 00003648 5A                  <1> 	pop	edx		       ; because [swpd_free] value	
 12254 00003649 5B                  <1> 	pop	ebx
 12255 0000364A EB2D                <1> 	jmp	short swpout_nfspc_err ; was checked at the beginging. 	
 12256                              <1> swpout_2:	
 12257 0000364C 56                  <1> 	push	esi
 12258 0000364D 51                  <1> 	push	ecx
 12259 0000364E 50                  <1> 	push	eax ; sector address
 12260 0000364F 8B35[0F920000]      <1> 	mov	esi, [swp_drv]	
 12261 00003655 B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 12262                              <1> 		; Note: Even if corresponding physical disk's sector 
 12263                              <1> 		; size different than 512 bytes, logical disk sector
 12264                              <1> 		; size is 512 bytes and disk writing procedure
 12265                              <1> 		; will be performed for writing 4096 bytes
 12266                              <1> 		; (2*2048, 8*512). 
 12267                              <1> 	; ESI = Logical disk description table address
 12268                              <1> 	; EBX = Buffer address
 12269                              <1> 	; EAX = Sector adress (offset address, logical sector number)
 12270                              <1> 	; ECX = Sector count ; 8 sectors
 12271 0000365A E8A4010000          <1> 	call	logical_disk_write
 12272 0000365F 59                  <1> 	pop	ecx ; sector address	
 12273 00003660 730C                <1> 	jnc	short swpout_write_ok
 12274                              <1> 	;
 12275                              <1> 	;; call	unlink_swap_block ; this block must be left as 'in use'
 12276                              <1> swpout_dw_err:
 12277 00003662 B808000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
 12278 00003667 A3[AD850000]        <1> 	mov	[u.error], eax
 12279 0000366C EB06                <1> 	jmp	short swpout_retn
 12280                              <1> 	;
 12281                              <1> swpout_write_ok:
 12282                              <1> 	; EBX = Buffer (page) address
 12283                              <1> 	; EDX = Page Table entry address
 12284                              <1> 	; ECX = Swap disk sector (file block) address (31 bit)
 12285 0000366E D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
 12286 00003670 890A                <1> 	mov 	[edx], ecx 
 12287                              <1> 		; bit 0 = 0 (swapped page)
 12288 00003672 89D8                <1> 	mov	eax, ebx
 12289                              <1> swpout_retn:
 12290 00003674 59                  <1> 	pop	ecx
 12291 00003675 5E                  <1> 	pop	esi
 12292 00003676 5A                  <1> 	pop	edx
 12293 00003677 5B                  <1> 	pop	ebx
 12294 00003678 C3                  <1> 	retn
 12295                              <1> 
 12296                              <1> ; Note: Swap_queue will not be updated in 'swap_out' procedure
 12297                              <1> ;	after the page is swapped out. (the PTE at the queue head
 12298                              <1> ;	-with 'non-present' attribute- will be dropped from the
 12299                              <1> ;	the queue in next 'swap_out' or in next 'swap_queue_shift'.
 12300                              <1> 	
 12301                              <1> ;swpout_dnp_err:
 12302                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
 12303                              <1> ;	jmp	short swpout_err_retn
 12304                              <1> swpout_nfspc_err:
 12305 00003679 B807000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
 12306                              <1> swpout_err_retn:
 12307 0000367E A3[AD850000]        <1> 	mov	[u.error], eax
 12308                              <1> 	;stc
 12309 00003683 C3                  <1> 	retn
 12310                              <1> swpout_npts_err:
 12311 00003684 B809000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
 12312 00003689 5B                  <1> 	pop	ebx
 12313 0000368A EBF2                <1> 	jmp	short swpout_err_retn
 12314                              <1> swpout_im_err:
 12315 0000368C B801000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
 12316 00003691 EBEB                <1> 	jmp	short swpout_err_retn
 12317                              <1> 
 12318                              <1> swap_queue_shift:
 12319                              <1> 	; 20/07/2015
 12320                              <1> 	; 28/04/2015
 12321                              <1> 	; 18/04/2015
 12322                              <1> 	; 23/10/2014 (Retro UNIX 386 v1 - beginning)
 12323                              <1> 	;
 12324                              <1> 	; INPUT ->
 12325                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
 12326                              <1> 	;	      and process number combination (bit 0 to 11)
 12327                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
 12328                              <1> 	; OUTPUT ->
 12329                              <1> 	;	If EBX input > 0 
 12330                              <1> 	;	    the queue will be shifted 4 bytes (dword),
 12331                              <1> 	; 	    from the tail to the head, up to entry offset
 12332                              <1> 	; 	    which points to EBX input value or nothing
 12333                              <1> 	;	    to do if EBX value is not found in the queue.
 12334                              <1> 	;	    (The entry -with EBX value- will be removed
 12335                              <1> 	;	     from the queue if it is found.)	
 12336                              <1> 	;	If EBX input = 0
 12337                              <1> 	;	    the queue will be shifted 4 bytes (dword),
 12338                              <1> 	; 	    from the tail to the head, if the PTE address
 12339                              <1> 	;	    in head of the queue is marked as "accessed"
 12340                              <1> 	;	    or it is marked as "non present".
 12341                              <1> 	;	    (If "accessed" flag of the PTE -in the head-
 12342                              <1> 	; 	    is set -to 1-, it will be reset -to 0- and then, 
 12343                              <1> 	;	    the queue will be rotated -without dropping
 12344                              <1> 	; 	    the PTE from the queue-, for 4 bytes on head
 12345                              <1> 	; 	    to tail direction. The PTE in the head will be
 12346                              <1> 	;	    moved in the tail, other PTEs will be shifted on
 12347                              <1> 	;	    head direction.)	
 12348                              <1> 	;
 12349                              <1> 	;	EAX = [swpq_count] (before the shifting)
 12350                              <1> 	;	    (EAX = 0 -> next 'swap_out' stage 
 12351                              <1> 	; 	     is not applicable)	
 12352                              <1> 	;
 12353                              <1> 	; Modified Registers -> EAX
 12354                              <1> 	;
 12355 00003693 0FB705[0D920000]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
 12356 0000369A 6621C0              <1> 	and	ax, ax
 12357 0000369D 7433                <1> 	jz	short swpqs_retn
 12358 0000369F 57                  <1> 	push	edi
 12359 000036A0 56                  <1> 	push	esi
 12360 000036A1 53                  <1> 	push	ebx
 12361 000036A2 51                  <1> 	push	ecx
 12362 000036A3 50                  <1> 	push	eax
 12363 000036A4 BE00E00800          <1> 	mov	esi, swap_queue
 12364 000036A9 89C1                <1> 	mov	ecx, eax
 12365 000036AB 09DB                <1> 	or	ebx, ebx
 12366 000036AD 7424                <1> 	jz	short swpqs_7
 12367                              <1> swpqs_1:
 12368 000036AF AD                  <1> 	lodsd
 12369 000036B0 39D8                <1> 	cmp	eax, ebx
 12370 000036B2 7404                <1> 	je	short swpqs_2
 12371 000036B4 E2F9                <1> 	loop	swpqs_1
 12372 000036B6 EB15                <1> 	jmp	short swpqs_6
 12373                              <1> swpqs_2:
 12374 000036B8 89F7                <1> 	mov	edi, esi
 12375 000036BA 83EF04              <1> 	sub 	edi, 4
 12376                              <1> swpqs_3:
 12377 000036BD 66FF0D[0D920000]    <1> 	dec	word [swpq_count]
 12378 000036C4 7403                <1> 	jz	short swpqs_5
 12379                              <1> swpqs_4:
 12380 000036C6 49                  <1> 	dec 	ecx
 12381 000036C7 F3A5                <1> 	rep	movsd	; shift up (to the head)
 12382                              <1> swpqs_5:
 12383 000036C9 31C0                <1> 	xor	eax, eax
 12384 000036CB 8907                <1> 	mov	[edi], eax
 12385                              <1> swpqs_6:
 12386 000036CD 58                  <1> 	pop	eax
 12387 000036CE 59                  <1> 	pop	ecx
 12388 000036CF 5B                  <1> 	pop	ebx
 12389 000036D0 5E                  <1> 	pop	esi
 12390 000036D1 5F                  <1> 	pop	edi
 12391                              <1> swpqs_retn:
 12392 000036D2 C3                  <1> 	retn		
 12393                              <1> swpqs_7:
 12394 000036D3 89F7                <1> 	mov	edi, esi ; head
 12395 000036D5 AD                  <1> 	lodsd
 12396                              <1> 	; 20/07/2015
 12397 000036D6 89C3                <1> 	mov	ebx, eax
 12398 000036D8 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
 12399                              <1> 		      ; ebx = virtual address (at page boundary)	
 12400 000036DE 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
 12401                              <1> 		      ; ax = process number (1 to 4095)
 12402 000036E3 3A05[A7850000]      <1> 	cmp	al, [u.uno]
 12403                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
 12404 000036E9 7507                <1> 	jne	short swpqs_8
 12405 000036EB A1[B1850000]        <1> 	mov	eax, [u.pgdir]
 12406 000036F0 EB16                <1> 	jmp	short swpqs_9
 12407                              <1> swpqs_8:
 12408                              <1> 	;shl	ax, 2
 12409 000036F2 C0E002              <1> 	shl	al, 2
 12410 000036F5 8B80[E8820000]      <1> 	mov 	eax, [eax+p.upage-4]
 12411 000036FB 09C0                <1> 	or	eax, eax
 12412 000036FD 74BE                <1> 	jz	short swpqs_3 ; invalid upage
 12413 000036FF 83C061              <1> 	add	eax, u.pgdir - user
 12414                              <1> 			 ; u.pgdir value for the process
 12415                              <1> 			 ; is in [eax]
 12416 00003702 8B00                <1> 	mov	eax, [eax]
 12417 00003704 21C0                <1> 	and	eax, eax
 12418 00003706 74B5                <1> 	jz	short swpqs_3 ; invalid page directory
 12419                              <1> swpqs_9:
 12420 00003708 52                  <1> 	push	edx
 12421                              <1> 	; eax = page directory
 12422                              <1> 	; ebx = virtual address
 12423 00003709 E87EFBFFFF          <1> 	call	get_pte
 12424 0000370E 89D3                <1> 	mov	ebx, edx ; PTE address
 12425 00003710 5A                  <1> 	pop	edx
 12426 00003711 72AA                <1> 	jc	short swpqs_3 ; empty PDE
 12427                              <1> 	; EAX = PTE value
 12428 00003713 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
 12429 00003715 74A6                <1> 	jz	short swpqs_3 ; Drop non-present page
 12430                              <1> 			      ; from the queue (head)
 12431 00003717 A802                <1> 	test	al, PTE_A_WRITE	  ; bit 1 = 0
 12432 00003719 74A2                <1> 	jz	short swpqs_3 ; Drop read only page
 12433                              <1> 			      ; from the queue (head) 	
 12434                              <1> 	;test	al, PTE_A_ACCESS  ; bit 5 = 1 (Accessed)
 12435                              <1> 	;jz	short swpqs_6 ; present
 12436                              <1> 			      ; non-accessed page
 12437 0000371B 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
 12438 0000371F 73AC                <1> 	jnc	short swpqs_6  ; non-accessed page
 12439 00003721 8903                <1> 	mov	[ebx], eax     ; save changed attribute
 12440                              <1> 	;
 12441                              <1> 	; Rotation (head -> tail)
 12442 00003723 49                  <1> 	dec	ecx     ; entry count -> last entry number		
 12443 00003724 74A7                <1> 	jz	short swpqs_6
 12444                              <1> 		; esi = head + 4
 12445                              <1> 		; edi = head
 12446 00003726 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
 12447 00003728 F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 12448 0000372A 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1] 		
 12449 0000372C EB9F                <1> 	jmp	short swpqs_6
 12450                              <1> 
 12451                              <1> add_to_swap_queue:
 12452                              <1> ; temporary - 16/09/2015
 12453 0000372E C3                  <1> retn
 12454                              <1> 	; 20/07/2015
 12455                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12456                              <1> 	;
 12457                              <1> 	; Adds new page to swap queue
 12458                              <1> 	; (page directories and page tables must not be added
 12459                              <1> 	; to swap queue)	
 12460                              <1> 	;
 12461                              <1> 	; INPUT ->
 12462                              <1> 	;	EBX = Virtual address (for current process, [u.uno])
 12463                              <1> 	;
 12464                              <1> 	; OUTPUT ->
 12465                              <1> 	;	EAX = [swpq_count]
 12466                              <1> 	;	      (after the PTE has been added)
 12467                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
 12468                              <1> 	;	      the pte could not be added.
 12469                              <1> 	;
 12470                              <1> 	; Modified Registers -> EAX
 12471                              <1> 	;
 12472 0000372F 53                  <1> 	push	ebx
 12473 00003730 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 12474 00003735 8A1D[A7850000]      <1> 	mov	bl, [u.uno] ; current process number
 12475 0000373B E853FFFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
 12476                              <1> 				 ; it is already in the queue
 12477                              <1> 		; Then add it to the tail of the queue
 12478 00003740 0FB705[0D920000]    <1> 	movzx	eax, word [swpq_count]
 12479 00003747 663D0004            <1> 	cmp	ax, 1024
 12480 0000374B 7205                <1> 	jb	short atsq_1
 12481 0000374D 6629C0              <1> 	sub	ax, ax
 12482 00003750 5B                  <1> 	pop	ebx
 12483 00003751 C3                  <1> 	retn
 12484                              <1> atsq_1:
 12485 00003752 56                  <1> 	push	esi
 12486 00003753 BE00E00800          <1> 	mov	esi, swap_queue
 12487 00003758 6621C0              <1> 	and	ax, ax
 12488 0000375B 740A                <1> 	jz	short atsq_2
 12489 0000375D 66C1E002            <1> 	shl	ax, 2	; convert to offset
 12490 00003761 01C6                <1> 	add	esi, eax
 12491 00003763 66C1E802            <1> 	shr	ax, 2
 12492                              <1> atsq_2:
 12493 00003767 6640                <1> 	inc	ax
 12494 00003769 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
 12495 0000376B 66A3[0D920000]      <1> 	mov	[swpq_count], ax
 12496 00003771 5E                  <1> 	pop	esi
 12497 00003772 5B                  <1> 	pop	ebx
 12498 00003773 C3                  <1> 	retn
 12499                              <1> 
 12500                              <1> unlink_swap_block:
 12501                              <1> 	; 15/09/2015
 12502                              <1> 	; 30/04/2015
 12503                              <1> 	; 18/04/2015
 12504                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12505                              <1> 	;
 12506                              <1> 	; INPUT -> 
 12507                              <1> 	;	EAX = swap disk/file offset address
 12508                              <1> 	;	      (bit 1 to bit 31)
 12509                              <1> 	; OUTPUT ->
 12510                              <1> 	;	[swpd_free] is increased
 12511                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
 12512                              <1> 	;
 12513                              <1> 	; Modified Registers -> EAX
 12514                              <1> 	;
 12515 00003774 53                  <1> 	push	ebx
 12516 00003775 52                  <1> 	push	edx
 12517                              <1> 	;
 12518 00003776 C1E804              <1> 	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
 12519                              <1> 				     ; 3 bits right
 12520                              <1> 				     ; to get swap block/page number
 12521 00003779 89C2                <1> 	mov	edx, eax
 12522                              <1> 	; 15/09/2015
 12523 0000377B C1EA03              <1> 	shr	edx, 3		     ; to get offset to S.A.T.
 12524                              <1> 				     ; (1 allocation bit = 1 page)
 12525                              <1> 				     ; (1 allocation bytes = 8 pages)
 12526 0000377E 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 12527                              <1> 				     ; (to get 32 bit position)			
 12528                              <1> 	;
 12529 00003781 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
 12530 00003786 01D3                <1> 	add	ebx, edx
 12531 00003788 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 12532                              <1> 				     ; (allocation bit position)	 
 12533 0000378B 3B05[1B920000]      <1> 	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
 12534                              <1> 				     ; than the address in 'swpd_next' ?
 12535                              <1> 				     ; (next/first free block value)		
 12536 00003791 7305                <1> 	jnb	short uswpbl_1	     ; no	
 12537 00003793 A3[1B920000]        <1> 	mov	[swpd_next], eax     ; yes	
 12538                              <1> uswpbl_1:
 12539 00003798 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate block
 12540                              <1> 				     ; set relevant bit to 1.
 12541                              <1> 				     ; set CF to the previous bit value	
 12542 0000379B F5                  <1> 	cmc			     ; complement carry flag	
 12543 0000379C 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
 12544                              <1> 				     ; if the block is already deallocated
 12545                              <1> 				     ; before.	
 12546 0000379E FF05[17920000]      <1>         inc     dword [swpd_free]
 12547                              <1> uswpbl_2:
 12548 000037A4 5A                  <1> 	pop	edx
 12549 000037A5 5B                  <1> 	pop	ebx
 12550 000037A6 C3                  <1> 	retn
 12551                              <1> 
 12552                              <1> link_swap_block:
 12553                              <1> 	; 01/07/2015
 12554                              <1> 	; 18/04/2015
 12555                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12556                              <1> 	;
 12557                              <1> 	; INPUT -> none
 12558                              <1> 	;
 12559                              <1> 	; OUTPUT ->
 12560                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
 12561                              <1> 	;	      in sectors (corresponding 
 12562                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
 12563                              <1> 	;
 12564                              <1> 	;	CF = 1 and EAX = 0 
 12565                              <1> 	; 		   if there is not a free block to be allocated	
 12566                              <1> 	;
 12567                              <1> 	; Modified Registers -> none (except EAX)
 12568                              <1> 	;
 12569                              <1> 
 12570                              <1> 	;mov	eax, [swpd_free]
 12571                              <1> 	;and	eax, eax
 12572                              <1> 	;jz	short out_of_swpspc
 12573                              <1> 	;
 12574 000037A7 53                  <1> 	push	ebx
 12575 000037A8 51                  <1> 	push	ecx
 12576                              <1> 	;
 12577 000037A9 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
 12578 000037AE 89D9                <1> 	mov	ecx, ebx
 12579 000037B0 031D[1B920000]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
 12580                              <1> 				 ; next_free_swap_block >> 5
 12581 000037B6 030D[1F920000]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
 12582                              <1> 				 ; (total_swap_blocks - 1) >> 5
 12583                              <1> lswbl_scan:
 12584 000037BC 39CB                <1> 	cmp	ebx, ecx
 12585 000037BE 770A                <1> 	ja	short lswbl_notfound
 12586                              <1> 	;
 12587 000037C0 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 12588                              <1> 			   ; Clears ZF if a bit is found set (1) and 
 12589                              <1> 			   ; loads the destination with an index to
 12590                              <1> 			   ; first set bit. (0 -> 31) 
 12591                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 12592                              <1> 	; 01/07/2015
 12593 000037C3 751C                <1> 	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
 12594                              <1> 			 ;
 12595                              <1> 			 ; NOTE:  a Swap Disk Allocation Table bit 
 12596                              <1> 			 ;	  with value of 1 means 
 12597                              <1> 			 ;	  the corresponding page is free 
 12598                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
 12599 000037C5 83C304              <1> 	add	ebx, 4
 12600                              <1> 			 ; We return back for searching next page block
 12601                              <1> 			 ; NOTE: [swpd_free] is not ZERO; so, 
 12602                              <1> 			 ;	 we always will find at least 1 free block here.
 12603 000037C8 EBF2                <1> 	jmp    	short lswbl_scan
 12604                              <1> 	;
 12605                              <1> lswbl_notfound:	
 12606 000037CA 81E900000D00        <1> 	sub	ecx, swap_alloc_table
 12607 000037D0 890D[1B920000]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
 12608                              <1> 				 ; (unlink_swap_block procedure will change it)
 12609 000037D6 31C0                <1> 	xor	eax, eax
 12610 000037D8 A3[17920000]        <1> 	mov	[swpd_free], eax
 12611 000037DD F9                  <1> 	stc
 12612                              <1> lswbl_ok:
 12613 000037DE 59                  <1> 	pop	ecx
 12614 000037DF 5B                  <1> 	pop	ebx
 12615 000037E0 C3                  <1> 	retn
 12616                              <1> 	;
 12617                              <1> ;out_of_swpspc:
 12618                              <1> ;	stc
 12619                              <1> ;	retn
 12620                              <1> 
 12621                              <1> lswbl_found:
 12622 000037E1 89D9                <1> 	mov	ecx, ebx
 12623 000037E3 81E900000D00        <1> 	sub	ecx, swap_alloc_table
 12624 000037E9 890D[1B920000]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
 12625                              <1> 				 ; address/offset (to the next)
 12626 000037EF FF0D[17920000]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
 12627                              <1> 	;
 12628 000037F5 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 12629                              <1> 				 ; is copied into the Carry Flag and then cleared
 12630                              <1> 				 ; in the destination.
 12631                              <1> 				 ;
 12632                              <1> 				 ; Reset the bit which is corresponding to the 
 12633                              <1> 				 ; (just) allocated block.
 12634 000037F8 C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
 12635 000037FB 01C8                <1> 	add	eax, ecx	 ; = block number
 12636 000037FD C1E003              <1> 	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
 12637                              <1> 				 ; 1 block =  8 sectors
 12638                              <1> 	;
 12639                              <1> 	; EAX = offset address of swap disk/file sector (beginning of the block)
 12640                              <1> 	;
 12641                              <1> 	; NOTE: The relevant page table entry will be updated
 12642                              <1> 	;       according to this EAX value...
 12643                              <1> 	;
 12644 00003800 EBDC                <1> 	jmp	short lswbl_ok
 12645                              <1> 
 12646                              <1> logical_disk_read:
 12647                              <1> 	; 20/07/2015
 12648                              <1> 	; 09/03/2015 (temporary code here)
 12649                              <1> 	;
 12650                              <1> 	; INPUT ->
 12651                              <1> 	; 	ESI = Logical disk description table address
 12652                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12653                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12654                              <1> 	; 	ECX = Sector count
 12655                              <1> 	;
 12656                              <1> 	;
 12657 00003802 C3                  <1> 	retn
 12658                              <1> 
 12659                              <1> logical_disk_write:
 12660                              <1> 	; 20/07/2015
 12661                              <1> 	; 09/03/2015 (temporary code here)
 12662                              <1> 	;
 12663                              <1> 	; INPUT ->
 12664                              <1> 	; 	ESI = Logical disk description table address
 12665                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12666                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12667                              <1> 	; 	ECX = Sector count
 12668                              <1> 	;
 12669 00003803 C3                  <1> 	retn
 12670                              <1> 
 12671                              <1> get_physical_addr:
 12672                              <1> 	; 18/10/2015
 12673                              <1> 	; 29/07/2015
 12674                              <1> 	; 20/07/2015
 12675                              <1> 	; 04/06/2015
 12676                              <1> 	; 20/05/2015
 12677                              <1> 	; 28/04/2015
 12678                              <1> 	; 18/04/2015
 12679                              <1> 	; Get physical address
 12680                              <1> 	;     (allocates a new page for user if it is not present)
 12681                              <1> 	;	
 12682                              <1> 	; (This subroutine is needed for mapping user's virtual 
 12683                              <1> 	; (buffer) address to physical address (of the buffer).)
 12684                              <1> 	; ('sys write', 'sys read' system calls...)
 12685                              <1> 	;
 12686                              <1> 	; INPUT ->
 12687                              <1> 	;	EBX = virtual address
 12688                              <1> 	;	u.pgdir = page directory (physical) address
 12689                              <1> 	;
 12690                              <1> 	; OUTPUT ->
 12691                              <1> 	;	EAX = physical address 
 12692                              <1> 	;	EBX = linear address	
 12693                              <1> 	;	EDX = physical address of the page frame
 12694                              <1> 	;	      (with attribute bits)
 12695                              <1> 	;	ECX = byte count within the page frame
 12696                              <1> 	;
 12697                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
 12698                              <1> 	;
 12699 00003804 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
 12700                              <1> 	;
 12701 0000380A A1[B1850000]        <1> 	mov	eax, [u.pgdir]
 12702 0000380F E878FAFFFF          <1> 	call	get_pte
 12703                              <1> 		; EDX = Page table entry address (if CF=0)
 12704                              <1> 	        ;       Page directory entry address (if CF=1)
 12705                              <1> 		;       (Bit 0 value is 0 if PT is not present)
 12706                              <1> 		; EAX = Page table entry value (page address)
 12707                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
 12708 00003814 731C                <1> 	jnc	short gpa_1
 12709                              <1> 	;
 12710 00003816 E856F9FFFF          <1> 	call	allocate_page
 12711 0000381B 725B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
 12712                              <1> gpa_0:
 12713 0000381D E8C9F9FFFF          <1> 	call 	clear_page
 12714                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 12715 00003822 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
 12716                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
 12717                              <1> 			   ; (user, writable, present page)	
 12718 00003824 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
 12719 00003826 A1[B1850000]        <1> 	mov	eax, [u.pgdir]	
 12720 0000382B E85CFAFFFF          <1> 	call	get_pte
 12721 00003830 7246                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12722                              <1> gpa_1:
 12723                              <1> 	; EAX = PTE value, EDX = PTE address
 12724 00003832 A801                <1> 	test 	al, PTE_A_PRESENT
 12725 00003834 751A                <1> 	jnz	short gpa_3
 12726 00003836 09C0                <1> 	or	eax, eax
 12727 00003838 7430                <1> 	jz	short gpa_4  ; Allocate a new page
 12728                              <1> 	; 20/07/2015
 12729 0000383A 55                  <1> 	push	ebp
 12730 0000383B 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
 12731                              <1> 	; reload swapped page
 12732 0000383D E83C000000          <1> 	call	reload_page ; 28/04/2015
 12733 00003842 5D                  <1> 	pop	ebp
 12734 00003843 7224                <1> 	jc	short gpa_retn
 12735                              <1> gpa_2:
 12736                              <1> 	; 20/07/2015
 12737                              <1> 	; 20/05/2015
 12738                              <1> 	; add this page to swap queue
 12739 00003845 50                  <1> 	push	eax 
 12740                              <1> 	; EBX = virtual address
 12741 00003846 E8E3FEFFFF          <1> 	call 	add_to_swap_queue
 12742 0000384B 58                  <1> 	pop	eax
 12743                              <1> 		; PTE address in EDX
 12744                              <1> 		; virtual address in EBX
 12745                              <1> 	; EAX = memory page address
 12746 0000384C 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
 12747                              <1> 				  ; present flag, bit 0 = 1
 12748                              <1> 				  ; user flag, bit 2 = 1	
 12749                              <1> 				  ; writable flag, bit 1 = 1
 12750 0000384E 8902                <1> 	mov	[edx], eax  ; Update PTE value
 12751                              <1> gpa_3:
 12752                              <1> 	; 18/10/2015
 12753 00003850 89D9                <1> 	mov	ecx, ebx
 12754 00003852 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
 12755 00003858 89C2                <1> 	mov 	edx, eax
 12756 0000385A 662500F0            <1> 	and	ax, PTE_A_CLEAR
 12757 0000385E 01C8                <1> 	add	eax, ecx
 12758 00003860 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
 12759 00003862 81C100100000        <1> 	add	ecx, PAGE_SIZE
 12760 00003868 F8                  <1> 	clc
 12761                              <1> gpa_retn:
 12762 00003869 C3                  <1> 	retn	
 12763                              <1> gpa_4:	
 12764 0000386A E802F9FFFF          <1> 	call	allocate_page
 12765 0000386F 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12766 00003871 E875F9FFFF          <1> 	call	clear_page
 12767 00003876 EBCD                <1> 	jmp	short gpa_2
 12768                              <1> 
 12769                              <1> gpa_im_err:	
 12770 00003878 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12771                              <1> 				  ; Major error = 0 (No protection fault)	
 12772 0000387D C3                  <1> 	retn
 12773                              <1> 
 12774                              <1> reload_page:
 12775                              <1> 	; 20/07/2015
 12776                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
 12777                              <1> 	;
 12778                              <1> 	; Reload (Restore) swapped page at memory
 12779                              <1> 	;
 12780                              <1> 	; INPUT -> 
 12781                              <1> 	;	EBP = Virtual (linear) memory address
 12782                              <1> 	;	EAX = PTE value (swap disk sector address)
 12783                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
 12784                              <1> 	; OUTPUT ->
 12785                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
 12786                              <1> 	;
 12787                              <1> 	;	CF = 1 and EAX = error code
 12788                              <1> 	;
 12789                              <1> 	; Modified Registers -> none (except EAX)
 12790                              <1> 	;
 12791 0000387E D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
 12792 00003880 53                  <1> 	push	ebx      ;
 12793 00003881 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
 12794 00003883 E8E9F8FFFF          <1> 	call	allocate_page
 12795 00003888 720C                <1> 	jc	short rlp_im_err
 12796 0000388A 93                  <1> 	xchg 	eax, ebx	
 12797                              <1> 	; EBX = Physical memory (page) address
 12798                              <1> 	; EAX = Swap disk (offset) address
 12799                              <1> 	; EBP = Virtual (linear) memory address
 12800 0000388B E81AFDFFFF          <1> 	call	swap_in
 12801 00003890 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
 12802 00003892 89D8                <1> 	mov	eax, ebx	
 12803                              <1> rlp_retn:
 12804 00003894 5B                  <1> 	pop	ebx
 12805 00003895 C3                  <1> 	retn
 12806                              <1> 	
 12807                              <1> rlp_im_err:	
 12808 00003896 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12809                              <1> 				  ; Major error = 0 (No protection fault)	
 12810 0000389B EBF7                <1> 	jmp	short rlp_retn
 12811                              <1> 
 12812                              <1> rlp_swp_err:
 12813 0000389D B804000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
 12814 000038A2 EBF0                <1> 	jmp	short rlp_retn
 12815                              <1> 
 12816                              <1> 
 12817                              <1> copy_page_dir:
 12818                              <1> 	; 19/09/2015
 12819                              <1> 	; temporary - 07/09/2015
 12820                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12821                              <1> 	;
 12822                              <1> 	; INPUT -> 
 12823                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 12824                              <1> 	;		    page directory.
 12825                              <1> 	; OUTPUT ->
 12826                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 12827                              <1> 	;	       page directory.
 12828                              <1> 	;	(New page directory with new page table entries.)
 12829                              <1> 	;	(New page tables with read only copies of the parent's
 12830                              <1> 	;	pages.)
 12831                              <1> 	;	EAX = 0 -> Error (CF = 1)
 12832                              <1> 	;
 12833                              <1> 	; Modified Registers -> none (except EAX)
 12834                              <1> 	;
 12835 000038A4 E8C8F8FFFF          <1> 	call	allocate_page
 12836 000038A9 723E                <1> 	jc	short cpd_err
 12837                              <1> 	;
 12838 000038AB 55                  <1> 	push	ebp ; 20/07/2015
 12839 000038AC 56                  <1> 	push	esi
 12840 000038AD 57                  <1> 	push	edi
 12841 000038AE 53                  <1> 	push	ebx
 12842 000038AF 51                  <1> 	push	ecx
 12843 000038B0 8B35[B1850000]      <1> 	mov	esi, [u.pgdir]
 12844 000038B6 89C7                <1> 	mov	edi, eax
 12845 000038B8 50                  <1> 	push	eax ; save child's page directory address
 12846                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 12847                              <1> 	; (use same system space for all user page tables) 
 12848 000038B9 A5                  <1> 	movsd
 12849 000038BA BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 12850 000038BF B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 12851                              <1> cpd_0:	
 12852 000038C4 AD                  <1> 	lodsd
 12853                              <1> 	;or	eax, eax
 12854                              <1>         ;jnz     short cpd_1
 12855 000038C5 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 12856 000038C7 7508                <1> 	jnz	short cpd_1
 12857                              <1>  	; (virtual address at the end of the page table)	
 12858 000038C9 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 12859 000038CF EB0F                <1> 	jmp	short cpd_2
 12860                              <1> cpd_1:	
 12861 000038D1 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 12862 000038D5 89C3                <1> 	mov	ebx, eax
 12863                              <1> 	; EBX = Parent's page table address
 12864 000038D7 E81F000000          <1> 	call	copy_page_table
 12865 000038DC 720C                <1> 	jc	short cpd_p_err
 12866                              <1> 	; EAX = Child's page table address
 12867 000038DE 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 12868                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 12869                              <1> 			 ; (present, writable, user)
 12870                              <1> cpd_2:
 12871 000038E0 AB                  <1> 	stosd
 12872 000038E1 E2E1                <1> 	loop	cpd_0
 12873                              <1> 	;
 12874 000038E3 58                  <1> 	pop	eax  ; restore child's page directory address
 12875                              <1> cpd_3:
 12876 000038E4 59                  <1> 	pop	ecx
 12877 000038E5 5B                  <1> 	pop	ebx
 12878 000038E6 5F                  <1> 	pop	edi
 12879 000038E7 5E                  <1> 	pop	esi
 12880 000038E8 5D                  <1> 	pop	ebp
 12881                              <1> cpd_err:
 12882 000038E9 C3                  <1> 	retn
 12883                              <1> cpd_p_err:
 12884                              <1> 	; release the allocated pages missing (recover free space)
 12885 000038EA 58                  <1> 	pop	eax  ; the new page directory address (physical)
 12886 000038EB 8B1D[B1850000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 12887 000038F1 E8B4F9FFFF          <1> 	call 	deallocate_page_dir
 12888 000038F6 29C0                <1> 	sub	eax, eax ; 0
 12889 000038F8 F9                  <1> 	stc
 12890 000038F9 EBE9                <1> 	jmp	short cpd_3	
 12891                              <1> 
 12892                              <1> copy_page_table:
 12893                              <1> 	; 19/09/2015
 12894                              <1> 	; temporary - 07/09/2015
 12895                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12896                              <1> 	;
 12897                              <1> 	; INPUT -> 
 12898                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 12899                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
 12900                              <1> 	; OUTPUT ->
 12901                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 12902                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 12903                              <1> 	;	CF = 1 -> error 
 12904                              <1> 	;
 12905                              <1> 	; Modified Registers -> EBP (except EAX)
 12906                              <1> 	;
 12907 000038FB E871F8FFFF          <1> 	call	allocate_page
 12908 00003900 725A                <1> 	jc	short cpt_err
 12909                              <1> 	;
 12910 00003902 50                  <1> 	push	eax ; *
 12911                              <1> 	;push 	ebx
 12912 00003903 56                  <1> 	push	esi
 12913 00003904 57                  <1> 	push	edi
 12914 00003905 52                  <1> 	push	edx
 12915 00003906 51                  <1> 	push	ecx
 12916                              <1> 	;
 12917 00003907 89DE                <1> 	mov	esi, ebx
 12918 00003909 89C7                <1> 	mov	edi, eax
 12919 0000390B 89C2                <1> 	mov	edx, eax
 12920 0000390D 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 12921                              <1> cpt_0:
 12922 00003913 AD                  <1> 	lodsd
 12923 00003914 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 12924 00003916 750B                <1> 	jnz	short cpt_1
 12925 00003918 21C0                <1> 	and	eax, eax
 12926 0000391A 7430                <1> 	jz	short cpt_2
 12927                              <1> 	; ebp = virtual (linear) address of the memory page
 12928 0000391C E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
 12929 00003921 7234                <1> 	jc	short cpt_p_err
 12930                              <1> cpt_1:
 12931 00003923 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 12932 00003927 89C1                <1> 	mov	ecx, eax
 12933                              <1> 	; Allocate a new page for the child process
 12934 00003929 E843F8FFFF          <1> 	call	allocate_page
 12935 0000392E 7227                <1> 	jc	short cpt_p_err
 12936 00003930 57                  <1> 	push	edi
 12937 00003931 56                  <1> 	push	esi
 12938 00003932 89CE                <1> 	mov	esi, ecx
 12939 00003934 89C7                <1> 	mov	edi, eax
 12940 00003936 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 12941 0000393B F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 12942 0000393D 5E                  <1> 	pop	esi
 12943 0000393E 5F                  <1> 	pop	edi
 12944                              <1> 	; 
 12945 0000393F 53                  <1> 	push	ebx
 12946 00003940 50                  <1> 	push	eax
 12947 00003941 89EB                <1> 	mov	ebx, ebp
 12948                              <1> 	; ebx = virtual address of the memory page
 12949 00003943 E8E6FDFFFF          <1> 	call	add_to_swap_queue
 12950 00003948 58                  <1> 	pop	eax
 12951 00003949 5B                  <1> 	pop	ebx
 12952                              <1> 	;
 12953                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 12954 0000394A 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 12955                              <1> cpt_2:
 12956 0000394C AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 12957                              <1> 	;
 12958 0000394D 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 12959                              <1> 	;
 12960 00003953 39D7                <1> 	cmp	edi, edx
 12961 00003955 72BC                <1> 	jb	short cpt_0
 12962                              <1> cpt_p_err:
 12963 00003957 59                  <1> 	pop	ecx
 12964 00003958 5A                  <1> 	pop	edx
 12965 00003959 5F                  <1> 	pop	edi
 12966 0000395A 5E                  <1> 	pop	esi
 12967                              <1> 	;pop	ebx
 12968 0000395B 58                  <1> 	pop	eax ; *
 12969                              <1> cpt_err:
 12970 0000395C C3                  <1> 	retn
 12971                              <1> 
 12972                              <1> 
 12973                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
 12974                              <1> 
 12975                              <1> ;; Data:
 12976                              <1> 
 12977                              <1> ; 09/03/2015
 12978                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
 12979                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
 12980                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 12981                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 12982                              <1> ;swpd_next:  dd 0 ; next free page block
 12983                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
 12984                                  %include 'timer.s'   ; 17/01/2015
 12985                              <1> ; ****************************************************************************
 12986                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - timer.s
 12987                              <1> ; ----------------------------------------------------------------------------
 12988                              <1> ; Last Update: 29/01/2016
 12989                              <1> ; ----------------------------------------------------------------------------
 12990                              <1> ; Beginning: 17/01/2016
 12991                              <1> ; ----------------------------------------------------------------------------
 12992                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 12993                              <1> ; ----------------------------------------------------------------------------
 12994                              <1> ; Turkish Rational DOS
 12995                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
 12996                              <1> ;
 12997                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 12998                              <1> ;
 12999                              <1> ; Derived from 'IBM PC-AT' BIOS source code (1985) 
 13000                              <1> ; ****************************************************************************
 13001                              <1> 
 13002                              <1> ; TRDOS 386  (TRDOS v2.0) Kernel - TIMER & REAL TIME CLOCK (BIOS) FUNCTIONS
 13003                              <1> 
 13004                              <1> ; IBM PC-AT BIOS Source Code ('BIOS2.ASM')
 13005                              <1> ; TITLE BIOS2 ---- 06/10/85 BIOS INTERRUPT ROUTINES
 13006                              <1> 
 13007                              <1> ;
 13008                              <1> ; ///////// TIMER (& REAL TIME CLOCK) FUNCTIONS ///////////////
 13009                              <1> 
 13010                              <1> int1Ah:
 13011                              <1> 	; 29/01/2016
 13012                              <1> 	; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
 13013 0000395D 9C                  <1> 	pushfd
 13014 0000395E 0E                  <1> 	push 	cs
 13015 0000395F E801000000          <1> 	call 	TIME_OF_DAY_1
 13016 00003964 C3                  <1> 	retn
 13017                              <1> 
 13018                              <1> ;--- INT  1A H -- (TIME OF DAY) -------------------------------------------------
 13019                              <1> ;       THIS BIOS ROUTINE ALLOWS THE CLOCKS TO BE SET OR READ			:
 13020                              <1> ;										:
 13021                              <1> ; PARAMETERS:									:
 13022                              <1> ;     (AH) = 00H  READ THE CURRENT SETTING AND RETURN WITH,			:
 13023                              <1> ;                      (CX) = HIGH PORTION OF COUNT				:
 13024                              <1> ;                      (DX) = LOW PORTION OF COUNT				:
 13025                              <1> ;                      (AL) = 0 TIMER HAS NOT PASSED 24 HOURS SINCE LAST READ	:
 13026                              <1> ;                             1 IF ON ANOTHER DAY. (RESET TO ZERO AFTER READ)	:
 13027                              <1> ;										:
 13028                              <1> ;     (AH) = 01H  SET THE CURRENT CLOCK USING,					:
 13029                              <1> ;		     (CX) = HIGH PORTION OF COUNT				:
 13030                              <1> ;		     (DX) = LOW PORTION OF COUNT.				:
 13031                              <1> ;										:
 13032                              <1> ;               NOTE: COUNTS OCCUR AT THE RATE OF 1193180/65536 COUNTS/SECOND	:
 13033                              <1> ;                            (OR ABOUT 18.2 PER SECOND -- SEE EQUATES)		:
 13034                              <1> ;										:
 13035                              <1> ;     (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,			:
 13036                              <1> ;                      (CH) = HOURS IN BCD (00-23)				:
 13037                              <1> ;                      (CL) = MINUTES IN BCD (00-59)				:
 13038                              <1> ;                      (DH) = SECONDS IN BCD (00-59)				:
 13039                              <1> ;                      (DL) = DAYLIGHT SAVINGS ENABLE (00-01)			:
 13040                              <1> ;										:
 13041                              <1> ;     (AH) = 03H  SET THE REAL TIME CLOCK USING,				:
 13042                              <1> ;                     (CH) = HOURS IN BCD (00-23)				:
 13043                              <1> ;                     (CL) = MINUTES IN BCD (00-59)				:
 13044                              <1> ;                     (DH) = SECONDS IN BCD (00-59)				:
 13045                              <1> ;                     (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.	:
 13046                              <1> ;										:
 13047                              <1> ;             NOTE: (DL) = 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED.	:
 13048                              <1> ;                   (DL) = 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN	:
 13049                              <1> ;	           APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN	:
 13050                              <1> ;                   OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.		:
 13051                              <1> ;										:
 13052                              <1> ;     (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,	:
 13053                              <1> ;                      (CH) = CENTURY IN BCD (19 OR 20)				:
 13054                              <1> ;                      (CL) = YEAR IN BCD (00-99)				:
 13055                              <1> ;                      (DH) = MONTH IN BCD (01-12)				:
 13056                              <1> ;                      (DL) = DAY IN BCD (01-31).				:
 13057                              <1> ;										:
 13058                              <1> ;     (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING,			:
 13059                              <1> ;                     (CH) = CENTURY IN BCD (19 OR 20)				:
 13060                              <1> ;                     (CL) = YEAR IN BCD (00-99)				:
 13061                              <1> ;                     (DH) = MONTH IN BCD (01-12)				:
 13062                              <1> ;                     (DL) = DAY IN BCD (01-31).				:
 13063                              <1> ;										:
 13064                              <1> ;     (AH) = 06H  SET THE ALARM TO INTERRUPT AT SPECIFIED TIME,			:
 13065                              <1> ;                     (CH) = HOURS IN BCD (00-23 (OR FFH))			:
 13066                              <1> ;                     (CL) = MINUTES IN BCD (00-59 (OR FFH))			:
 13067                              <1> ;                     (DH) = SECONDS IN BCD (00-59 (OR FFH))			:
 13068                              <1> ;										:
 13069                              <1> ;     (AH) = 07H  RESET THE ALARM INTERRUPT FUNCTION.				:
 13070                              <1> ;										:
 13071                              <1> ; NOTES: FOR ALL RETURNS CY= 0 FOR SUCCESSFUL OPERATION.			:
 13072                              <1> ;        FOR (AH)= 2, 4, 6 - CARRY FLAG SET IF REAL TIME CLOCK NOT OPERATING.	:
 13073                              <1> ;        FOR (AH)= 6 - CARRY FLAG SET IF ALARM ALREADY ENABLED. 		:
 13074                              <1> ;        FOR THE ALARM FUNCTION (AH = 6) THE USER MUST SUPPLY A ROUTINE AND	:
 13075                              <1> ;         INTERCEPT THE CORRECT ADDRESS IN THE VECTOR TABLE FOR INTERRUPT 4AH.	:
 13076                              <1> ;         USE 0FFH FOR ANY "DO NOT CARE" POSITION FOR INTERVAL INTERRUPTS.	:
 13077                              <1> ;        INTERRUPTS ARE DISABLED DURING DATA MODIFICATION. 			:
 13078                              <1> ;        AH & AL ARE RETURNED MODIFIED AND NOT DEFINED EXCEPT WHERE INDICATED.	:
 13079                              <1> ;--------------------------------------------------------------------------------
 13080                              <1> 
 13081                              <1> ; 29/01/2016
 13082                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
 13083                              <1> 
 13084                              <1> TIME_OF_DAY_1:
 13085 00003965 FB                  <1> 	sti				; INTERRUPTS BACK ON
 13086 00003966 80FC08              <1> 	cmp	ah, (RTC_TBE-RTC_TB)/4	; CHECK IF COMMAND IN VALID RANGE (0-7)
 13087 00003969 F5                  <1> 	cmc				; COMPLEMENT CARRY FOR ERROR EXIT
 13088 0000396A 721A                <1> 	jc	short TIME_9		; EXIT WITH CARRY = 1 IF NOT VALID
 13089                              <1> 
 13090 0000396C 1E                  <1> 	push	ds
 13091 0000396D 56                  <1> 	push	esi
 13092 0000396E 66BE1000            <1> 	mov	si, KDATA		; kernel data segment
 13093 00003972 8EDE                <1> 	mov	ds, si
 13094 00003974 C0E402              <1> 	shl	ah, 2			; convert function to dword offset
 13095 00003977 0FB6F4              <1> 	movzx	esi, ah			; PLACE INTO ADDRESSING REGISTER
 13096 0000397A FA                  <1> 	cli				; NO INTERRUPTS DURING TIME FUNCTIONS
 13097 0000397B FF96[89390000]      <1> 	call	[esi+RTC_TB]		; VECTOR TO FUNCTION REQUESTED WITH CY=0
 13098                              <1> 					; RETURN WITH CARRY FLAG SET FOR RESULT
 13099 00003981 FB                  <1> 	sti				; INTERRUPTS BACK ON
 13100 00003982 B400                <1> 	mov	ah, 0			; CLEAR (AH) TO ZERO
 13101 00003984 5E                  <1> 	pop	esi			; RECOVER USERS REGISTER
 13102 00003985 1F                  <1> 	pop	ds			; RECOVER USERS SEGMENT SELECTOR
 13103                              <1> TIME_9:					; RETURN WITH CY= 0 IF NO ERROR
 13104 00003986 CA0400              <1> 	retf	4
 13105                              <1> 					; ROUTINE VECTOR TABLE (AH)=
 13106                              <1> RTC_TB:
 13107 00003989 [A9390000]          <1> 	dd	RTC_00			; 0 = READ CURRENT CLOCK COUNT
 13108 0000398D [BC390000]          <1> 	dd	RTC_10			; 1 = SET CLOCK COUNT
 13109 00003991 [CA390000]          <1> 	dd	RTC_20			; 2 = READ THE REAL TIME CLOCK TIME
 13110 00003995 [F9390000]          <1> 	dd	RTC_30			; 3 = SET REAL TIME CLOCK TIME
 13111 00003999 [3B3A0000]          <1> 	dd	RTC_40			; 4 = READ THE REAL TIME CLOCK DATE
 13112 0000399D [683A0000]          <1> 	dd	RTC_50			; 5 = SET REAL TIME CLOCK DATE
 13113 000039A1 [B53A0000]          <1> 	dd	RTC_60			; 6 = SET THE REAL TIME CLOCK ALARM
 13114 000039A5 [083B0000]          <1> 	dd	RTC_70			; 7 = RESET ALARM
 13115                              <1> 
 13116                              <1> RTC_TBE	equ	$
 13117                              <1> 
 13118                              <1> RTC_00:				; READ TIME COUNT
 13119 000039A9 A0[50790000]        <1> 	mov	al, [TIMER_OFL]		; GET THE OVERFLOW FLAG
 13120 000039AE C605[50790000]00    <1> 	mov	byte [TIMER_OFL], 0	; AND THEN RESET THE OVERFLOW FLAG
 13121 000039B5 8B0D[4C790000]      <1>         mov     ecx, [TIMER_LH]         ; GET COUNT OF TIME
 13122 000039BB C3                  <1> 	retn
 13123                              <1> 
 13124                              <1> RTC_10:				; SET TIME COUNT
 13125 000039BC 890D[4C790000]      <1>         mov     [TIMER_LH], ecx         ; SET TIME COUNT
 13126 000039C2 C605[50790000]00    <1> 	mov	byte [TIMER_OFL], 0	; RESET OVERFLOW FLAG
 13127 000039C9 C3                  <1> 	retn				; RETURN WITH NO CARRY
 13128                              <1> 
 13129                              <1> RTC_20:				; GET RTC TIME
 13130 000039CA E8EB010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
 13131 000039CF 7227                <1> 	jc	short RTC_29		; EXIT IF ERROR (CY= 1)
 13132                              <1> 
 13133 000039D1 B000                <1> 	mov	al, CMOS_SECONDS	; SET ADDRESS OF SECONDS
 13134 000039D3 E8FD010000          <1> 	call	CMOS_READ		; GET SECONDS
 13135 000039D8 88C6                <1> 	mov	dh, al			; SAVE
 13136 000039DA B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
 13137 000039DC E8F4010000          <1> 	call	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 13138 000039E1 2401                <1> 	and	al, 00000001b		; MASK FOR VALID DSE BIT
 13139 000039E3 88C2                <1> 	mov	dl, al			; SET [DL] TO ZERO FOR NO DSE BIT
 13140 000039E5 B002                <1> 	mov	al, CMOS_MINUTES	; SET ADDRESS OF MINUTES
 13141 000039E7 E8E9010000          <1> 	call	CMOS_READ		; GET MINUTES
 13142 000039EC 88C1                <1> 	mov	cl, al			; SAVE
 13143 000039EE B004                <1>         mov     al, CMOS_HOURS          ; SET ADDRESS OF HOURS
 13144 000039F0 E8E0010000          <1> 	call	CMOS_READ		; GET HOURS
 13145 000039F5 88C5                <1> 	mov	ch, al			; SAVE
 13146 000039F7 F8                  <1> 	clc				; SET CY= 0
 13147                              <1> RTC_29:
 13148 000039F8 C3                  <1> 	retn				; RETURN WITH RESULT IN CARRY FLAG
 13149                              <1> 
 13150                              <1> RTC_30:				; SET RTC TIME
 13151 000039F9 E8BC010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
 13152 000039FE 7305                <1> 	jnc	short RTC_35		; GO AROUND IF CLOCK OPERATING
 13153 00003A00 E817010000          <1> 	call	RTC_STA			; ELSE TRY INITIALIZING CLOCK
 13154                              <1> RTC_35:
 13155 00003A05 88F4                <1> 	mov	ah, dh			; GET TIME BYTE - SECONDS
 13156 00003A07 B000                <1> 	mov	al, CMOS_SECONDS	; ADDRESS SECONDS
 13157 00003A09 E8DF010000          <1> 	call	CMOS_WRITE		; UPDATE SECONDS
 13158 00003A0E 88CC                <1> 	mov	ah, cl			; GET TIME BYTE - MINUTES
 13159 00003A10 B002                <1> 	mov	al, CMOS_MINUTES	; ADDRESS MINUTES
 13160 00003A12 E8D6010000          <1> 	call	CMOS_WRITE		; UPDATE MINUTES
 13161 00003A17 88EC                <1> 	mov	ah, ch			; GET TIME BYTE - HOURS
 13162 00003A19 B004                <1> 	mov	al, CMOS_HOURS		; ADDRESS HOURS
 13163 00003A1B E8CD010000          <1> 	call	CMOS_WRITE		; UPDATE ADDRESS
 13164                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
 13165                              <1> 	;mov	ah, al
 13166 00003A20 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
 13167 00003A24 E8AC010000          <1> 	call	CMOS_READ		; READ CURRENT TIME
 13168 00003A29 2462                <1> 	and	al, 01100010b		; MASK FOR VALID BIT POSITIONS
 13169 00003A2B 0C02                <1> 	or	al, 00000010b		; TURN ON 24 HOUR MODE
 13170 00003A2D 80E201              <1> 	and	dl, 00000001b		; USE ONLY THE DSE BIT
 13171 00003A30 08D0                <1> 	or	al, dl			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
 13172 00003A32 86E0                <1> 	xchg	ah, al			; PLACE IN WORK REGISTER AND GET ADDRESS
 13173 00003A34 E8B4010000          <1> 	call	CMOS_WRITE		; SET NEW ALARM SITS
 13174 00003A39 F8                  <1> 	clc				; SET CY= 0
 13175 00003A3A C3                  <1> 	retn				; RETURN WITH CY= 0
 13176                              <1> 
 13177                              <1> RTC_40:				; GET RTC DATE
 13178 00003A3B E87A010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
 13179 00003A40 7225                <1> 	jc	short RTC_49		; EXIT IF ERROR (CY= 1)
 13180                              <1> 
 13181 00003A42 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
 13182 00003A44 E88C010000          <1> 	call	CMOS_READ		; READ DAY OF MONTH
 13183 00003A49 88C2                <1> 	mov	dl, al			; SAVE
 13184 00003A4B B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH
 13185 00003A4D E883010000          <1> 	call	CMOS_READ		; READ MONTH
 13186 00003A52 88C6                <1> 	mov	dh, al			; SAVE
 13187 00003A54 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR
 13188 00003A56 E87A010000          <1> 	call	CMOS_READ		; READ YEAR
 13189 00003A5B 88C1                <1> 	mov	cl, al			; SAVE
 13190 00003A5D B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY LOCATION
 13191 00003A5F E871010000          <1> 	call	CMOS_READ		; GET CENTURY BYTE
 13192 00003A64 88C5                <1> 	mov	ch, al			; SAVE
 13193 00003A66 F8                  <1> 	clc				; SET CY=0
 13194                              <1> RTC_49:
 13195 00003A67 C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAG
 13196                              <1> 
 13197                              <1> RTC_50:				; SET RTC DATE
 13198 00003A68 E84D010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
 13199 00003A6D 7305                <1> 	jnc	short RTC_55		; GO AROUND IF NO ERROR
 13200 00003A6F E8A8000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
 13201                              <1> RTC_55:
 13202 00003A74 66B80600            <1> 	mov	ax, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
 13203 00003A78 E870010000          <1> 	call	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
 13204 00003A7D 88D4                <1> 	mov	ah, dl			; GET DAY OF MONTH BYTE
 13205 00003A7F B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
 13206 00003A81 E867010000          <1> 	call	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
 13207 00003A86 88F4                <1> 	mov	ah, dh			; GET MONTH
 13208 00003A88 B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH BYTE
 13209 00003A8A E85E010000          <1> 	call	CMOS_WRITE		; WRITE MONTH REGISTER
 13210 00003A8F 88CC                <1> 	mov	ah, cl			; GET YEAR BYTE
 13211 00003A91 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR REGISTER
 13212 00003A93 E855010000          <1> 	call	CMOS_WRITE		; WRITE YEAR REGISTER
 13213 00003A98 88EC                <1> 	mov	ah, ch			; GET CENTURY BYTE
 13214 00003A9A B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY BYTE
 13215 00003A9C E84C010000          <1> 	call	CMOS_WRITE		; WRITE CENTURY LOCATION
 13216                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
 13217                              <1> 	;mov	ah, al
 13218 00003AA1 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
 13219 00003AA5 E82B010000          <1> 	call	CMOS_READ		; READ WIRRENT SETTINGS
 13220 00003AAA 247F                <1> 	and	al, 07Fh		; CLEAR 'SET BIT'
 13221 00003AAC 86E0                <1> 	xchg	ah, al			; MOVE TO WORK REGISTER
 13222 00003AAE E83A010000          <1> 	call	CMOS_WRITE		; AND START CLOCK UPDATING
 13223 00003AB3 F8                  <1> 	clc				; SET CY= 0
 13224 00003AB4 C3                  <1> 	retn				; RETURN CY=0
 13225                              <1> 
 13226                              <1> RTC_60:				; SET RTC ALARM
 13227 00003AB5 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM
 13228 00003AB7 E819010000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
 13229 00003ABC A820                <1> 	test	al, 20h			; CHECK FOR ALARM ALREADY ENABLED
 13230 00003ABE F9                  <1> 	stc				; SET CARRY IN CASE OF ERROR
 13231 00003ABF 7542                <1> 	jnz	short RTC_69		; ERROR EXIT IF ALARM SET
 13232 00003AC1 E8F4000000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
 13233 00003AC6 7305                <1> 	jnc	short RTC_65		; SKIP INITIALIZATION IF NO ERROR
 13234 00003AC8 E84F000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
 13235                              <1> RTC_65:	
 13236 00003ACD 88F4                <1> 	mov	ah, dh			; GET SECONDS BYTE
 13237 00003ACF B001                <1> 	mov	al, CMOS_SEC_ALARM	; ADDRESS THE SECONDS ALARM REGISTER
 13238 00003AD1 E817010000          <1> 	call	CMOS_WRITE		; INSERT SECONDS
 13239 00003AD6 88CC                <1> 	mov	ah, cl			; GET MINUTES PARAMETER
 13240 00003AD8 B003                <1> 	mov	al, CMOS_MIN_ALARM	; ADDRESS MINUTES ALARM REGISTER
 13241 00003ADA E80E010000          <1> 	call	CMOS_WRITE		; INSERT MINUTES
 13242 00003ADF 88EC                <1> 	mov	ah, ch			; GET HOURS PARAMETER
 13243 00003AE1 B005                <1> 	mov	al, CMOS_HR_ALARM	; ADDRESS HOUR ALARM REGISTER
 13244 00003AE3 E805010000          <1> 	call	CMOS_WRITE		; INSERT HOURS
 13245 00003AE8 E4A1                <1> 	in	al, INTB01		; READ SECOND INTERRUPT MASK REGISTER
 13246 00003AEA 24FE                <1> 	and	al, 0FEh		; ENABLE ALARM TIMER BIT (CY= 0)
 13247 00003AEC E6A1                <1> 	out	INTB01, al		; WRITE UPDATED MASK
 13248                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
 13249                              <1> 	;mov	ah, al
 13250 00003AEE 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
 13251 00003AF2 E8DE000000          <1> 	call	CMOS_READ		; READ CURRENT ALARM REGISTER
 13252 00003AF7 247F                <1> 	and	al, 07Fh		; ENSURE SET BIT TURNED OFF
 13253 00003AF9 0C20                <1> 	or	al, 20h			; TURN ON ALARM ENABLE
 13254 00003AFB 86E0                <1> 	xchg	ah, al			; MOVE MASK TO OUTPUT REGISTER
 13255 00003AFD E8EB000000          <1> 	call	CMOS_WRITE		; WRITE NEW ALARM MASK
 13256 00003B02 F8                  <1> 	clc				; SET CY= 0
 13257                              <1> RTC_69:
 13258 00003B03 66B80000            <1> 	mov	ax, 0			; CLEAR AX REGISTER
 13259 00003B07 C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAC
 13260                              <1> 
 13261                              <1> RTC_70:				; RESET ALARM
 13262                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
 13263                              <1> 	;mov	ah, al
 13264 00003B08 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257	; ADDRESS ALARM REGISTER (TO BOTH AH,AL)
 13265 00003B0C E8C4000000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
 13266 00003B11 2457                <1> 	and	al, 57h			; TURN OFF ALARM ENABLE
 13267 00003B13 86E0                <1> 	xchg	ah, al			; SAVE DATA AND RECOVER ADDRESS
 13268 00003B15 E8D3000000          <1> 	call	CMOS_WRITE		; RESTORE NEW VALUE
 13269 00003B1A F8                  <1> 	clc				; SET CY= 0
 13270 00003B1B C3                  <1> 	retn				; RETURN WITH NO CARRY
 13271                              <1> 
 13272                              <1> RTC_STA:			; INITIALIZE REAL TIME CLOCK
 13273                              <1> 	;mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK		
 13274                              <1> 	;mov	ah, 26h
 13275 00003B1C 66B80A26            <1> 	mov	ax, (26h*100h)+CMOS_REG_A
 13276 00003B20 E8C8000000          <1> 	call	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
 13277                              <1> 	;mov	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION	
 13278                              <1> 	;mov	ah, 82h
 13279 00003B25 66B80B82            <1> 	mov	ax, (82h*100h)+CMOS_REG_B
 13280 00003B29 E8BF000000          <1> 	call	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
 13281 00003B2E B00C                <1> 	mov	al, CMOS_REG_C		; ADDRESS REGISTER C
 13282 00003B30 E8A0000000          <1> 	call	CMOS_READ		; READ REGISTER C TO INITIALIZE
 13283 00003B35 B00D                <1> 	mov	al, CMOS_REG_D		; ADDRESS REGISTER D
 13284 00003B37 E899000000          <1> 	call	CMOS_READ		; READ REGISTER D TO INITIALIZE
 13285 00003B3C C3                  <1> 	retn
 13286                              <1> 
 13287                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
 13288                              <1> 
 13289                              <1> ;--- HARDWARE INT  70 H -- ( IRQ LEVEL  8) --------------------------------------
 13290                              <1> ; ALARM INTERRUPT HANDLER (RTC)							:
 13291                              <1> ;       THIS ROUTINE HANDLES THE PERIODIC AND ALARM INTERRUPTS FROM THE CMOS	:
 13292                              <1> ;       TIMER. INPUT FREQUENCY IS 1.024 KHZ OR APPROXIMATELY 1024 INTERRUPTS	:
 13293                              <1> ;       EVERY SECOND FOR THE PERIODIC INTERRUPT. FOR THE ALARM FUNCTION,	:
 13294                              <1> ;       THE INTERRUPT WILL OCCUR AT THE DESIGNATED TIME.			:
 13295                              <1> ;										:
 13296                              <1> ;       INTERRUPTS ARE ENABLED WHEN THE EVENT OR ALARM FUNCTION IS ACTIVATED.	:
 13297                              <1> ;       FOR THE EVENT INTERRUPT, THE HANDLER WILL DECREMENT THE WAIT COUNTER	:
 13298                              <1> ;       AND WHEN IT EXPIRES WILL SET THE DESIGNATED LOCATION TO 80H. FOR	:
 13299                              <1> ;       THE ALARM INTERRUPT. THE USER MUST PROVIDE A ROUTINE TO INTERCEPT	:
 13300                              <1> ;       THE CORRECT ADDRESS FROM THE VECTOR TABLE INVOKED BY INTERRUPT 4AH	:
 13301                              <1> ;       PRIOR TO SETTING THE REAL TIME CLOCK ALARM (INT 1AH, AH= 06H).		:
 13302                              <1> ;--------------------------------------------------------------------------------
 13303                              <1> 
 13304                              <1> RTC_INT:			; ALARM INTERRUPT
 13305 00003B3D 1E                  <1> 	push	ds			; LEAVE INTERRUPTS DISABLED
 13306 00003B3E 50                  <1> 	push	eax			; SAVE REGISTERS
 13307 00003B3F 57                  <1> 	push	edi
 13308                              <1> RTC_I_1:				; CHECK FOR SECOND INTERRUPT
 13309 00003B40 66B88C8B            <1> 	mov	ax, 256*(CMOS_REG_B+NMI)+CMOS_REG_C+NMI ; ALARM AND STATUS
 13310 00003B44 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM FLAG MASK ADDRESS
 13311 00003B46 90                  <1> 	nop				; I/O DELAY
 13312 00003B47 EB00                <1> 	jmp	short $+2
 13313 00003B49 E471                <1> 	in	al, CMOS_DATA		; READ AND RESET INTERRUPT REQUEST FLAGS
 13314 00003B4B A860                <1> 	test	al, 01100000b		; CHECK FOR EITHER INTERRUPT PENDING
 13315 00003B4D 745D                <1> 	jz	short	RTC_I_9		; EXIT IF NOT A VALID RTC INTERRUPT
 13316                              <1> 
 13317 00003B4F 86E0                <1> 	xchg	ah, al			; SAVE FLAGS AND GET ENABLE ADDRESS
 13318 00003B51 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM ENABLE MASK ADDRESS
 13319 00003B53 90                  <1> 	nop				; I/O DELAY
 13320 00003B54 EB00                <1> 	jmp	short $+2	
 13321 00003B56 E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ALARM ENABLE MASK
 13322 00003B58 20E0                <1> 	and	al, ah			; ALLOW ONLY SOURCES THAT ARE ENABLED
 13323 00003B5A A840                <1> 	test	al, 01000000b		; CHECK FOR PERIODIC INTERRUPT
 13324 00003B5C 743B                <1> 	jz	short RTC_I_5		; SKIP IF NOT A PERIODIC INTERRUPT
 13325                              <1> 
 13326                              <1> ;-----	DECREMENT WAIT COUNT BY INTERRUPT INTERVAL
 13327                              <1> 
 13328 00003B5E 66BF1000            <1> 	mov	di, KDATA		; kernel data segment
 13329 00003B62 8EDF                <1> 	mov	ds, di
 13330                              <1> 	
 13331 00003B64 812D[46790000]D003- <1> 	sub	dword [RTC_LH], 976	; DECREMENT COUNT BY 1/1024
 13332 00003B6C 0000                <1>
 13333 00003B6E 7329                <1> 	jnc	short RTC_I_5		; SKIP TILL 32 BIT WORD LESS THAN ZERO
 13334                              <1> 
 13335                              <1> ;-----	TURN OFF PERIODIC INTERRUPT ENABLE
 13336                              <1> 
 13337 00003B70 6650                <1> 	push	ax			; SAVE INTERRUPT FLAG MASK
 13338 00003B72 66B88B8B            <1> 	mov	ax, 257*(CMOS_REG_B+NMI) ; INTERRUPT ENABLE REGISTER
 13339 00003B76 E670                <1> 	out	CMOS_PORT, al		; WRITE ADDRESS TO CMOS CLOCK
 13340 00003B78 90                  <1> 	nop				; I/O DELAY
 13341 00003B79 EB00                <1> 	jmp	short $+2
 13342 00003B7B E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ENABLES
 13343 00003B7D 24BF                <1> 	and	al, 0BFh		; TURN OFF PIE
 13344 00003B7F 86C4                <1> 	xchg	al, ah			; GET CMOS ADDRESS AND SAVE VALUE
 13345 00003B81 E670                <1> 	out	CMOS_PORT, al		; ADDRESS REGISTER B
 13346 00003B83 86C4                <1> 	xchg	al, ah			; GET NEW INTERRUPT ENABLE MASK
 13347 00003B85 E671                <1> 	out	CMOS_DATA, al		; SET MASK IN INTERRUPT ENABLE REGISTER
 13348 00003B87 C605[4A790000]00    <1> 	mov	byte [RTC_WAIT_FLAG], 0	; SET FUNCTION ACTIVE FLAG OFF
 13349 00003B8E 8B3D[4B790000]      <1> 	mov	edi, [USER_FLAG]	; SET UP (DS:DI) TO POINT TO USER FLAG
 13350 00003B94 C60780              <1> 	mov	byte [edi], 80h		; TURN ON USERS FLAG
 13351 00003B97 6658                <1> 	pop	ax			; GET INTERRUPT SOURCE BACK
 13352                              <1> RTC_I_5:
 13353 00003B99 A820                <1> 	test	al, 00100000b		; TEST FOR ALARM INTERRUPT
 13354 00003B9B 740D                <1> 	jz	short RTC_I_7		; SKIP USER INTERRUPT CALL IF NOT ALARM
 13355                              <1> 
 13356 00003B9D B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
 13357 00003B9F E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
 13358 00003BA1 FB                  <1> 	sti				; INTERRUPTS BACK ON NOW
 13359 00003BA2 52                  <1> 	push	edx
 13360 00003BA3 E8D82F0000          <1> 	call	INT4Ah			; TRANSFER TO USER ROUTINE
 13361 00003BA8 5A                  <1> 	pop	edx
 13362 00003BA9 FA                  <1> 	cli				; BLOCK INTERRUPT FOR RETRY
 13363                              <1> RTC_I_7:				; RESTART ROUTINE TO HANDLE DELAYED
 13364 00003BAA EB94                <1> 	jmp	short RTC_I_1		;  ENTRY AND SECOND EVENT BEFORE DONE
 13365                              <1> 
 13366                              <1> RTC_I_9:				; EXIT - NO PENDING INTERRUPTS
 13367 00003BAC B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
 13368 00003BAE E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
 13369 00003BB0 B020                <1> 	mov	al, EOI			; END OF INTERRUPT MASK TO 8259 - 2
 13370 00003BB2 E6A0                <1> 	out	INTB00, al		; TO 8259 - 2
 13371 00003BB4 E620                <1> 	out	INTA00,	al		; TO 8259 - 1
 13372 00003BB6 5F                  <1> 	pop	edi			; RESTORE REGISTERS
 13373 00003BB7 58                  <1> 	pop	eax
 13374 00003BB8 1F                  <1> 	pop	ds
 13375 00003BB9 CF                  <1> 	iret				; END OF INTERRUPT
 13376                              <1> 
 13377                              <1> 
 13378                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
 13379                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
 13380                              <1> UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
 13381 00003BBA 51                  <1> 	push	ecx
 13382 00003BBB B9FFFF0000          <1> 	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
 13383                              <1> 		; mov cx, 800	
 13384                              <1> UPD_10:
 13385 00003BC0 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
 13386 00003BC2 FA                  <1> 	cli				; NO TIMER INTERRUPTS DURING UPDATES
 13387 00003BC3 E80D000000          <1> 	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
 13388 00003BC8 A880                <1> 	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
 13389 00003BCA 7406                <1> 	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
 13390 00003BCC FB                  <1> 	sti				; ALLOW INTERRUPTS WHILE WAITING
 13391 00003BCD E2F1                <1> 	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
 13392 00003BCF 31C0                <1> 	xor	eax, eax		; CLEAR RESULTS IF ERROR
 13393                              <1> 		; xor ax, ax
 13394 00003BD1 F9                  <1> 	stc				; SET CARRY FOR ERROR
 13395                              <1> UPD_90:
 13396 00003BD2 59                  <1> 	pop	ecx			; RESTORE CALLERS REGISTER
 13397 00003BD3 FA                  <1> 	cli				; INTERRUPTS OFF DURING SET
 13398 00003BD4 C3                  <1> 	retn				; RETURN WITH CY FLAG SET
 13399                              <1> 
 13400                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
 13401                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
 13402                              <1> 
 13403                              <1> ;--- CMOS_READ -----------------------------------------------------------------
 13404                              <1> ;		READ BYTE FROM CMOS_SYSTEM CLOCK CONFIGURATION TABLE	       :
 13405                              <1> ;									       :
 13406                              <1> ; INPUT: (AL)=	CMOS_TABLE ADDRESS TO BE READ				       :
 13407                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
 13408                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ		       :
 13409                              <1> ;									       :
 13410                              <1> ; OUTPUT: (AL)	VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS   :
 13411                              <1> ;		ON THEN NMI LEFT DISABLED, DURING THE CMOS READ BOTH NMI AND   :
 13412                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
 13413                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
 13414                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
 13415                              <1> ;		ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED.	       :
 13416                              <1> ;-------------------------------------------------------------------------------
 13417                              <1> 
 13418                              <1> CMOS_READ:
 13419 00003BD5 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
 13420 00003BD6 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
 13421 00003BD8 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
 13422 00003BD9 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
 13423 00003BDB FA                  <1> 	cli				; DISABLE INTERRUPTS
 13424 00003BDC E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
 13425 00003BDE 90                  <1> 	nop				; I/O DELAY
 13426 00003BDF E471                <1> 	in	al, CMOS_DATA		; READ THE REQUESTED CMOS LOCATION
 13427 00003BE1 6650                <1> 	push	ax			; SAVE (AH) REGISTER VALUE AND CMOS BYTE
 13428                              <1> 	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
 13429                              <1> 		     ; ----- 10/06/85 (test4.asm)
 13430 00003BE3 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
 13431                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
 13432 00003BE5 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
 13433 00003BE7 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
 13434 00003BE9 6658                <1> 	pop	ax			; RESTORE (AH) AND (AL), CMOS BYTE
 13435 00003BEB 9D                  <1> 	popf	
 13436 00003BEC C3                  <1> 	retn				; RETURN WITH FLAGS RESTORED
 13437                              <1> 
 13438                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
 13439                              <1> 
 13440                              <1> ;--- CMOS_WRITE ----------------------------------------------------------------
 13441                              <1> ;	WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE		       :
 13442                              <1> ;									       :
 13443                              <1> ; INPUT: (AL)=	CMOS TABLE ADDRESS TO BE WRITTEN TO			       :
 13444                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
 13445                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE		       :
 13446                              <1> ;	 (AH)=	NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION	       :
 13447                              <1> ;									       :
 13448                              <1> ; OUTPUT:	VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED   :
 13449                              <1> ;		IF BIT 7 OF (AL) IS ON, DURING THE CMOS UPDATE BOTH NMI AND    :
 13450                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
 13451                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
 13452                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
 13453                              <1> ;		ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED.	       :
 13454                              <1> ;-------------------------------------------------------------------------------
 13455                              <1> 
 13456                              <1> CMOS_WRITE:				; WRITE (AH) TO LOCATION (AL)
 13457 00003BED 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
 13458 00003BEE 6650                <1> 	push	ax			; SAVE WORK REGISTER VALUES
 13459 00003BF0 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
 13460 00003BF2 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
 13461 00003BF3 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
 13462 00003BF5 FA                  <1> 	cli				; DISABLE INTERRUPTS
 13463 00003BF6 E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
 13464 00003BF8 88E0                <1> 	mov	al, ah			; GET THE DATA BYTE TO WRITE
 13465 00003BFA E671                <1> 	out	CMOS_DATA, al		; PLACE IN REQUESTED CMOS LOCATION
 13466 00003BFC B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2	; GET ADDRESS OF DEFAULT LOCATION
 13467                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
 13468 00003BFE D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
 13469 00003C00 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
 13470 00003C02 90                  <1> 	nop				; I/O DELAY
 13471 00003C03 E471                <1> 	in	al, CMOS_DATA		; OPEN STANDBY LATCH
 13472 00003C05 6658                <1> 	pop	ax			; RESTORE WORK REGISTERS
 13473 00003C07 9D                  <1> 	popf
 13474 00003C08 C3                  <1> 	retn
 13475                              <1> 
 13476                              <1> ; /// End Of TIMER FUNCTIONS ///
 13477                                  %include 'sysdefs.s' ; 24/01/2015
 13478                              <1> ; ****************************************************************************
 13479                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - SYSTEM DEFINITIONS : sysdefs.s
 13480                              <1> ; ----------------------------------------------------------------------------
 13481                              <1> ; Last Update: 24/01/2016
 13482                              <1> ; ----------------------------------------------------------------------------
 13483                              <1> ; Beginning: 24/01/2016
 13484                              <1> ; ----------------------------------------------------------------------------
 13485                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 13486                              <1> ; ----------------------------------------------------------------------------
 13487                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 13488                              <1> ; sysdefs.inc (14/11/2015)
 13489                              <1> ; ****************************************************************************
 13490                              <1> 
 13491                              <1> ; Retro UNIX 386 v1 Kernel - SYSDEFS.INC
 13492                              <1> ; Last Modification: 14/11/2015
 13493                              <1> ;
 13494                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 13495                              <1> ; (Modified from 
 13496                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 13497                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 13498                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
 13499                              <1> ; ----------------------------------------------------------------------------
 13500                              <1> ;
 13501                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 13502                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 13503                              <1> ; <Bell Laboratories (17/3/1972)>
 13504                              <1> ; <Preliminary Release of UNIX Implementation Document>
 13505                              <1> ;
 13506                              <1> ; ****************************************************************************
 13507                              <1> 
 13508                              <1> nproc 	equ	16  ; number of processes
 13509                              <1> nfiles 	equ	50
 13510                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
 13511                              <1> nbuf	equ	4   ; 6 ;; 21/08/2015 - 'namei' buffer problem when nbuf > 4 	
 13512                              <1> 		; NOTE: If fd0 super block buffer addres is beyond of the 1st
 13513                              <1> 		; 32K, DMA r/w routine or someting else causes a jump to 
 13514                              <1> 		; kernel panic routine (in 'alloc' routine, in u5.s)
 13515                              <1> 		; because of invalid buffer content (r/w error). 
 13516                              <1> 		; When all buffers are set before the end of the 1st 32k,
 13517                              <1> 		; there is no problem!? (14/11/2015) 
 13518                              <1> 
 13519                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
 13520                              <1> ;core	equ 	0  	    ; 19/04/2013	
 13521                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
 13522                              <1> 	; (if total size of argument list and arguments is 128 bytes)
 13523                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
 13524                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
 13525                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
 13526                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
 13527                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
 13528                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
 13529                              <1> 	; '/core' dump file size = 32768 bytes
 13530                              <1>  
 13531                              <1> ; 08/03/2014 
 13532                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)		 	 
 13533                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
 13534                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
 13535                              <1> 
 13536                              <1> ; 30/08/2013
 13537                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
 13538                              <1> 
 13539                              <1> ; 05/02/2014
 13540                              <1> ; process status
 13541                              <1> ;SFREE 	equ 0
 13542                              <1> ;SRUN	equ 1
 13543                              <1> ;SWAIT	equ 2
 13544                              <1> ;SZOMB	equ 3
 13545                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
 13546                              <1> 
 13547                              <1> ; 09/03/2015
 13548                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
 13549                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
 13550                              <1> swap_alloc_table equ 0D0000h  ;  swap allocation table address ; temporary
 13551                              <1> 
 13552                              <1> ; 17/09/2015
 13553                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
 13554                              <1> 
 13555                              <1> ; 21/09/2015 (36) 
 13556                              <1> ; 01/07/2015 (35)
 13557                              <1> ; 14/07/2013 (0-34)
 13558                              <1> ; UNIX v1 system calls
 13559                              <1> _rele 	equ 0
 13560                              <1> _exit 	equ 1
 13561                              <1> _fork 	equ 2
 13562                              <1> _read 	equ 3
 13563                              <1> _write	equ 4
 13564                              <1> _open	equ 5
 13565                              <1> _close 	equ 6
 13566                              <1> _wait 	equ 7
 13567                              <1> _creat 	equ 8
 13568                              <1> _link 	equ 9
 13569                              <1> _unlink	equ 10
 13570                              <1> _exec	equ 11
 13571                              <1> _chdir	equ 12
 13572                              <1> _time 	equ 13
 13573                              <1> _mkdir 	equ 14
 13574                              <1> _chmod	equ 15
 13575                              <1> _chown	equ 16
 13576                              <1> _break	equ 17
 13577                              <1> _stat	equ 18
 13578                              <1> _seek	equ 19
 13579                              <1> _tell 	equ 20
 13580                              <1> _mount	equ 21
 13581                              <1> _umount	equ 22
 13582                              <1> _setuid	equ 23
 13583                              <1> _getuid	equ 24
 13584                              <1> _stime	equ 25
 13585                              <1> _quit	equ 26	
 13586                              <1> _intr	equ 27
 13587                              <1> _fstat	equ 28
 13588                              <1> _emt 	equ 29
 13589                              <1> _mdate 	equ 30
 13590                              <1> _stty 	equ 31
 13591                              <1> _gtty	equ 32
 13592                              <1> _ilgins	equ 33
 13593                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
 13594                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
 13595                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
 13596                              <1> 
 13597                              <1> %macro sys 1-4
 13598                              <1>     ; 13/04/2015
 13599                              <1>     ; Retro UNIX 386 v1 system call.		
 13600                              <1>     mov eax, %1
 13601                              <1>     %if %0 >= 2   
 13602                              <1>         mov ebx, %2
 13603                              <1>         %if %0 >= 3    
 13604                              <1>             mov ecx, %3
 13605                              <1>             %if %0 = 4
 13606                              <1>                mov edx, %4   
 13607                              <1>             %endif
 13608                              <1>         %endif
 13609                              <1>     %endif
 13610                              <1>     int 30h	   
 13611                              <1> %endmacro
 13612                              <1> 
 13613                              <1> ; 13/05/2015 - ERROR CODES
 13614                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
 13615                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
 13616                              <1> ; 14/05/2015
 13617                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
 13618                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
 13619                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
 13620                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
 13621                              <1> ; 16/05/2015		
 13622                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
 13623                              <1> ; 18/05/2015
 13624                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
 13625                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
 13626                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
 13627                              <1> ; 07/06/2015
 13628                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
 13629                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
 13630                              <1> ; 09/06/2015
 13631                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
 13632                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
 13633                              <1> ; 16/06/2015
 13634                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
 13635                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
 13636                              <1> ; 22/06/2015
 13637                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
 13638                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
 13639                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
 13640                              <1> ; 23/06/2015
 13641                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
 13642                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
 13643                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
 13644                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
 13645                              <1> ; 27/06/2015
 13646                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
 13647                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
 13648                              <1> ; 29/06/2015
 13649                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
 13650                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error	
 13651                              <1> 
 13652                              <1> ; 26/08/2015
 13653                              <1> ; 24/07/2015
 13654                              <1> ; 24/06/2015
 13655                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
 13656                              <1> ; 01/07/2015
 13657                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
 13658                              <1> ;	 					 		
 13659                                  %include 'trdosk0.s' ; 04/01/2016 
 13660                              <1> ; ****************************************************************************
 13661                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - DEFINITIONS : trdosk0.s
 13662                              <1> ; ----------------------------------------------------------------------------
 13663                              <1> ; 04/01/2016
 13664                              <1> ; ----------------------------------------------------------------------------
 13665                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 13666                              <1> ; ----------------------------------------------------------------------------
 13667                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 13668                              <1> ; TRDOS2.ASM (09/11/2011)
 13669                              <1> ; ****************************************************************************
 13670                              <1> ; TRDOS2.ASM (c) 2004-2011 Erdogan TAN [ 17/01/2004 ] Last Update: 09/11/2011
 13671                              <1> ;
 13672                              <1> ; Masterboot / Partition Table at Beginning+1BEh
 13673                              <1> ptBootable       equ 0
 13674                              <1> ptBeginHead      equ 1
 13675                              <1> ptBeginSector    equ 2
 13676                              <1> ptBeginCylinder  equ 3
 13677                              <1> ptFileSystemID   equ 4
 13678                              <1> ptEndHead        equ 5
 13679                              <1> ptEndSector      equ 6
 13680                              <1> ptEndCylinder    equ 7
 13681                              <1> ptStartSector    equ 8
 13682                              <1> ptSectors        equ 12
 13683                              <1> 
 13684                              <1> ; Boot Sector Parameters at 7C00h
 13685                              <1> DataArea1     equ -4
 13686                              <1> DataArea2     equ -2
 13687                              <1> BootStart     equ 0h
 13688                              <1> OemName       equ 03h
 13689                              <1> BytesPerSec   equ 0Bh
 13690                              <1> SecPerClust   equ 0Dh
 13691                              <1> ResSectors    equ 0Eh
 13692                              <1> FATs          equ 10h
 13693                              <1> RootDirEnts   equ 11h
 13694                              <1> Sectors       equ 13h
 13695                              <1> Media         equ 15h
 13696                              <1> FATsecs       equ 16h
 13697                              <1> SecPerTrack   equ 18h
 13698                              <1> Heads         equ 1Ah 
 13699                              <1> Hidden1       equ 1Ch
 13700                              <1> Hidden2       equ 1Eh
 13701                              <1> HugeSec1      equ 20h
 13702                              <1> HugeSec2      equ 22h
 13703                              <1> DriveNumber   equ 24h
 13704                              <1> Reserved1     equ 25h
 13705                              <1> bootsignature equ 26h                 
 13706                              <1> VolumeID      equ 27h
 13707                              <1> VolumeLabel   equ 2Bh
 13708                              <1> FileSysType   equ 36h          
 13709                              <1> Reserved2     equ 3Eh                           ; Starting cluster of P2000
 13710                              <1> 
 13711                              <1> ; FAT32 BPB Structure
 13712                              <1> FAT32_FAT_Size equ 36
 13713                              <1> FAT32_RootFClust equ 44
 13714                              <1> FAT32_FSInfoSec equ 48
 13715                              <1> FAT32_DrvNum equ 64
 13716                              <1> FAT32_BootSig equ 66
 13717                              <1> FAT32_VolID equ 67
 13718                              <1> FAT32_VolLab equ 71
 13719                              <1> FAT32_FilSysType equ 82
 13720                              <1> 
 13721                              <1> ; BIOS Disk Parameters
 13722                              <1> DPDiskNumber  equ 0h
 13723                              <1> DPDType       equ 1h
 13724                              <1> DPReturn      equ 2h
 13725                              <1> DPHeads       equ 3h
 13726                              <1> DPCylinders   equ 4h
 13727                              <1> DPSecPerTrack equ 6h
 13728                              <1> DPDisks       equ 7h
 13729                              <1> DPTableOff    equ 8h
 13730                              <1> DPTableSeg    equ 0Ah
 13731                              <1> DPNumOfSecs   equ 0Ch
 13732                              <1> 
 13733                              <1> ; BIOS INT 13h Extensions (LBA extensions)
 13734                              <1> ; Just After DP Data (DPDiskNumber+)
 13735                              <1> DAP_PacketSize equ 10h  ; If extensions present, this byte will be >=10h
 13736                              <1> DAP_Reserved1 equ 11h   ; Reserved Byte 
 13737                              <1> DAP_NumOfBlocks equ 12h ; Value of this byte must be 0 to 127
 13738                              <1> DAP_Reserved2 equ 13h   ; Reserved Byte
 13739                              <1> DAP_Destination equ 14h ; Address of Transfer Buffer as SEGMENT:OFFSET
 13740                              <1> DAP_LBA_Address equ 18h ; LBA=(C1*H0+H1)*S0+S1-1
 13741                              <1>                         ; C1= Selected Cylinder Number
 13742                              <1>                         ; H0= Number Of Heads (Maximum Head Number + 1)
 13743                              <1>                         ; H1= Selected Head Number
 13744                              <1>                         ; S0= Maximum Sector Number
 13745                              <1>                         ; S1= Selected Sector Number
 13746                              <1>                         ; QUAD WORD
 13747                              <1> ; DAP_Flat_Destination equ 20h ; 64 bit address, if value in 4h is FFFF:FFFFh
 13748                              <1>                              ; QUAD WORD (Also, value in 0h must be 18h) 
 13749                              <1>                              ; TR-DOS will not use 64 bit Flat Address
 13750                              <1> 
 13751                              <1> ; INT 13h Function 48h "Get Enhanced Disk Drive Parameters"
 13752                              <1> ; Just After DP Data (DPDiskNumber+)
 13753                              <1> GetDParams_48h equ 20h ; Word. Data Length, must be 26 (1Ah) for short data.
 13754                              <1> GDP_48h_InfoFlag equ 22h ; Word
 13755                              <1> ; Bit 1 = 1 -> The geometry returned in bytes 4-15 is valid.
 13756                              <1> GDP_48h_NumOfPCyls equ 24h ; Double Word. Number physical cylinders.
 13757                              <1> GDP_48h_NumOfPHeads equ 28h ; Double Word. Number of physical heads.
 13758                              <1> GDP_48h_NumOfPSpT equ 2Ch ; Double word. Num of physical sectors per track.
 13759                              <1> GDP_48h_LBA_Sectors equ 30h ; 8 bytes. Number of physical/LBA sectors.
 13760                              <1> GDP_48h_BytesPerSec equ 38h ; Word. Number of bytes in a sector.
 13761                              <1> 
 13762                              <1> ; TR-DOS Standalone Program Extensions to the DiskParams Block
 13763                              <1> ; Just After DP Data (DPDiskNumber+)
 13764                              <1> TRDP_CurrentSector equ 3Ah  ; DX:AX (LBA)
 13765                              <1> TRDP_SectorCount equ 3Eh    ; CX (or Counter)
 13766                              <1> 
 13767                              <1> 
 13768                              <1> ; DOS Logical Disks
 13769                              <1> LD_Name equ 0
 13770                              <1> LD_DiskType equ 1
 13771                              <1> LD_PhyDrvNo equ 2
 13772                              <1> LD_FATType equ 3
 13773                              <1> LD_FSType equ 4
 13774                              <1> LD_LBAYes equ 5
 13775                              <1> LD_BPB equ 6
 13776                              <1> LD_FATBegin equ 96
 13777                              <1> LD_ROOTBegin equ 100
 13778                              <1> LD_DATABegin equ 104
 13779                              <1> LD_StartSector equ 108
 13780                              <1> LD_TotalSectors equ 112
 13781                              <1> LD_FreeSectors equ 116
 13782                              <1> LD_Clusters equ 120
 13783                              <1> LD_PartitionEntry equ 124
 13784                              <1> LD_DParamEntry equ 125
 13785                              <1> LD_MediaChanged equ 126
 13786                              <1> LD_CDirLevel equ 127
 13787                              <1> LD_CurrentDirectory equ 128
 13788                              <1> 
 13789                              <1> ; Singlix FS Extensions to DOS Logical Disks
 13790                              <1> ; 03/01/2010 (LD_BPB compatibility for CHS r/w)
 13791                              <1> 
 13792                              <1> LD_FS_Name equ 0
 13793                              <1> LD_FS_DiskType equ 1
 13794                              <1> LD_FS_PhyDrvNo equ 2
 13795                              <1> LD_FS_FATType equ 3
 13796                              <1> LD_FS_FSType equ 4
 13797                              <1> LD_FS_LBAYes equ 5
 13798                              <1> LD_FS_BPB equ 6
 13799                              <1> LD_FS_MediaAttrib equ 6
 13800                              <1> LD_FS_VersionMajor equ 7
 13801                              <1> LD_FS_RootDirD equ 8
 13802                              <1> LD_FS_MATLocation equ 12
 13803                              <1> LD_FS_Reserved1 equ 16 ;1 reserved byte
 13804                              <1> LD_FS_BytesPerSec equ 17 ; LD_BPB + 0Bh
 13805                              <1> LD_FS_Reserved2 equ 19 ;2 reserved byte
 13806                              <1> LD_FS_DATLocation equ 20
 13807                              <1> LD_FS_DATSectors equ 24
 13808                              <1> LD_FS_Reserved3 equ 28 ;3 reserved word
 13809                              <1> LD_FS_SecPerTrack equ 30 ; LD_BPB + 18h
 13810                              <1> LD_FS_NumHeads equ 32    ; LD_BPB + 1Ah
 13811                              <1> LD_FS_UnDelDirD equ 34
 13812                              <1> LD_FS_Reserved4 equ 38 ;4 reserved word
 13813                              <1> LD_FS_VolumeSerial equ 40
 13814                              <1> LD_FS_VolumeName equ 44
 13815                              <1> LD_FS_BeginSector equ 108
 13816                              <1> LD_FS_VolumeSize equ 112
 13817                              <1> LD_FS_FreeSectors equ 116
 13818                              <1> LD_FS_FirstFreeSector equ 120
 13819                              <1> LD_FS_PartitionEntry equ 124
 13820                              <1> LD_FS_DParamEntry equ 125
 13821                              <1> LD_FS_MediaChanged equ 126
 13822                              <1> LD_FS_CDirLevel equ 127
 13823                              <1> LD_FS_CDIR_Converted equ 128
 13824                              <1> 
 13825                              <1> ; Valid FAT Types
 13826                              <1> FS_FAT12 equ 1
 13827                              <1> FS_FAT16_CHS equ 2
 13828                              <1> FS_FAT32_CHS equ 3
 13829                              <1> FS_FAT16_LBA equ 4
 13830                              <1> FS_FAT32_LBA equ 5
 13831                              <1> 
 13832                              <1> ; Cursor Location
 13833                              <1> CCCpointer equ  0450h   ; BIOS data, current cursor column
 13834                              <1> ; FAT Clusters EOC sign
 13835                              <1> FAT12EOC equ 0FFFh
 13836                              <1> FAT16EOC equ 0FFFFh
 13837                              <1> ;FAT32EOC equ 0FFFFFFFh ; It is not direct usable for 8086 code
 13838                              <1> ; BAD Cluster
 13839                              <1> FAT12BADC equ 0FF7h
 13840                              <1> FAT16BADC equ 0FFF7h
 13841                              <1> ;FAT32BADC equ 0FFFFFF7h ; It is not direct usable for 8086 code
 13842                              <1> ; MS-DOS FAT16 FS (Maximum Possible) Last Cluster Number= 0FFF6h 
 13843                              <1> 
 13844                              <1> ; TRFS
 13845                              <1> 
 13846                              <1> bs_FS_JmpBoot equ 0 ; jmp short bsBootCode
 13847                              <1>                 ; db 0EBh, db 3Fh, db 90h
 13848                              <1> bs_FS_Identifier equ 3  ; db 'FS', db 0
 13849                              <1> bs_FS_BytesPerSec equ 6 ; dw 512
 13850                              <1> bs_FS_MediaAttrib equ 8 ; db 3
 13851                              <1> bs_FS_PartitionID equ 9 ; db 0A1h
 13852                              <1> bs_FS_VersionMaj equ 10 ; db 01h
 13853                              <1> bs_FS_VersionMin equ 11 ; db 0
 13854                              <1> bs_FS_BeginSector equ 12   ; dd 0 
 13855                              <1> bs_FS_VolumeSize equ 16 ; dd 2880
 13856                              <1> bs_FS_StartupFD equ 20 ; dd 0
 13857                              <1> bs_FS_MATLocation equ 24 ; dd 1
 13858                              <1> bs_FS_RootDirD equ 28 ; dd 8
 13859                              <1> bs_FS_SystemConfFD equ 32 ; dd 0
 13860                              <1> bs_FS_SwapFD equ 36 ; dd 0
 13861                              <1> bs_FS_UnDelDirD equ 40 ; dd 0
 13862                              <1> bs_FS_DriveNumber equ 44 ; db 0
 13863                              <1> bs_FS_LBA_Ready equ 45 ; db 0
 13864                              <1> bs_FS_MagicWord equ 46 
 13865                              <1> bs_FS_SecPerTrack equ 46 ; db 0A1h
 13866                              <1> bs_FS_Heads equ 47 ; db 01h 
 13867                              <1> bs_FS_OperationSys equ 48 ; db "TR-SINGLIX v1.0b"
 13868                              <1> bs_FS_Terminator equ 64 ; db 0
 13869                              <1> bs_FS_BootCode equ 65 
 13870                              <1> 
 13871                              <1> FS_MAT_DATLocation equ 12
 13872                              <1> FS_MAT_DATScount equ 16
 13873                              <1> FS_MAT_FreeSectors equ 20
 13874                              <1> FS_MAT_FirstFreeSector equ 24
 13875                              <1> FS_RDT_VolumeSerialNo equ 28
 13876                              <1> FS_RDT_VolumeName equ 64
 13877                              <1> 
 13878                              <1> ; FAT12 + FAT16 + FAT32
 13879                              <1> BS_JmpBoot equ 0
 13880                              <1> BS_OEMName equ 3
 13881                              <1> BPB_BytsPerSec equ 11
 13882                              <1> BPB_SecPerClust equ 13
 13883                              <1> BPB_RsvdSecCnt equ 14
 13884                              <1> BPB_NumFATs equ 16
 13885                              <1> BPB_RootEntCnt equ 17
 13886                              <1> BPB_TotalSec16 equ 19
 13887                              <1> BPB_Media equ 21
 13888                              <1> BPB_FATSz16 equ 22
 13889                              <1> BPB_SecPerTrk equ 24
 13890                              <1> BPB_NumHeads equ 26
 13891                              <1> BPB_HiddSec equ 28
 13892                              <1> BPB_TotalSec32 equ 32
 13893                              <1> 
 13894                              <1> ; FAT12 and FAT16 only
 13895                              <1> BS_DrvNum equ 36
 13896                              <1> BS_Reserved1 equ 37
 13897                              <1> BS_BootSig equ 38
 13898                              <1> BS_VolID equ 39
 13899                              <1> BS_VolLab equ 43
 13900                              <1> BS_FilSysType equ 54 ; 8 bytes
 13901                              <1> BS_BootCode equ 62
 13902                              <1> 
 13903                              <1> ; FAT32 only
 13904                              <1> BPB_FATSz32 equ 36 ; FAT32, 4 bytes
 13905                              <1> BPB_ExtFlags equ 40 ; FAT32, 2 bytes
 13906                              <1> BPB_FSVer equ 42 ; FAT32, 2 bytes
 13907                              <1> BPB_RootClus equ 44 ; FAT32, 4 bytes
 13908                              <1> BPB_FSInfo equ 48 ; FAT 32, 2 bytes 
 13909                              <1> BPB_BkBootSec equ 50 ; FAT32, 2 bytes
 13910                              <1> BPB_Reserved equ 52 ; FAT32, 12 bytes
 13911                              <1> BS_FAT32_DrvNum equ 64 ; FAT32, 1 byte
 13912                              <1> BS_FAT32_Reserved1 equ 65 ; FAT32, 1 byte
 13913                              <1> BS_FAT32_BootSig equ 66 ; FAT32, 1 byte
 13914                              <1> BS_FAT32_VolID equ 67 ; FAT32, 4 bytes
 13915                              <1> BS_FAT32_VolLab equ 71 ; FAT32, 11 bytes
 13916                              <1> BS_FAT32_FilSysType equ 82 ; FAT32, 8 bytes
 13917                              <1> BS_FAT32_BootCode equ 90
 13918                              <1> 
 13919                              <1> BS_Validation equ 510
 13920                                  %include 'trdosk1.s' ; 04/01/2016 
 13921                              <1> ; ****************************************************************************
 13922                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - SYS INIT : trdosk1.s
 13923                              <1> ; ----------------------------------------------------------------------------
 13924                              <1> ; Last Update: 30/01/2016
 13925                              <1> ; ----------------------------------------------------------------------------
 13926                              <1> ; Beginning: 04/01/2016
 13927                              <1> ; ----------------------------------------------------------------------------
 13928                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 13929                              <1> ; ----------------------------------------------------------------------------
 13930                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 13931                              <1> ; TRDOS2.ASM (09/11/2011)
 13932                              <1> ; ****************************************************************************
 13933                              <1> ; TRDOS2.ASM (c) 2004-2011 Erdogan TAN [ 17/01/2004 ] Last Update: 09/11/2011
 13934                              <1> ;
 13935                              <1> 
 13936                              <1> sys_init:
 13937                              <1> 	; 24/01/2016
 13938                              <1> 	; 06/01/2016
 13939                              <1> 	; 04/01/2016
 13940                              <1> 
 13941 00003C09 B83F3A2F00          <1> 	mov	eax, '?:/'
 13942 00003C0E A3[8F790000]        <1> 	mov	[Current_Dir_Drv], eax
 13943                              <1> 
 13944                              <1> 	; Logical DRV INIT (only for hard disks)
 13945 00003C13 E854010000          <1> 	call 	ldrv_init  ; trdosk2.s
 13946                              <1> 	
 13947                              <1> 	; When floppy_drv_init call is disabled
 13948                              <1> 	; media changed sign is needed
 13949                              <1> 	; for proper drive initialization
 13950                              <1>         
 13951 00003C18 BE00010900          <1> 	mov 	esi, Logical_DOSDisks
 13952 00003C1D B001                <1> 	mov 	al, 1 ; Initialization sign (invalid_fd_parameter)
 13953 00003C1F 83C67E              <1> 	add 	esi, LD_MediaChanged ; Media Change Status = 1 (init needed)
 13954 00003C22 8806                <1> 	mov 	[esi], al ; A:
 13955 00003C24 81C600010000        <1> 	add 	esi, 100h 
 13956 00003C2A 8806                <1> 	mov 	[esi], al ; B: 
 13957                              <1>            
 13958                              <1> _current_drive_bootdisk:
 13959 00003C2C 8A15[AA750000]      <1> 	mov 	dl, [boot_drv] ; physical drive number
 13960 00003C32 80FAFF              <1> 	cmp 	dl, 0FFh
 13961 00003C35 740A                <1> 	je 	short _last_dos_diskno_check
 13962                              <1> _boot_drive_check:
 13963 00003C37 80FA80              <1> 	cmp 	dl, 80h
 13964 00003C3A 7218                <1> 	jb 	short _current_drive_a
 13965 00003C3C 80EA7E              <1> 	sub 	dl, 7Eh ; C = 2 , D = 3
 13966 00003C3F EB13                <1> 	jmp 	short _current_drive_a 
 13967                              <1> 
 13968                              <1> _last_dos_diskno_check:
 13969 00003C41 8A15[407F0000]      <1> 	mov 	dl, [Last_DOS_DiskNo]
 13970 00003C47 80FA02              <1> 	cmp 	dl, 2
 13971 00003C4A 7706                <1> 	ja 	short _current_drive_c
 13972 00003C4C 7406                <1> 	je 	short _current_drive_a
 13973 00003C4E 30D2                <1> 	xor 	dl, dl ; A:
 13974 00003C50 EB02                <1> 	jmp 	short _current_drive_a
 13975                              <1> 
 13976                              <1> _current_drive_c:
 13977 00003C52 B202                <1> 	mov 	dl, 2 ; C:
 13978                              <1> 
 13979                              <1> _current_drive_a:
 13980 00003C54 8815[AB750000]      <1> 	mov	[drv], dl
 13981 00003C5A BE[A76D0000]        <1>         mov     esi, msg_CRLF_temp
 13982 00003C5F E840000000          <1> 	call 	print_msg
 13983                              <1> 
 13984 00003C64 8A15[AB750000]      <1> 	mov	dl, [drv]
 13985 00003C6A E810090000          <1> 	call 	change_current_drive
 13986 00003C6F 730C                <1> 	jnc 	short _start_mainprog
 13987                              <1> 
 13988                              <1> _drv_not_ready_error: 
 13989 00003C71 BE[36760000]        <1> 	mov 	esi, msgl_drv_not_ready
 13990 00003C76 E829000000          <1> 	call 	print_msg
 13991 00003C7B EB05                <1> 	jmp 	short _end_of_mainprog
 13992                              <1> 
 13993                              <1> _start_mainprog:
 13994 00003C7D E8390A0000          <1>         call    dos_prompt
 13995                              <1>               
 13996                              <1> _end_of_mainprog:
 13997 00003C82 BE[A76D0000]        <1>         mov     esi, msg_CRLF_temp
 13998 00003C87 E818000000          <1> 	call 	print_msg
 13999 00003C8C BE[AD6D0000]        <1> 	mov 	esi, mainprog_Version
 14000 00003C91 E80E000000          <1> 	call 	print_msg
 14001                              <1> 	; 24/01/2016
 14002 00003C96 28E4                <1> 	sub	ah, ah
 14003 00003C98 E8BDCFFFFF          <1> 	call	int16h ; call getch
 14004 00003C9D E97AD4FFFF          <1> 	jmp	cpu_reset
 14005                              <1> 
 14006 00003CA2 EBFE                <1> infinitiveloop: jmp short infinitiveloop
 14007                              <1> 
 14008                              <1> 
 14009                              <1> print_msg:
 14010                              <1> 	; 04/01/2016
 14011                              <1> 	; 01/07/2015
 14012                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 14013                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 14014                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
 14015                              <1> 	;
 14016 00003CA4 AC                  <1> 	lodsb
 14017                              <1> pmsg1:
 14018 00003CA5 56                  <1> 	push 	esi
 14019 00003CA6 0FB61D[F8780000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; 04/01/2016 (ptty)
 14020 00003CAD B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
 14021 00003CAF E875DBFFFF          <1> 	call 	WRITE_TTY
 14022 00003CB4 5E                  <1> 	pop	esi
 14023 00003CB5 AC                  <1> 	lodsb
 14024 00003CB6 20C0                <1> 	and 	al, al
 14025 00003CB8 75EB                <1> 	jnz 	short pmsg1
 14026 00003CBA C3                  <1> 	retn
 14027                              <1> 
 14028                              <1> clear_screen:
 14029                              <1> 	; 30/01/2016
 14030                              <1> 	; 24/01/2016
 14031                              <1> 	; 04/01/2016
 14032 00003CBB 0FB61D[F8780000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; video page number (0 to 7)
 14033 00003CC2 8AA3[F0720000]      <1> 	mov 	ah, [ebx+vmode] ; default = 03h (80x25 text)
 14034 00003CC8 80FC04              <1> 	cmp	ah, 4
 14035 00003CCB 7205                <1> 	jb	short cls1
 14036 00003CCD 80FC07              <1> 	cmp	ah, 7
 14037 00003CD0 7524                <1> 	jne	short vga_clear
 14038                              <1> cls1:
 14039 00003CD2 3A25[D6720000]      <1> 	cmp	ah, [CRT_MODE] ; current video mode ? 
 14040                              <1> 	;je	short cls2 ; yes (current video mode = 3)
 14041                              <1> 	;;call	set_mode_3 ; set video mode to 3 (& clear screen)
 14042                              <1> 	;;retn
 14043                              <1> 	;jmp	set_mode_3
 14044 00003CD8 0F855DD8FFFF        <1> 	jne	set_mode_3
 14045                              <1> cls2:
 14046 00003CDE B407                <1> 	mov	ah, 07h ; attribute to be used on blanked line
 14047 00003CE0 28C0                <1> 	sub 	al, al ; 0 =  entire window
 14048 00003CE2 6631C9              <1> 	xor 	cx, cx
 14049 00003CE5 66BA4F18            <1> 	mov 	dx, 184Fh
 14050 00003CE9 E891D9FFFF          <1> 	call	_scroll_up ; 24/01/2016
 14051                              <1> 	;
 14052                              <1> 	;mov	bl, [ACTIVE_PAGE] ; video page number (0 to 7)
 14053 00003CEE 6631D2              <1> 	xor 	dx, dx
 14054 00003CF1 E8C7DBFFFF          <1> 	call	_set_cpos ; 24/01/2016 
 14055                              <1> 	;retn
 14056                              <1> vga_clear:
 14057 00003CF6 C3                  <1> 	retn	
 14058                              <1> 
 14059                              <1> panic:
 14060                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 14061                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 14062 00003CF7 BE[2B750000]        <1> 	mov 	esi, panic_msg
 14063 00003CFC E8A3FFFFFF          <1> 	call 	print_msg
 14064                              <1> key_to_reboot:
 14065                              <1>         ; 24/01/2016
 14066 00003D01 28E4                <1>         sub     ah, ah
 14067 00003D03 E852CFFFFF          <1>         call    int16h ; call   getch
 14068                              <1>         ; wait for a character from the current tty
 14069                              <1> 	;
 14070 00003D08 B00A                <1> 	mov	al, 0Ah
 14071 00003D0A 8A1D[F8780000]      <1> 	mov	bl, [ptty] ; [ACTIVE_PAGE]
 14072 00003D10 B407                <1> 	mov	ah, 07h ; Black background, 
 14073                              <1> 			; light gray forecolor
 14074 00003D12 E812DBFFFF          <1> 	call 	WRITE_TTY
 14075 00003D17 E900D4FFFF          <1> 	jmp	cpu_reset 
 14076                              <1> 
 14077                              <1> ctrlbrk:
 14078                              <1> 	; 12/11/2015
 14079                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 14080                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
 14081                              <1> 	;
 14082                              <1> 	; INT 1Bh (control+break) handler		
 14083                              <1> 	;
 14084                              <1>       	; Retro Unix 8086 v1 feature only!
 14085                              <1>       	;
 14086 00003D1C 66833D[9C850000]00  <1> 	cmp 	word [u.intr], 0
 14087 00003D24 7645                <1> 	jna 	short cbrk4
 14088                              <1> cbrk0:
 14089                              <1> 	; 12/11/2015
 14090                              <1> 	; 06/12/2013
 14091 00003D26 66833D[9E850000]00  <1> 	cmp 	word [u.quit], 0
 14092 00003D2E 743B                <1> 	jz	short cbrk4
 14093                              <1> 	;
 14094                              <1> 	; 20/09/2013	
 14095 00003D30 6650                <1> 	push 	ax
 14096 00003D32 A0[F8780000]        <1> 	mov	al, [ptty]
 14097                              <1> 	;
 14098                              <1> 	; 12/11/2015
 14099                              <1> 	;
 14100                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
 14101                              <1> 	; or ctrl+break from console (pseudo) tty
 14102                              <1> 	; (!redirection!)
 14103                              <1> 	;
 14104 00003D37 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
 14105 00003D39 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
 14106                              <1> 	;	
 14107                              <1> 	; Serial port interrupt handler sets [ptty]
 14108                              <1> 	; to the port's tty number (as temporary).
 14109                              <1> 	;
 14110                              <1> 	; If active process is using a stdin or 
 14111                              <1> 	; stdout redirection (by the shell),
 14112                              <1>         ; console tty keyboard must be available
 14113                              <1> 	; to terminate running process,
 14114                              <1> 	; in order to prevent a deadlock. 
 14115                              <1> 	;
 14116 00003D3B 52                  <1> 	push	edx
 14117 00003D3C 0FB615[A7850000]    <1> 	movzx	edx, byte [u.uno]
 14118 00003D43 3A82[AB820000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
 14119 00003D49 5A                  <1> 	pop	edx
 14120 00003D4A 7412                <1> 	je	short cbrk2
 14121                              <1> cbrk1:
 14122 00003D4C FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
 14123                              <1> 	; 06/12/2013
 14124 00003D4E 3A05[88850000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
 14125 00003D54 7408                <1> 	je	short cbrk2	
 14126 00003D56 3A05[89850000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
 14127 00003D5C 750B                <1> 	jne	short cbrk3	
 14128                              <1> cbrk2:
 14129                              <1> 	;; 06/12/2013
 14130                              <1> 	;mov	ax, [u.quit]
 14131                              <1> 	;and	ax, ax
 14132                              <1> 	;jz	short cbrk3
 14133                              <1> 	;
 14134 00003D5E 6631C0              <1> 	xor	ax, ax ; 0
 14135 00003D61 6648                <1> 	dec	ax
 14136                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
 14137 00003D63 66A3[9E850000]      <1> 	mov	[u.quit], ax
 14138                              <1> cbrk3:
 14139 00003D69 6658                <1> 	pop	ax
 14140                              <1> cbrk4:
 14141 00003D6B C3                  <1> 	retn
 14142                                  %include 'trdosk2.s' ; 04/01/2016
 14143                              <1> ; ****************************************************************************
 14144                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - DRV INIT : trdosk2.s
 14145                              <1> ; ----------------------------------------------------------------------------
 14146                              <1> ; Last Update: 02/02/2016
 14147                              <1> ; ----------------------------------------------------------------------------
 14148                              <1> ; Beginning: 04/01/2016
 14149                              <1> ; ----------------------------------------------------------------------------
 14150                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 14151                              <1> ; ----------------------------------------------------------------------------
 14152                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 14153                              <1> ; TRDOS2.ASM (09/11/2011)
 14154                              <1> ; ****************************************************************************
 14155                              <1> ; DRV_INIT.ASM (c) 2009-2011 Erdogan TAN  [26/09/2009] Last Update: 07/08/2011
 14156                              <1> ;
 14157                              <1> 
 14158                              <1> ldrv_init: ; Logical Drive Initialization
 14159                              <1> 	; 06/01/2016
 14160                              <1> 	;  	('diskinit.inc', 'diskio.inc' integration)
 14161                              <1> 	; 04/01/2016 (TRDOS 386 = TRDOS v2.0)
 14162                              <1> 	; 07/08/2011
 14163                              <1> 	; 20/09/2009
 14164                              <1> 	; 2005
 14165 00003D6C 0FB60D[68790000]    <1> 	movzx	ecx, byte [HF_NUM] ; number of fixed disks
 14166 00003D73 80F901              <1> 	cmp	cl, 1
 14167 00003D76 7301                <1> 	jnb	short load_hd_partition_tables
 14168                              <1> 	; No hard disks
 14169 00003D78 C3                  <1> 	retn
 14170                              <1> load_hd_partition_tables:
 14171 00003D79 8B35[6C790000]      <1> 	mov	esi, [HDPM_TBL_VEC] ; primary master disk FDPT
 14172 00003D7F BF[407D0000]        <1> 	mov 	edi, PTable_hd0
 14173 00003D84 B280                <1> 	mov 	dl, 80h
 14174                              <1> load_next_hd_partition_table:
 14175 00003D86 51                  <1> 	push	ecx
 14176 00003D87 57                  <1> 	push	edi
 14177 00003D88 56                  <1> 	push	esi ; FDPT (+ DPTE) address
 14178 00003D89 8A4614              <1> 	mov	al, [esi+20] ; DPTE offset 4
 14179 00003D8C 2440                <1> 	and	al, 40h ;  LBA bit (bit 6)
 14180                              <1> 	;shr	al, 6
 14181 00003D8E A2[417F0000]        <1> 	mov 	byte [HD_LBA_yes], al
 14182 00003D93 E814040000          <1> 	call	load_masterboot
 14183 00003D98 7274                <1> 	jc	short pass_pt_this_hard_disk
 14184 00003D9A BE[FE7C0000]        <1> 	mov	esi, PartitionTable
 14185 00003D9F 89F3                <1> 	mov	ebx, esi
 14186                              <1> 	;mov	ecx, 16
 14187 00003DA1 B110                <1> 	mov	cl, 16
 14188 00003DA3 F3A5                <1> 	rep 	movsd
 14189 00003DA5 89DE                <1> 	mov 	esi, ebx 
 14190 00003DA7 C605[AD750000]04    <1> 	mov 	byte [hdc], 4 ; 4 - partition index
 14191                              <1> loc_validate_hdp_partition:
 14192 00003DAE 807E0400            <1> 	cmp 	byte [esi+ptFileSystemID], 0
 14193 00003DB2 7640                <1> 	jna	short loc_validate_next_hdp_partition2
 14194 00003DB4 56                  <1> 	push	esi ; Masterboot partition table offset
 14195 00003DB5 52                  <1> 	push	edx ; dl = Physical drive number 
 14196 00003DB6 FE05[427F0000]      <1> 	inc	byte [PP_Counter]
 14197 00003DBC 31FF                <1>         xor	edi, edi ; 0  
 14198                              <1> 	; Input -> ESI = PartitionTable offset
 14199                              <1> 	; DL = Hard disk drive number 
 14200                              <1> 	; EDI = 0 -> Primary Partition
 14201                              <1> 	; EDI > 0 -> Extended Partition's Start Sector   
 14202 00003DBE E878010000          <1> 	call 	validate_hd_fat_partition
 14203 00003DC3 7309                <1> 	jnc 	short loc_set_valid_hdp_partition_entry
 14204 00003DC5 5A                  <1> 	pop	edx
 14205 00003DC6 52                  <1> 	push	edx 
 14206 00003DC7 E8C3020000          <1> 	call	validate_hd_fs_partition
 14207 00003DCC 7224                <1> 	jc	short loc_validate_next_hdp_partition1
 14208                              <1> loc_set_valid_hdp_partition_entry:
 14209 00003DCE 8A0D[407F0000]      <1> 	mov 	cl, [Last_DOS_DiskNo] 
 14210 00003DD4 80C141              <1> 	add 	cl, 'A'
 14211                              <1> 	; ESI = Logical dos drive description table address
 14212 00003DD7 880E                <1> 	mov	[esi+LD_Name], cl
 14213 00003DD9 8A6602              <1> 	mov	ah, [esi+LD_PhyDrvNo]
 14214 00003DDC 88E0                <1> 	mov	al, ah ; Physical drive number
 14215 00003DDE 2C80                <1> 	sub	al, 80h
 14216 00003DE0 C0E002              <1> 	shl	al, 2
 14217 00003DE3 0404                <1> 	add	al, 4 ; 0 Based
 14218 00003DE5 2A05[AD750000]      <1> 	sub	al, [hdc] ; 4 - partition index
 14219                              <1> 	; AL = Partition entry/index, 0 based
 14220                              <1> 	;  0 -> hd 0, Partition Table offset = 0
 14221                              <1> 	; 15 -> hd 3, Partition Table offset = 3
 14222                              <1> 	;mov	[esi+LD_PartitionEntry], al 
 14223 00003DEB 80EC7E              <1> 	sub 	ah, 7Eh
 14224                              <1> 	; AH = Physical drive index, zero based
 14225                              <1> 	;  0 for drive A:, 2 for drive C:
 14226                              <1> 	;mov 	[esi+LD_DParamEntry], ah 
 14227 00003DEE 6689467C            <1> 	mov 	[esi+LD_PartitionEntry], ax
 14228                              <1> loc_validate_next_hdp_partition1:
 14229 00003DF2 5A                  <1> 	pop 	edx ; dl = Physical drive number 
 14230 00003DF3 5E                  <1> 	pop	esi ; Masterboot partition table offset
 14231                              <1> loc_validate_next_hdp_partition2:
 14232                              <1> 	; ESI = PartitionTable offset
 14233                              <1> 	; DL = Hard/Fixed disk drive number
 14234 00003DF4 FE0D[AD750000]      <1> 	dec	byte [hdc] ; 4 - partition index
 14235 00003DFA 7412                <1> 	jz	short pass_pt_this_hard_disk
 14236 00003DFC 83C610              <1> 	add	esi, 16 ; 10h
 14237 00003DFF EBAD                <1> 	jmp	short loc_validate_hdp_partition
 14238                              <1> loc_next_hd_partition_table:
 14239 00003E01 FEC2                <1> 	inc	dl
 14240 00003E03 83C620              <1> 	add	esi, 32 ; next FDPT address
 14241 00003E06 83C740              <1> 	add	edi, 64 ; next partition table destination
 14242 00003E09 E978FFFFFF          <1>         jmp     load_next_hd_partition_table
 14243                              <1> pass_pt_this_hard_disk:
 14244 00003E0E 5E                  <1> 	pop	esi ; FDPT (+ DPTE) address
 14245 00003E0F 5F                  <1> 	pop	edi ; Ptable_hd?
 14246 00003E10 59                  <1> 	pop	ecx
 14247 00003E11 E2EE                <1> 	loop	loc_next_hd_partition_table
 14248 00003E13 803D[427F0000]01    <1> 	cmp	byte [PP_Counter], 1
 14249 00003E1A 7301                <1> 	jnb	short load_extended_dos_partitions
 14250                              <1> 	; Empty partition table
 14251 00003E1C C3                  <1> 	retn 
 14252                              <1> load_extended_dos_partitions:
 14253 00003E1D BE[407D0000]        <1> 	mov	esi, PTable_hd0
 14254 00003E22 BF[407E0000]        <1> 	mov	edi, PTable_ep0
 14255 00003E27 C605[AD750000]80    <1> 	mov	byte [hdc], 80h
 14256                              <1> next_hd_extd_partition:
 14257 00003E2E 56                  <1> 	push	esi ; PTable_hd? offset
 14258 00003E2F 57                  <1> 	push	edi ; PTable_ep?
 14259                              <1> 	;mov	ecx, 4
 14260 00003E30 B104                <1> 	mov	cl, 4
 14261 00003E32 8A15[AD750000]      <1> 	mov	dl, byte [hdc]
 14262                              <1> hd_check_fs_id_05h:
 14263 00003E38 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
 14264 00003E3B 3C05                <1> 	cmp	al, 05h ; Is it an extended dos partition ?
 14265 00003E3D 7404                <1> 	je	short loc_set_ep_start_sector
 14266 00003E3F 3C0F                <1> 	cmp	al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
 14267 00003E41 7546                <1> 	jne	short continue_to_check_ep
 14268                              <1> loc_set_ep_start_sector:
 14269 00003E43 FE05[437F0000]      <1> 	inc	byte [EP_Counter]
 14270 00003E49 88D4                <1> 	mov	ah, dl ; byte [hdc]
 14271 00003E4B 86E0                <1> 	xchg	ah, al ; al = Drv Number, ah = Partition Identifier
 14272 00003E4D 50                  <1> 	push	eax 
 14273 00003E4E 30E4                <1> 	xor	ah, ah  
 14274 00003E50 2C80                <1> 	sub	al, 80h
 14275 00003E52 50                  <1> 	push	eax
 14276 00003E53 C0E002              <1> 	shl	al, 2 ; al = al * 4
 14277 00003E56 0FB6D8              <1> 	movzx	ebx, al
 14278 00003E59 81C3[447F0000]      <1> 	add	ebx, EP_StartSector
 14279 00003E5F 8B4608              <1> 	mov	eax, [esi+ptStartSector]
 14280                              <1>         ; EAX = Extended partition's start sector
 14281 00003E62 8903                <1>         mov	[ebx], eax
 14282 00003E64 58                  <1> 	pop	eax ; AL = Drv number - 80h, AH = 0 
 14283 00003E65 5A                  <1> 	pop	edx ; DL = Drv number, DH = Partition ID
 14284 00003E66 BB[407B0000]        <1> 	mov	ebx, MasterBootBuff
 14285 00003E6B 803D[417F0000]01    <1> 	cmp	byte [HD_LBA_yes], 1 ; LBA ready = Yes
 14286 00003E72 7240                <1> 	jb	short loc_hd_load_ep_05h
 14287 00003E74 80FE05              <1> 	cmp	dh, 05h
 14288 00003E77 743B                <1> 	je	short loc_hd_load_ep_05h
 14289                              <1> loc_hd_load_ep_0Fh:
 14290                              <1> 	; 04/01/2016
 14291 00003E79 51                  <1> 	push	ecx
 14292 00003E7A 8B4E08              <1> 	mov	ecx, [esi+ptStartSector] ; sector number
 14293                              <1> 	;mov	ebx, MasterBootBuff ; buffer address
 14294                              <1> 	; LBA read/write (with private LBA function) 
 14295                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 14296                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
 14297 00003E7D B41B                <1> 	mov	ah, 1Bh ; LBA read
 14298 00003E7F B001                <1> 	mov	al, 1 ; sector count
 14299 00003E81 E8B7EAFFFF          <1> 	call	int13h
 14300 00003E86 59                  <1> 	pop	ecx
 14301 00003E87 733F                <1> 	jnc	short loc_hd_move_ep_table
 14302                              <1> continue_to_check_ep:
 14303 00003E89 83C610              <1> 	add	esi, 16
 14304 00003E8C E2AA                <1> 	loop	hd_check_fs_id_05h
 14305                              <1> continue_check_ep_next_disk:
 14306 00003E8E 5F                  <1> 	pop	edi ; PTable_ep?
 14307 00003E8F 5E                  <1> 	pop	esi ; PTable_hd?
 14308 00003E90 A0[68790000]        <1> 	mov	al, [HF_NUM] ; number of hard disks
 14309 00003E95 047F                <1> 	add	al, 7Fh
 14310 00003E97 3805[AD750000]      <1> 	cmp	[hdc], al
 14311 00003E9D 0F8392000000        <1> 	jnb	loc_validating_hd_partitions_ok
 14312 00003EA3 83C640              <1> 	add	esi, 64
 14313 00003EA6 83C740              <1> 	add	edi, 64
 14314 00003EA9 FE05[AD750000]      <1> 	inc	byte [hdc]
 14315 00003EAF E97AFFFFFF          <1> 	jmp	next_hd_extd_partition
 14316                              <1> loc_hd_load_ep_05h:
 14317 00003EB4 51                  <1> 	push	ecx 
 14318 00003EB5 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
 14319 00003EB8 668B4E02            <1>         mov     cx, word [esi+ptBeginSector]
 14320 00003EBC 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
 14321                              <1> 	;mov	ebx, MasterBootBuff
 14322 00003EC0 E878EAFFFF          <1> 	call	int13h
 14323 00003EC5 59                  <1> 	pop	ecx  
 14324 00003EC6 72C1                <1> 	jc	short continue_to_check_ep
 14325                              <1> loc_hd_move_ep_table:
 14326                              <1>         ;pop	edi
 14327                              <1> 	;push	edi  ; PTable_ep?
 14328 00003EC8 8B3C24              <1> 	mov	edi, [esp]        
 14329 00003ECB BE[FE7C0000]        <1>         mov	esi, PartitionTable ; Extended
 14330 00003ED0 89F3                <1> 	mov	ebx, esi
 14331                              <1> 	;mov	ecx, 16
 14332 00003ED2 B110                <1> 	mov	cl, 16
 14333 00003ED4 F3A5                <1>        	rep	movsd
 14334 00003ED6 89DE                <1> 	mov	esi, ebx 
 14335                              <1> loc_set_hde_sub_partition_count:
 14336 00003ED8 C605[427F0000]04    <1> 	mov	byte [PP_Counter], 4
 14337                              <1> loc_validate_hde_partition:
 14338 00003EDF 807E0400            <1> 	cmp	byte [esi+ptFileSystemID], 0
 14339 00003EE3 763F                <1> 	jna	short loc_validate_next_hde_partition2
 14340 00003EE5 56                  <1> 	push	esi ; Extended partition table offset
 14341 00003EE6 8A15[AD750000]      <1> 	mov	dl, byte [hdc]
 14342 00003EEC 0FB6C2              <1> 	movzx	eax, dl
 14343 00003EEF 2C80                <1> 	sub	al, 80h
 14344 00003EF1 C0E002              <1> 	shl	al, 2
 14345                              <1> 	; 06/01/2016 
 14346                              <1> 	; (TRDOS v1.0 had a bug here, in 'DRV_INIT.ASM')
 14347                              <1> 	; BUGFIX *
 14348                              <1> 	;mov	ecx, eax
 14349 00003EF4 88C1                <1> 	mov	cl, al
 14350 00003EF6 80C104              <1> 	add	cl, 4
 14351 00003EF9 2A0D[427F0000]      <1> 	sub	cl, [PP_Counter] ; 4 to 1
 14352                              <1> 	; CL = Partition entry/index, 0 based
 14353                              <1>         ;  0 -> hd 0, Partition Table offset = 0
 14354                              <1>         ; 15 -> hd 3, Partition Table offset = 3
 14355 00003EFF 88D5                <1>       	mov	ch, dl   
 14356 00003F01 80ED7E              <1> 	sub	ch, 7Eh ;
 14357                              <1> 	; CH = Physical drive index, zero based
 14358                              <1> 	;  0 for drive A:, 2 for drive C:	
 14359                              <1> 	; BUGFIX *
 14360 00003F04 51                  <1> 	push	ecx ; *
 14361 00003F05 BF[447F0000]        <1> 	mov	edi, EP_StartSector
 14362 00003F0A 01C7                <1> 	add	edi, eax
 14363                              <1> 	; Input -> ESI = PartitionTable offset
 14364                              <1> 	; DL = Hard disk drive number   
 14365                              <1> 	; EDI = Extended partition start sector pointer
 14366 00003F0C E82A000000          <1> 	call	validate_hd_fat_partition
 14367 00003F11 59                  <1> 	pop	ecx ; *
 14368 00003F12 720F                <1> 	jc	short loc_validate_next_hde_partition1
 14369                              <1> loc_set_valid_hde_partition_entry:
 14370                              <1> 	; 06/01/2016 (TRDOS v2.0)
 14371                              <1> 	; BUGFIX *
 14372                              <1> 	;mov	[esi+LD_PartitionEntry], cl 
 14373                              <1> 	;mov	[esi+LD_DParamEntry], ch 
 14374 00003F14 66894E7C            <1> 	mov	[esi+LD_PartitionEntry], cx 
 14375                              <1> 	;
 14376 00003F18 8A0D[407F0000]      <1> 	mov	cl, [Last_DOS_DiskNo] 
 14377 00003F1E 80C141              <1> 	add	cl, 'A'
 14378 00003F21 880E                <1> 	mov	[esi+LD_Name], cl
 14379                              <1> loc_validate_next_hde_partition1:
 14380 00003F23 5E                  <1> 	pop	esi ; Extended partition table offset
 14381                              <1> loc_validate_next_hde_partition2:
 14382                              <1> 	; ESI = Extended partition table offset
 14383                              <1> 	; DL = Hard disk drive number
 14384 00003F24 FE0D[427F0000]      <1> 	dec	byte [PP_Counter]
 14385 00003F2A 0F845EFFFFFF        <1> 	jz	continue_check_ep_next_disk
 14386 00003F30 83C610              <1> 	add 	esi, 16 ; 10h
 14387 00003F33 EBAA                <1> 	jmp	short loc_validate_hde_partition
 14388                              <1> loc_validating_hd_partitions_ok:
 14389 00003F35 A0[407F0000]        <1> 	mov	al, [Last_DOS_DiskNo]
 14390                              <1> loc_drv_init_retn:
 14391 00003F3A C3                  <1> 	retn
 14392                              <1> 
 14393                              <1> validate_hd_fat_partition:
 14394                              <1> 	; 07/01/2016 (TRDOS 386 = TRDOS v2.0)
 14395                              <1> 	; 07/08/2011
 14396                              <1> 	; 23/07/2011
 14397                              <1> 	; Input
 14398                              <1> 	;   DL = Hard/Fixed Disk Drive Number
 14399                              <1> 	;   ESI = PartitionTable offset
 14400                              <1> 	;   EDI = Extend. Part. Start Sector Pointer
 14401                              <1> 	;   EDI = 0 -> Primary Partition 
 14402                              <1> 	;   byte [Last_DOS_DiskNo]
 14403                              <1>  	; Output
 14404                              <1> 	;  cf=0 -> Validated
 14405                              <1> 	;   ESI = Logical dos drv desc. table
 14406                              <1> 	;   EBX = FAT boot sector buffer
 14407                              <1> 	;   byte [Last_DOS_DiskNo]
 14408                              <1> 	;  cf=1 -> Not a valid FAT partition
 14409                              <1> 	; EAX, EDX, ECX, EDI -> changed 
 14410                              <1> 	
 14411                              <1> 	;mov 	esi, PartitionTable
 14412 00003F3B 8A6604              <1> 	mov 	ah, [esi+ptFileSystemID]
 14413 00003F3E 80FC06              <1> 	cmp 	ah, 06h ; FAT16 CHS partition
 14414 00003F41 721A                <1>  	jb	short loc_not_a_valid_fat_partition2
 14415                              <1> 	;
 14416 00003F43 B002                <1> 	mov	al, 2
 14417 00003F45 7417                <1> 	je	short loc_set_valid_hd_partition_params
 14418 00003F47 80FC0E              <1> 	cmp	ah, 0Eh ; FAT16 LBA partition
 14419 00003F4A 7710                <1> 	ja	short loc_not_a_valid_fat_partition1
 14420 00003F4C 7410                <1> 	je	short loc_set_valid_hd_partition_params
 14421                              <1> 	;
 14422 00003F4E FEC0                <1> 	inc	al ; 3
 14423 00003F50 80FC0B              <1> 	cmp	ah, 0Bh ; FAT32 CHS partition 
 14424 00003F53 7409                <1> 	je	short loc_set_valid_hd_partition_params
 14425 00003F55 7206                <1> 	jb	short loc_not_a_valid_fat_partition2
 14426 00003F57 80FC0C              <1> 	cmp	ah, 0Ch ; FAT32 LBA partition
 14427 00003F5A 7402                <1> 	je	short loc_set_valid_hd_partition_params
 14428                              <1> loc_not_a_valid_fat_partition1:
 14429 00003F5C F9                  <1> 	stc
 14430                              <1> loc_not_a_valid_fat_partition2:
 14431 00003F5D C3                  <1> 	retn
 14432                              <1> 
 14433                              <1> loc_set_valid_hd_partition_params:
 14434 00003F5E FE05[407F0000]      <1> 	inc 	byte [Last_DOS_DiskNo] ; > 1
 14435                              <1> 	;
 14436 00003F64 31DB                <1> 	xor	ebx, ebx
 14437 00003F66 8A3D[407F0000]      <1> 	mov	bh, [Last_DOS_DiskNo] ; * 256	
 14438 00003F6C 81C300010900        <1> 	add	ebx, Logical_DOSDisks
 14439                              <1> 	;
 14440 00003F72 C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
 14441 00003F76 885302              <1> 	mov	byte [ebx+LD_PhyDrvNo], dl
 14442                              <1> 	;mov	byte [ebx+LD_FATType], al ; 2 or 3
 14443                              <1> 	;mov	byte [ebx+LD_FSType], ah ; 06h, 0Eh, 0Bh, 0Ch
 14444 00003F79 66894303            <1> 	mov	word [ebx+LD_FATType], ax
 14445                              <1> 	;
 14446 00003F7D 8B4608              <1> 	mov	eax, [esi+ptStartSector]
 14447 00003F80 09FF                <1> 	or	edi, edi 
 14448 00003F82 7402                <1> 	jz	short pass_hd_FAT_ep_start_sector_adding
 14449                              <1> loc_add_hd_FAT_ep_start_sector:
 14450 00003F84 0307                <1> 	add	eax, [edi]
 14451                              <1> pass_hd_FAT_ep_start_sector_adding:
 14452 00003F86 89436C              <1> 	mov	[ebx+LD_StartSector], eax
 14453                              <1> loc_hd_FAT_logical_drv_init:
 14454 00003F89 89DD                <1> 	mov	ebp, ebx
 14455                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
 14456 00003F8B A0[417F0000]        <1> 	mov	al, [HD_LBA_yes] ; 07/01/2016
 14457 00003F90 884305              <1> 	mov	[ebx+LD_LBAYes], al
 14458 00003F93 89DE                <1> 	mov	esi, ebx
 14459 00003F95 BB[547F0000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer address
 14460 00003F9A 08C0                <1> 	or	al, al
 14461 00003F9C 740F                <1> 	jz	short loc_hd_FAT_drv_init_load_bs_chs
 14462                              <1> loc_hd_FAT_drv_init_load_bs_lba:
 14463                              <1> 	; DL = Physical drive number
 14464                              <1> 	;mov	esi, ebx
 14465 00003F9E 8B4E08              <1>    	mov	ecx, [esi+ptStartSector] ; sector number
 14466                              <1> 	;mov	ebx, DOSBootSectorBuff ; buffer address
 14467                              <1> 	; LBA read/write (with private LBA function) 
 14468                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 14469                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
 14470 00003FA1 B41B                <1> 	mov	ah, 1Bh ; LBA read
 14471 00003FA3 B001                <1> 	mov	al, 1 ; sector count
 14472 00003FA5 E893E9FFFF          <1> 	call	int13h
 14473 00003FAA 7313                <1> 	jnc	short loc_hd_drv_FAT_boot_validation
 14474                              <1> loc_not_a_valid_fat_partition3:
 14475 00003FAC C3                  <1> 	retn
 14476                              <1> loc_hd_FAT_drv_init_load_bs_chs:
 14477 00003FAD 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
 14478 00003FB0 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
 14479 00003FB4 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
 14480                              <1> 	;mov	ebx, DOSBootSectorBuff
 14481 00003FB8 E880E9FFFF          <1> 	call	int13h
 14482 00003FBD 72ED                <1> 	jc	short loc_not_a_valid_fat_partition3
 14483                              <1> loc_hd_drv_FAT_boot_validation:
 14484                              <1> 	;mov	esi, DOSBootSectorBuff
 14485 00003FBF 89DE                <1> 	mov	esi, ebx
 14486 00003FC1 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
 14487 00003FCA 751A                <1> 	jne	short loc_not_a_valid_fat_partition4
 14488 00003FCC 807E15F8            <1> 	cmp	byte [esi+BPB_Media], 0F8h
 14489 00003FD0 7514                <1> 	jne	short loc_not_a_valid_fat_partition4
 14490 00003FD2 66837E1600          <1> 	cmp	word [esi+BPB_FATSz16], 0
 14491 00003FD7 770F                <1> 	ja	short loc_hd_FAT16_BPB
 14492 00003FD9 807E4229            <1> 	cmp	byte [esi+BS_FAT32_BootSig], 29h
 14493 00003FDD 7507                <1> 	jne	short loc_not_a_valid_fat_partition4
 14494                              <1> loc_hd_FAT32_BPB:
 14495 00003FDF B92D000000          <1> 	mov	ecx, 45
 14496 00003FE4 EB0D                <1> 	jmp	short loc_hd_move_FAT_BPB
 14497                              <1> 	;
 14498                              <1> loc_not_a_valid_fat_partition4:
 14499 00003FE6 F9                  <1> 	stc
 14500 00003FE7 C3                  <1> 	retn
 14501                              <1> 	;
 14502                              <1> loc_hd_FAT16_BPB:
 14503 00003FE8 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
 14504 00003FEC 75F8                <1> 	jne	short loc_not_a_valid_fat_partition4
 14505 00003FEE B920000000          <1> 	mov	ecx, 32
 14506                              <1> loc_hd_move_FAT_BPB:
 14507 00003FF3 89EF                <1> 	mov 	edi, ebp
 14508                              <1> 	;mov	esi, ebx ; Boot sector
 14509 00003FF5 57                  <1> 	push	edi
 14510 00003FF6 83C706              <1> 	add	edi, LD_BPB
 14511 00003FF9 F366A5              <1> 	rep	movsw 
 14512 00003FFC 5E                  <1> 	pop	esi
 14513 00003FFD 0FB74614            <1> 	movzx	eax, word [esi+LD_BPB+BPB_RsvdSecCnt]
 14514 00004001 03466C              <1> 	add	eax, [esi+LD_StartSector]
 14515 00004004 894660              <1> 	mov	[esi+LD_FATBegin], eax
 14516 00004007 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
 14517 0000400B 7224                <1> 	jb	short loc_set_FAT16_RootDirLoc
 14518                              <1> loc_set_FAT32_RootDirLoc:
 14519 0000400D 8B462A              <1> 	mov	eax, [esi+LD_BPB+BPB_FATSz32]
 14520 00004010 0FB65E16            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_NumFATs]
 14521 00004014 F7E3                <1> 	mul	ebx
 14522 00004016 034660              <1> 	add	eax, [esi+LD_FATBegin]
 14523                              <1> loc_set_FAT32_data_begin:
 14524 00004019 894668              <1> 	mov	[esi+LD_DATABegin], eax
 14525 0000401C 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
 14526                              <1> 	; If Root Directory Cluster <> 2 then
 14527                              <1> 	; change the beginning sector value 
 14528                              <1> 	; of the root dir by adding sector offset.
 14529 0000401F 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
 14530 00004022 83E802              <1> 	sub	eax, 2
 14531 00004025 7442                <1> 	jz	short short loc_set_32bit_FAT_total_sectors  
 14532                              <1> 	;movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
 14533 00004027 8A5E13              <1> 	mov	bl, byte [esi+LD_BPB+BPB_SecPerClust] 
 14534 0000402A F7E3                <1> 	mul	ebx
 14535 0000402C 014664              <1> 	add	[esi+LD_ROOTBegin], eax
 14536 0000402F EB38                <1> 	jmp	short loc_set_32bit_FAT_total_sectors
 14537                              <1> 	;
 14538                              <1> loc_set_FAT16_RootDirLoc:
 14539 00004031 0FB64616            <1> 	movzx	eax, byte [esi+LD_BPB+BPB_NumFATs]
 14540 00004035 0FB7561C            <1> 	movzx	edx, word [esi+LD_BPB+BPB_FATSz16]
 14541 00004039 F7E2                <1> 	mul	edx
 14542 0000403B 034660              <1> 	add	eax, [esi+LD_FATBegin]  
 14543 0000403E 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
 14544                              <1> loc_set_FAT16_data_begin:
 14545 00004041 894668              <1> 	mov	[esi+LD_DATABegin], eax 
 14546 00004044 B820000000          <1> 	mov	eax, 20h  ; Size of a directory entry
 14547                              <1> 	;movzx	edx, word [esi+LD_BPB+BPB_RootEntCnt]
 14548 00004049 668B5617            <1>         mov     dx, [esi+LD_BPB+BPB_RootEntCnt]
 14549 0000404D F7E2                <1>         mul	edx
 14550                              <1> 	;mov	ecx, 511
 14551 0000404F 66B9FF01            <1> 	mov	cx, 511
 14552 00004053 01C8                <1> 	add	eax, ecx
 14553 00004055 41                  <1> 	inc	ecx ; 512
 14554 00004056 F7F1                <1> 	div	ecx
 14555 00004058 014668              <1> 	add	[esi+LD_DATABegin], eax
 14556 0000405B 0FB74619            <1> 	movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
 14557 0000405F 6685C0              <1> 	test	ax, ax
 14558 00004062 7405                <1> 	jz	short loc_set_32bit_FAT_total_sectors
 14559                              <1> loc_set_16bit_FAT_total_sectors:
 14560 00004064 894670              <1> 	mov	[esi+LD_TotalSectors], eax
 14561 00004067 EB06                <1> 	jmp	short loc_set_hd_FAT_cluster_count
 14562                              <1> loc_set_32bit_FAT_total_sectors:
 14563 00004069 8B4626              <1> 	mov	eax, [esi+LD_BPB+BPB_TotalSec32]
 14564 0000406C 894670              <1> 	mov	[esi+LD_TotalSectors], eax
 14565                              <1> loc_set_hd_FAT_cluster_count:
 14566 0000406F 03466C              <1> 	add	eax, [esi+LD_StartSector]
 14567 00004072 2B4668              <1> 	sub	eax, [esi+LD_DATABegin]
 14568 00004075 29D2                <1> 	sub	edx, edx ; 0
 14569 00004077 0FB64E13            <1>         movzx   ecx, byte [esi+LD_BPB+BPB_SecPerClust]
 14570 0000407B F7F1                <1>         div	ecx 
 14571 0000407D 894678              <1> 	mov	[esi+LD_Clusters], eax
 14572                              <1> 	; Maximum Valid Cluster Number= EAX +1
 14573                              <1> 	; with 2 reserved clusters= EAX +2
 14574                              <1> loc_set_hd_FAT_fs_free_sectors:
 14575                              <1> 	;mov	dword [esi+LD_FreeSectors], 0
 14576 00004080 E854010000          <1> 	call	get_free_FAT_sectors
 14577 00004085 7207                <1> 	jc	short loc_validate_hd_FAT_partition_retn
 14578 00004087 894674              <1> 	mov	[esi+LD_FreeSectors], eax
 14579 0000408A C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6  ; Volume Name Reset
 14580                              <1> 	;mov	cl, [Last_DOS_DiskNo] 
 14581                              <1> 	;add	cl, 'A'
 14582                              <1> 	;mov	[esi+LD_FS_Name], cl
 14583                              <1> 
 14584                              <1> loc_validate_hd_FAT_partition_retn:         
 14585 0000408E C3                  <1> 	retn
 14586                              <1> 
 14587                              <1> validate_hd_fs_partition:
 14588                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
 14589                              <1> 	; 29/01/2011
 14590                              <1> 	; 23/07/2011
 14591                              <1> 	; Input
 14592                              <1> 	;   DL = Hard/Fixed Disk Drive Number
 14593                              <1> 	;   ESI = PartitionTable offset
 14594                              <1> 	;   byte [Last_DOS_DiskNo]
 14595                              <1> 	; Output
 14596                              <1> 	;  cf=0 -> Validated
 14597                              <1> 	;   ESI = Logical dos drv desc. table
 14598                              <1> 	;   EBX = Singlix FS boot sector buffer
 14599                              <1> 	;   byte [Last_DOS_DiskNo]
 14600                              <1> 	;  cf=1 -> Not a valid 'Singlix FS' partition
 14601                              <1> 	; EAX, EDX, ECX, EDI -> changed 
 14602                              <1> 
 14603                              <1> 	;mov	esi, PartitionTable
 14604 0000408F 8A6604              <1> 	mov	ah, [esi+ptFileSystemID]
 14605 00004092 80FCA1              <1> 	cmp	ah, 0A1h ; SINGLIX FS1 (trfs1) partition
 14606 00004095 7549                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
 14607                              <1> loc_set_valid_hd_fs_partition_params:
 14608 00004097 FE05[407F0000]      <1> 	inc	byte [Last_DOS_DiskNo] ; > 1
 14609 0000409D 30C0                <1> 	xor	al, al ; mov al, 0
 14610                              <1> 	;mov	[drv], dl
 14611 0000409F 29DB                <1> 	sub	ebx, ebx ; 0
 14612 000040A1 8A3D[407F0000]      <1> 	mov	bh, [Last_DOS_DiskNo] 
 14613 000040A7 81C300010900        <1> 	add	ebx, Logical_DOSDisks
 14614 000040AD C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
 14615 000040B1 885302              <1> 	mov	[ebx+LD_PhyDrvNo], dl
 14616                              <1> 	;mov	[ebx+LD_FATType], al ; 0
 14617                              <1> 	;mov	[ebx+LD_FSType], ah
 14618 000040B4 66894303            <1> 	mov	[ebx+LD_FATType], ax
 14619                              <1> 	;mov	eax, [esi+ptStartSector]
 14620                              <1> 	;mov	[ebx+LD_StartSector], eax
 14621                              <1> loc_hd_fs_logical_drv_init:
 14622 000040B8 89DD                <1> 	mov	ebp, ebx ; 10/01/2016
 14623                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
 14624 000040BA A0[417F0000]        <1> 	mov	al, [HD_LBA_yes] ; 10/01/2016
 14625 000040BF 884305              <1> 	mov	[ebx+LD_LBAYes], al
 14626 000040C2 89DE                <1> 	mov	esi, ebx
 14627 000040C4 BB[547F0000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer addressh
 14628 000040C9 08C0                <1> 	or	al, al
 14629 000040CB 7515                <1> 	jnz	short loc_hd_fs_drv_init_load_bs_lba
 14630                              <1> loc_hd_fs_drv_init_load_bs_chs:
 14631 000040CD 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
 14632 000040D0 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
 14633 000040D4 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
 14634                              <1> 	;mov	ebx, DOSBootSectorBuff
 14635 000040D8 E860E8FFFF          <1> 	call	int13h
 14636 000040DD 7311                <1> 	jnc	short loc_hd_drv_fs_boot_validation
 14637                              <1> loc_validate_hd_fs_partition_err_retn:
 14638 000040DF C3                  <1> 	retn
 14639                              <1> loc_validate_hd_fs_partition_stc_retn:
 14640 000040E0 F9                  <1> 	stc
 14641 000040E1 C3                  <1> 	retn
 14642                              <1> loc_hd_fs_drv_init_load_bs_lba:
 14643                              <1> 	; DL = Physical drive number
 14644                              <1> 	;mov	esi, ebx
 14645 000040E2 8B4E08              <1>    	mov	ecx, [esi+ptStartSector] ; sector number
 14646                              <1> 	;mov	ebx, DOSBootSectorBuff ; buffer address
 14647                              <1> 	; LBA read/write (with private LBA function) 
 14648                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 14649                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
 14650 000040E5 B41B                <1> 	mov	ah, 1Bh ; LBA read
 14651 000040E7 B001                <1> 	mov	al, 1 ; sector count
 14652 000040E9 E84FE8FFFF          <1> 	call	int13h
 14653 000040EE 72EF                <1> 	jc	short loc_validate_hd_fs_partition_err_retn
 14654                              <1> loc_hd_drv_fs_boot_validation:
 14655                              <1> 	;mov	esi, DOSBootSectorBuff
 14656 000040F0 89DE                <1> 	mov	esi, ebx ; Boot sector buffer
 14657 000040F2 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
 14658 000040FB 75E3                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
 14659                              <1>         ;
 14660                              <1> 	;Singlix FS Extensions to TR-DOS (7/6/2009) 
 14661 000040FD 66817E035346        <1> 	cmp	word [esi+bs_FS_Identifier], 'SF'
 14662 00004103 75DB                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
 14663                              <1>         ;'A1h' check is not necessary
 14664                              <1> 	;  if 'FS' check is passed as OK/Yes.
 14665 00004105 807E09A1            <1> 	cmp	byte [esi+bs_FS_PartitionID], 0A1h
 14666 00004109 75D5                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
 14667                              <1> 	;
 14668 0000410B 89EF                <1> 	mov	edi, ebp ; 10/01/2016
 14669                              <1> 	;
 14670 0000410D 8A462D              <1> 	mov	al, byte [esi+bs_FS_LBA_Ready]
 14671 00004110 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
 14672                              <1> 	;
 14673                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
 14674 00004113 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
 14675 00004116 884706              <1> 	mov	byte [edi+LD_FS_MediaAttrib], al
 14676                              <1> 	;
 14677 00004119 8A460A              <1> 	mov	al, [esi+bs_FS_VersionMaj]
 14678 0000411C 884707              <1> 	mov	[edi+LD_FS_VersionMajor], al
 14679                              <1> 	;
 14680 0000411F 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
 14681 00004123 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
 14682 00004127 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
 14683 0000412A 6698                <1> 	cbw
 14684 0000412C 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
 14685 00004130 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
 14686                              <1> 	;cbw
 14687 00004133 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
 14688                              <1> 	;
 14689 00004137 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
 14690 0000413A 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
 14691 0000413D 8B5618              <1> 	mov	edx, [esi+bs_FS_MATLocation]
 14692 00004140 89570C              <1> 	mov	[edi+LD_FS_MATLocation], edx
 14693 00004143 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
 14694 00004146 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
 14695 00004149 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
 14696 0000414C 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
 14697 0000414F 8B4710              <1> 	mov	eax, [edi+bs_FS_VolumeSize]
 14698 00004152 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
 14699                              <1> 	;
 14700 00004155 89D0                <1> 	mov	eax, edx ; [edi+LD_FS_MATLocation]
 14701 00004157 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
 14702 0000415A 89FE                <1> 	mov	esi, edi
 14703                              <1> mread_hd_fs_MAT_sector:
 14704                              <1>        ;mov	ebx, DOSBootSectorBuff
 14705 0000415C B901000000          <1> 	mov	ecx, 1
 14706 00004161 E82A290000          <1> 	call	disk_read
 14707 00004166 7243                <1> 	jc	short loc_validate_hd_fs_partition_retn
 14708                              <1> 	; EDI will not be changed
 14709 00004168 89DE                <1> 	mov	esi, ebx
 14710                              <1> use_hdfs_mat_sector_params:
 14711 0000416A 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
 14712 0000416D 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
 14713 00004170 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
 14714 00004173 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
 14715 00004176 8B4614              <1> 	mov	eax, [esi+FS_MAT_FreeSectors]
 14716 00004179 894774              <1>         mov     [edi+LD_FS_FreeSectors], eax
 14717 0000417C 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
 14718 0000417F 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
 14719 00004182 8B4708              <1> 	mov	eax, [edi+LD_FS_RootDirD]
 14720 00004185 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
 14721 00004188 89FE                <1> 	mov	esi, edi   
 14722                              <1> read_hd_fs_RDT_sector:
 14723                              <1> 	;mov	ebx, DOSBootSectorBuff
 14724                              <1> 	;mov	ecx, 1
 14725 0000418A B101                <1> 	mov	cl, 1
 14726 0000418C E8FF280000          <1> 	call	disk_read
 14727 00004191 7218                <1> 	jc	short loc_validate_hd_fs_partition_retn
 14728                              <1> 	; EDI will not be changed
 14729 00004193 89DE                <1> 	mov	esi, ebx
 14730                              <1> use_hdfs_RDT_sector_params:
 14731 00004195 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
 14732 00004198 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
 14733 0000419B 57                  <1> 	push	edi
 14734                              <1> 	;mov	ecx, 16
 14735 0000419C B110                <1> 	mov	cl, 16
 14736 0000419E 83C640              <1> 	add	esi, FS_RDT_VolumeName
 14737 000041A1 83C72C              <1> 	add	edi, LD_FS_VolumeName
 14738 000041A4 F3A5                <1> 	rep	movsd ; 64 bytes
 14739 000041A6 5E                  <1> 	pop	esi
 14740                              <1> 		; Volume Name Reset
 14741 000041A7 C6467E06            <1>         mov     byte [esi+LD_FS_MediaChanged], 6
 14742                              <1> 	;
 14743                              <1>         ;mov	cl, [Last_DOS_DiskNo] 
 14744                              <1> 	;add	cl, 'A'
 14745                              <1> 	;mov	[esi+LD_FS_Name], cl
 14746                              <1> 
 14747                              <1> loc_validate_hd_fs_partition_retn:
 14748 000041AB C3                  <1> 	retn
 14749                              <1> 
 14750                              <1> load_masterboot:
 14751                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
 14752                              <1> 	; 2005 - 2011
 14753                              <1> 	; input -> DL = drive number
 14754 000041AC B40D                <1> 	mov	ah, 0Dh ; Alternate disk reset
 14755 000041AE E88AE7FFFF          <1> 	call	int13h
 14756 000041B3 7301                <1> 	jnc	short pass_reset_error
 14757                              <1> harddisk_error:
 14758 000041B5 C3                  <1>   	retn
 14759                              <1> pass_reset_error:
 14760 000041B6 BB[407B0000]        <1> 	mov	ebx, MasterBootBuff
 14761 000041BB 66B80102            <1> 	mov	ax, 0201h
 14762 000041BF 66B90100            <1> 	mov	cx,1
 14763 000041C3 30F6                <1> 	xor	dh,dh
 14764 000041C5 E873E7FFFF          <1>  	call	int13h
 14765 000041CA 72E9                <1> 	jc	short harddisk_error
 14766                              <1> 	;
 14767 000041CC 66813D[3E7D0000]55- <1> 	cmp	word [MBIDCode], 0AA55h
 14768 000041D4 AA                  <1>
 14769 000041D5 7401                <1> 	je	short load_masterboot_ok
 14770 000041D7 F9                  <1> 	stc
 14771                              <1> load_masterboot_ok:
 14772 000041D8 C3                  <1> 	retn
 14773                              <1> 
 14774                              <1> get_free_FAT_sectors:
 14775                              <1> 	; 07/01/2016 (TRDOS 386 = TRDOS v2.0)
 14776                              <1> 	; 11/07/2010
 14777                              <1> 	; 21/06/2009
 14778                              <1> 	; INPUT: ESI = Logical DOS Drive Description Table address
 14779                              <1> 	; OUTPUT: STC => Error
 14780                              <1>         ;	cf=0 and EAX = Free FAT sectors
 14781                              <1> 	; Also, related parameters and FAT buffer will be reset and updated
 14782                              <1> 
 14783 000041D9 B802000000          <1> 	mov	eax, 2
 14784 000041DE 384603              <1>         cmp     [esi+LD_FATType], al ; 2
 14785 000041E1 7637                <1> 	jna	short loc_gfc_get_fat_free_clusters
 14786                              <1> 
 14787 000041E3 8B466C              <1> 	mov	eax, [esi+LD_StartSector]
 14788 000041E6 BB[547F0000]        <1> 	mov	ebx, DOSBootSectorBuff
 14789 000041EB B901000000          <1> 	mov	ecx, 1
 14790 000041F0 E89B280000          <1>  	call	disk_read
 14791 000041F5 7301                <1> 	jnc	short loc_gfc_check_fsinfo_signs
 14792                              <1> retn_gfc_get_fsinfo_sec:
 14793 000041F7 C3                  <1> 	retn
 14794                              <1> 
 14795                              <1> loc_gfc_check_fsinfo_signs:
 14796 000041F8 813D[547F0000]5252- <1> 	cmp	dword [DOSBootSectorBuff], 41615252h
 14797 00004200 6141                <1>
 14798 00004202 7514                <1> 	jne	short retn_gfc_get_fsinfo_stc
 14799                              <1> 	;mov 	ebx, DOSBootSectorBuff
 14800                              <1> 	;add	ebx, 484
 14801                              <1> 	;cmp	dword [ebx], 61417272h
 14802 00004204 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
 14803 0000420D 61                  <1>
 14804 0000420E 7508                <1> 	jne	short retn_gfc_get_fsinfo_stc
 14805                              <1> 	;add	ebx, 4
 14806                              <1> 	;mov	eax, [ebx]
 14807 00004210 8B83E8010000        <1> 	mov	eax, [ebx+488]
 14808 00004216 EB10                <1> 	jmp	short retn_from_get_free_fat32_clusters
 14809                              <1> 
 14810                              <1> retn_gfc_get_fsinfo_stc:
 14811 00004218 F9                  <1> 	stc
 14812 00004219 C3                  <1> 	retn
 14813                              <1> 
 14814                              <1> loc_gfc_get_fat_free_clusters:
 14815                              <1> 	;mov	eax, 2
 14816                              <1> 	;mov	[FAT_CurrentCluster], eax
 14817                              <1> loc_gfc_loop_get_next_cluster:
 14818 0000421A E8E40F0000          <1> 	call	get_next_cluster
 14819 0000421F 730E                <1> 	jnc	short loc_gfc_free_fat_clusters_cont
 14820 00004221 21C0                <1> 	and	eax, eax
 14821 00004223 7411                <1> 	jz	short loc_gfc_pass_inc_free_cluster_count
 14822                              <1>  
 14823                              <1> retn_from_get_free_fat_clusters:
 14824 00004225 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
 14825                              <1> retn_from_get_free_fat32_clusters:
 14826 00004228 0FB65E13            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
 14827 0000422C F7E3                <1>       	mul	ebx
 14828                              <1> 	;mov	[esi+LD_FreeSectors], eax
 14829                              <1> retn_get_free_sectors_calc:
 14830 0000422E C3                  <1> 	retn
 14831                              <1> 
 14832                              <1> loc_gfc_free_fat_clusters_cont:
 14833 0000422F 09C0                <1> 	or	eax, eax
 14834 00004231 7503                <1> 	jnz	short loc_gfc_pass_inc_free_cluster_count
 14835 00004233 FF4674              <1> 	inc	dword [esi+LD_FreeSectors]
 14836                              <1>    
 14837                              <1> loc_gfc_pass_inc_free_cluster_count:
 14838                              <1> 	;mov	eax, [FAT_CurrentCluster]
 14839                              <1> 	;cmp	eax, [esi+LD_Clusters]
 14840                              <1> 	;ja	short retn_from_get_free_fat_clusters
 14841                              <1> 	;inc	eax
 14842                              <1> 	;mov	[FAT_CurrentCluster], eax
 14843 00004236 FF05[54810000]      <1> 	inc	dword [FAT_CurrentCluster]
 14844 0000423C EBDC                <1> 	jmp	short loc_gfc_loop_get_next_cluster
 14845                              <1> 
 14846                              <1> floppy_drv_init:
 14847                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
 14848                              <1> 	; 24/07/2011
 14849                              <1> 	; 04/07/2009
 14850                              <1> 	; INPUT ->
 14851                              <1> 	;	DL = Drive number (0,1)
 14852                              <1> 	; OUTPUT ->
 14853                              <1> 	;	BL = drive name
 14854                              <1> 	;	BH = drive number
 14855                              <1> 	;	ESI = Logical DOS drv description table
 14856                              <1> 	;	EAX = Volume serial number
 14857                              <1>  
 14858 0000423E BE[AE750000]        <1> 	mov	esi, fd0_type ; 10/01/2016
 14859 00004243 BF00010900          <1> 	mov	edi, Logical_DOSDisks
 14860 00004248 08D2                <1> 	or	dl, dl
 14861 0000424A 7407                <1> 	jz	short loc_drv_init_fd0_fd1
 14862 0000424C 81C700010000        <1> 	add	edi, 100h
 14863 00004252 46                  <1> 	inc	esi ; fd1_type ; 10/01/2016
 14864                              <1> loc_drv_init_fd0_fd1:
 14865 00004253 C6477E00            <1> 	mov	byte [edi+LD_MediaChanged], 0
 14866 00004257 803E01              <1> 	cmp	byte [esi], 1 ; type (>0 if it is existing) 
 14867                              <1> 		; 4 = 1.44 MB, 80 track, 3 1/2"
 14868 0000425A 7221                <1> 	jb	short read_fd_boot_sector_retn
 14869 0000425C 885702              <1> 	mov	[edi+LD_PhyDrvNo], dl
 14870                              <1> read_fd_boot_sector:
 14871 0000425F 30F6                <1> 	xor	dh, dh
 14872 00004261 B904000000          <1> 	mov	ecx, 4 ; Retry Count
 14873                              <1> read_fd_boot_sector_again:
 14874 00004266 51                  <1> 	push 	ecx
 14875                              <1> 	;mov	cx, 1
 14876 00004267 B101                <1> 	mov	cl, 1
 14877 00004269 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
 14878 0000426D BB[547F0000]        <1> 	mov	ebx, DOSBootSectorBuff
 14879 00004272 E8C6E6FFFF          <1> 	call	int13h
 14880 00004277 59                  <1> 	pop	ecx
 14881 00004278 7304                <1> 	jnc	short use_fd_boot_sector_params
 14882 0000427A E2EA                <1> 	loop	read_fd_boot_sector_again
 14883                              <1> 
 14884                              <1> read_fd_boot_sector_stc_retn:
 14885 0000427C F9                  <1> 	stc
 14886                              <1> read_fd_boot_sector_retn:
 14887 0000427D C3                  <1> 	retn
 14888                              <1> 
 14889                              <1> use_fd_boot_sector_params:
 14890                              <1> 	;mov	esi, DOSBootSectorBuff
 14891 0000427E 89DE                <1> 	mov	esi, ebx
 14892 00004280 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
 14893 00004289 75F1                <1> 	jne	short read_fd_boot_sector_stc_retn
 14894 0000428B 66817E035346        <1>         cmp     word [esi+bs_FS_Identifier], 'SF'
 14895 00004291 0F85A2000000        <1>         jne     use_fd_fatfs_boot_sector_params
 14896                              <1> 	;
 14897 00004297 8A462D              <1> 	mov	al, [esi+bs_FS_LBA_Ready]
 14898 0000429A 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
 14899                              <1> 	;
 14900                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
 14901 0000429D 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
 14902 000042A0 884706              <1> 	mov	[edi+LD_FS_MediaAttrib], al
 14903                              <1> 	;
 14904 000042A3 8A460A              <1>         mov	al, [esi+bs_FS_VersionMaj]
 14905 000042A6 884707              <1> 	mov	byte [edi+LD_FS_VersionMajor], al
 14906 000042A9 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
 14907 000042AD 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
 14908 000042B1 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
 14909 000042B4 6698                <1> 	cbw
 14910 000042B6 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
 14911 000042BA 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
 14912                              <1> 	;cbw
 14913 000042BD 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
 14914                              <1> 	;
 14915 000042C1 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
 14916 000042C4 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
 14917 000042C7 8B4618              <1> 	mov	eax, [esi+bs_FS_MATLocation]
 14918 000042CA 89470C              <1> 	mov	[edi+LD_FS_MATLocation], eax
 14919 000042CD 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
 14920 000042D0 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
 14921 000042D3 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
 14922 000042D6 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
 14923 000042D9 8B4610              <1> 	mov	eax, [esi+bs_FS_VolumeSize]
 14924 000042DC 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
 14925                              <1> 	;		
 14926 000042DF 89FE                <1> 	mov	esi, edi
 14927 000042E1 8B460C              <1>  	mov	eax, [esi+LD_FS_MATLocation]
 14928                              <1> 	;add	eax, [edi+LD_FS_BeginSector]
 14929                              <1> read_fd_MAT_sector_again:
 14930                              <1> 	;mov	ebx, DOSBootSectorBuff
 14931                              <1> 	;mov	ecx, 1
 14932 000042E4 B101                <1> 	mov	cl, 1
 14933 000042E6 E8AB270000          <1> 	call	chs_read
 14934 000042EB 89DE                <1> 	mov	esi, ebx
 14935 000042ED 7301                <1> 	jnc	short use_fdfs_mat_sector_params
 14936                              <1> 	;jmp	short read_fd_boot_sector_retn
 14937 000042EF C3                  <1> 	retn
 14938                              <1> use_fdfs_mat_sector_params:
 14939 000042F0 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
 14940 000042F3 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
 14941 000042F6 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
 14942 000042F9 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
 14943 000042FC 8B4714              <1> 	mov	eax, [edi+FS_MAT_FreeSectors]
 14944 000042FF 894774              <1> 	mov	[edi+LD_FS_FreeSectors], eax
 14945 00004302 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
 14946 00004305 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
 14947                              <1> 	;
 14948 00004308 89FE                <1> 	mov	esi, edi
 14949 0000430A 8B4608              <1>  	mov	eax, [esi+LD_FS_RootDirD]
 14950                              <1> read_fd_RDT_sector_again:
 14951                              <1> 	;mov	ebx, DOSBootSectorBuff
 14952                              <1> 	;mov	cx, 1
 14953 0000430D B101                <1> 	mov	cl, 1
 14954 0000430F E882270000          <1> 	call	chs_read
 14955 00004314 89DE                <1> 	mov	esi, ebx
 14956 00004316 7220                <1> 	jc	short read_fd_RDT_sector_retn
 14957                              <1> use_fdfs_RDT_sector_params:
 14958 00004318 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
 14959 0000431B 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
 14960 0000431E 57                  <1> 	push	edi
 14961                              <1> 	;mov	ecx, 16
 14962 0000431F B110                <1> 	mov	cl, 16	
 14963 00004321 83C640              <1> 	add	esi, FS_RDT_VolumeName
 14964 00004324 83C72C              <1> 	add	edi, LD_FS_VolumeName
 14965 00004327 F3A5                <1> 	rep	movsd ; 64 bytes
 14966 00004329 5E                  <1> 	pop	esi
 14967 0000432A C6460300            <1> 	mov	byte [esi+LD_FATType], 0
 14968 0000432E C64604A1            <1> 	mov	byte [esi+LD_FSType], 0A1h  
 14969 00004332 E9AA000000          <1>         jmp     loc_cont_use_fd_boot_sector_params
 14970                              <1> 
 14971                              <1> read_fd_RDT_sector_stc_retn:
 14972 00004337 F9                  <1> 	stc
 14973                              <1> read_fd_RDT_sector_retn:
 14974 00004338 C3                  <1> 	retn
 14975                              <1> 
 14976                              <1> use_fd_fatfs_boot_sector_params:
 14977 00004339 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
 14978 0000433D 75F8                <1> 	jne	short read_fd_RDT_sector_stc_retn
 14979 0000433F 807E15F0            <1> 	cmp	byte [esi+BPB_Media], 0F0h
 14980 00004343 72F3                <1> 	jb	short read_fd_RDT_sector_retn
 14981 00004345 57                  <1> 	push	edi
 14982 00004346 83C706              <1> 	add	edi, LD_BPB
 14983                              <1> 	;mov	ecx, 16
 14984 00004349 B110                <1> 	mov	cl, 16
 14985 0000434B F3A5                <1> 	rep	movsd ; 64 bytes 
 14986 0000434D 5E                  <1> 	pop	esi
 14987 0000434E 31C0                <1> 	xor	eax, eax
 14988 00004350 89466C              <1> 	mov	[esi+LD_StartSector], eax ; 0
 14989 00004353 668B461C            <1> 	mov	ax, [esi+LD_BPB+BPB_FATSz16]
 14990 00004357 8A4E16              <1> 	mov	cl, [esi+LD_BPB+BPB_NumFATs] 
 14991 0000435A F7E1                <1>   	mul	ecx
 14992                              <1> 	; edx = 0 !
 14993 0000435C 668B5614            <1> 	mov	dx, [esi+LD_BPB+BPB_RsvdSecCnt]
 14994 00004360 66895660            <1> 	mov	[esi+LD_FATBegin], dx
 14995                              <1> 	;add	eax, edx
 14996 00004364 6601D0              <1> 	add	ax, dx
 14997 00004367 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
 14998 0000436A 894668              <1> 	mov	[esi+LD_DATABegin], eax 
 14999 0000436D 668B5617            <1> 	mov	dx, [esi+LD_BPB+BPB_RootEntCnt]
 15000                              <1> 	;shl	edx, 5 ; * 32 (Size of a directory entry)
 15001 00004371 66C1E205            <1> 	shl	dx, 5
 15002                              <1> 	;add	edx, 511
 15003 00004375 6681C2FF01          <1> 	add	dx, 511
 15004                              <1> 	;shr	edx, 9 ; edx = ((edx*32)+511) / 512
 15005 0000437A 66C1EA09            <1> 	shr	dx, 9
 15006 0000437E 015668              <1> 	add 	[esi+LD_DATABegin], edx
 15007                              <1> 	;movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
 15008 00004381 668B4619            <1> 	mov	ax, [esi+LD_BPB+BPB_TotalSec16]
 15009 00004385 894670              <1> 	mov	[esi+LD_TotalSectors], eax
 15010 00004388 2B4668              <1> 	sub	eax, [esi+LD_DATABegin]
 15011                              <1>   	;movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust]
 15012 0000438B 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]  
 15013 0000438E 80F901              <1> 	cmp	cl, 1
 15014 00004391 7605                <1> 	jna	short save_fd_fatfs_cluster_count
 15015                              <1> 	;sub	edx, edx
 15016 00004393 6629D2              <1> 	sub	dx, dx ; 0
 15017 00004396 F7F1                <1> 	div	ecx
 15018                              <1> save_fd_fatfs_cluster_count:
 15019 00004398 894678              <1> 	mov	[esi+LD_Clusters], eax
 15020                              <1> 
 15021                              <1>       ; Maximum Valid Cluster Number = EAX +1
 15022                              <1>       ; with 2 reserved clusters= EAX +2
 15023                              <1>  
 15024                              <1> reset_FAT_buffer_decriptors:
 15025 0000439B 29C0                <1> 	sub	eax, eax ; 0  
 15026 0000439D A2[58810000]        <1> 	mov	[FAT_BuffValidData], al ; 0
 15027 000043A2 A2[59810000]        <1> 	mov	[FAT_BuffDrvName], al ; 0
 15028 000043A7 A3[5C810000]        <1> 	mov	[FAT_BuffSector], eax ; 0
 15029                              <1> 
 15030                              <1> read_fd_FAT_sectors:
 15031 000043AC BB001C0900          <1>   	mov	ebx, FAT_Buffer
 15032 000043B1 668B4614            <1> 	mov	ax, [esi+LD_BPB+BPB_RsvdSecCnt]
 15033                              <1> 	;mov	ecx, 3
 15034 000043B5 B103                <1> 	mov	cl, 3 ; 3 sectors
 15035 000043B7 E8DA260000          <1> 	call	chs_read
 15036 000043BC 7240                <1> 	jc	short read_fd_FAT_sectors_retn
 15037                              <1> use_fd_FAT_sectors:
 15038 000043BE 8A4602              <1> 	mov	al, [esi+LD_PhyDrvNo]
 15039 000043C1 0441                <1> 	add	al, 'A' 
 15040 000043C3 A2[59810000]        <1> 	mov	[FAT_BuffDrvName], al 
 15041 000043C8 C605[58810000]01    <1>  	mov	byte [FAT_BuffValidData], 1
 15042 000043CF E82B000000          <1> 	call	fd_init_calculate_free_clusters
 15043 000043D4 7228                <1> 	jc	short read_fd_FAT_sectors_retn
 15044                              <1>   
 15045                              <1> loc_use_fd_boot_sector_params_FAT:
 15046 000043D6 C6460301            <1> 	mov	byte [esi+LD_FATType], 1 ; FAT 12
 15047 000043DA C6460401            <1> 	mov	byte [esi+LD_FSType], 1
 15048 000043DE 8B462D              <1>         mov     eax, [esi+LD_BPB+VolumeID]
 15049                              <1> loc_cont_use_fd_boot_sector_params:
 15050 000043E1 8A7E02              <1> 	mov	bh, [esi+LD_PhyDrvNo]
 15051 000043E4 887E7D              <1> 	mov	[esi+LD_DParamEntry], bh
 15052 000043E7 88FB                <1> 	mov	bl, bh
 15053 000043E9 80C341              <1> 	add	bl, 'A'
 15054 000043EC 881E                <1> 	mov	byte [esi+LD_Name], bl
 15055 000043EE C6460101            <1> 	mov	byte [esi+LD_DiskType], 1
 15056 000043F2 C6460500            <1> 	mov	byte [esi+LD_LBAYes], 0
 15057 000043F6 C6467C00            <1> 	mov	byte [esi+LD_PartitionEntry], 0
 15058 000043FA C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6 ; Volume Name Reset
 15059                              <1> 
 15060                              <1> read_fd_FAT_sectors_retn:
 15061 000043FE C3                  <1> 	retn   
 15062                              <1> 
 15063                              <1> fd_init_calculate_free_clusters:
 15064                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
 15065                              <1> 	; 04/07/2009
 15066                              <1> 	; INPUT ->
 15067                              <1> 	;     ESI = Logical DOS drive description table address
 15068                              <1> 	; OUTPUT ->
 15069                              <1> 	;    [ESI+LD_FreeSectors] will be set
 15070                              <1> 	
 15071 000043FF 29C0                <1> 	sub	eax, eax
 15072 00004401 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; 0
 15073 00004404 B002                <1> 	mov	al, 2 ; eax = 2
 15074                              <1> 
 15075                              <1> fd_init_loop_get_next_cluster:
 15076 00004406 E830000000          <1> 	call	fd_init_get_next_cluster
 15077 0000440B 722D                <1> 	jc	short fd_init_calculate_free_clusters_retn
 15078                              <1> 
 15079                              <1> fd_init_free_fat_clusters:
 15080                              <1> 	;cmp 	eax, 0
 15081                              <1> 	;ja	short fd_init_pass_inc_free_cluster_count
 15082                              <1> 	;and	eax, eax
 15083                              <1> 	;jnz	short fd_init_pass_inc_free_cluster_count
 15084 0000440D 6621C0              <1> 	and	ax, ax
 15085 00004410 7504                <1> 	jnz	short fd_init_pass_inc_free_cluster_count
 15086                              <1> 	;inc	dword [esi+LD_FreeSectors]
 15087 00004412 66FF4674            <1>         inc	word [esi+LD_FreeSectors]
 15088                              <1>     
 15089                              <1> fd_init_pass_inc_free_cluster_count:
 15090                              <1>   	;mov	eax, [FAT_CurrentCluster]
 15091 00004416 66A1[54810000]      <1> 	mov	ax, [FAT_CurrentCluster]
 15092                              <1> 	;cmp	eax, [esi+LD_Clusters]
 15093 0000441C 663B4678            <1> 	cmp	ax, [esi+LD_Clusters]
 15094 00004420 7704                <1> 	ja	short short retn_from_fd_init_calculate_free_clusters
 15095                              <1> 	;inc	eax
 15096 00004422 6640                <1> 	inc	ax
 15097 00004424 EBE0                <1> 	jmp	short fd_init_loop_get_next_cluster
 15098                              <1> 
 15099                              <1> retn_from_fd_init_calculate_free_clusters:
 15100 00004426 8A4613              <1>   	mov	al, [esi+LD_BPB+BPB_SecPerClust]
 15101 00004429 3C01                <1>   	cmp	al, 1
 15102 0000442B 760D                <1> 	jna	short fd_init_calculate_free_clusters_retn
 15103                              <1> 	;movzx	eax, al
 15104 0000442D 6698                <1> 	cbw
 15105                              <1> 	;mov	ecx, [esi+LD_FreeSectors]
 15106 0000442F 668B4E74            <1> 	mov	cx, [esi+LD_FreeSectors] ; Count of free clusters
 15107                              <1>   	;mul	ecx
 15108 00004433 66F7E1              <1> 	mul	cx
 15109                              <1> 	;mov	[esi+LD_FreeSectors], eax
 15110 00004436 66894674            <1> 	mov	[esi+LD_FreeSectors], ax
 15111                              <1> fd_init_calculate_free_clusters_retn:
 15112 0000443A C3                  <1> 	retn
 15113                              <1> 
 15114                              <1> fd_init_get_next_cluster:
 15115                              <1> 	; 02/02/2016
 15116                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
 15117                              <1> 	; 04/07/2009
 15118                              <1> 	; INPUT ->
 15119                              <1> 	;    EAX = Current cluster
 15120                              <1> 	;    ESI = Logical DOS drive description table address
 15121                              <1> 	;    EDX = 0
 15122                              <1> 	; OUTPUT ->
 15123                              <1> 	;    EAX = Next cluster
 15124                              <1> 
 15125 0000443B A3[54810000]        <1> 	mov	[FAT_CurrentCluster], eax
 15126                              <1> fd_init_get_next_cluster_readnext:
 15127 00004440 29D2                <1> 	sub	edx, edx ; 0
 15128 00004442 BB00040000          <1>   	mov	ebx, 1024 ; 400h
 15129 00004447 F7F3                <1>   	div	ebx
 15130                              <1>   	; EAX = Count of 3 FAT sectors
 15131                              <1>   	; EDX = Buffer entry index
 15132 00004449 89C1                <1> 	mov	ecx, eax
 15133                              <1> 	;mov	eax, 3
 15134 0000444B B003                <1> 	mov	al, 3
 15135 0000444D F7E2                <1> 	mul	edx ; Multiply by 3
 15136 0000444F 66D1E8              <1> 	shr	ax, 1 ; Divide by 2
 15137 00004452 89C3                <1> 	mov	ebx, eax ; Buffer byte offset
 15138 00004454 89C8                <1> 	mov	eax, ecx
 15139                              <1> 	;mov	edx, 3
 15140 00004456 66BA0300            <1> 	mov	dx, 3
 15141 0000445A F7E2                <1> 	mul	edx 
 15142                              <1>   	; EAX = FAT Beginning Sector
 15143                              <1> 	; EDX = 0
 15144 0000445C 8A0E                <1> 	mov	cl, [esi+LD_Name]
 15145                              <1> 	;cmp	byte [FAT_BuffValidData], 0
 15146                              <1> 	;jna	short fd_init_load_FAT_sectors0
 15147 0000445E 3A0D[59810000]      <1> 	cmp	cl, [FAT_BuffDrvName]
 15148 00004464 751E                <1> 	jne	short fd_init_load_FAT_sectors0
 15149 00004466 3B05[5C810000]      <1> 	cmp	eax, [FAT_BuffSector]
 15150 0000446C 751C                <1> 	jne	short fd_init_load_FAT_sectors1
 15151                              <1> 	;mov	eax, [FAT_CurrentCluster]
 15152 0000446E A0[54810000]        <1> 	mov	al, [FAT_CurrentCluster]
 15153                              <1> 	;shr	eax, 1
 15154 00004473 D0E8                <1> 	shr	al, 1
 15155 00004475 668B03              <1> 	mov	ax, [ebx]
 15156 00004478 7306                <1>   	jnc	short fd_init_gnc_even
 15157 0000447A 66C1E804            <1> 	shr	ax, 4
 15158                              <1> fd_init_gnc_clc_retn:
 15159 0000447E F8                  <1> 	clc
 15160 0000447F C3                  <1> 	retn
 15161                              <1> 
 15162                              <1> fd_init_gnc_even:
 15163 00004480 80E40F              <1> 	and	ah, 0Fh
 15164 00004483 C3                  <1> 	retn
 15165                              <1> 
 15166                              <1> fd_init_load_FAT_sectors0:
 15167 00004484 880D[59810000]      <1> 	mov 	[FAT_BuffDrvName], cl
 15168                              <1> fd_init_load_FAT_sectors1:
 15169 0000448A C605[58810000]00    <1> 	mov	byte [FAT_BuffValidData], 0
 15170 00004491 A3[5C810000]        <1> 	mov	[FAT_BuffSector], eax
 15171 00004496 034660              <1> 	add	eax, [esi+LD_FATBegin]
 15172 00004499 BB001C0900          <1>  	mov	ebx, FAT_Buffer
 15173                              <1> 	;movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
 15174 0000449E 668B4E1C            <1> 	mov	cx, [esi+LD_BPB+BPB_FATSz16]
 15175 000044A2 662B0D[5C810000]    <1> 	sub	cx, [FAT_BuffSector]
 15176                              <1>         ;cmp	ecx, 3
 15177 000044A9 6683F903            <1> 	cmp	cx, 3
 15178 000044AD 7605                <1> 	jna	short fdinit_pass_fix_sector_count_3
 15179                              <1> 	;mov	ecx, 3
 15180 000044AF B903000000          <1> 	mov	ecx, 3
 15181                              <1> fdinit_pass_fix_sector_count_3:  
 15182 000044B4 E8DD250000          <1> 	call	chs_read
 15183 000044B9 730D                <1> 	jnc	short fd_init_FAT_sectors_no_load_error
 15184 000044BB C605[58810000]00    <1> 	mov	byte [FAT_BuffValidData], 0
 15185                              <1> 		; Drv not ready or read Error !
 15186 000044C2 B80F000000          <1> 	mov	eax, ERR_DRV_NOT_RDY ; 15
 15187                              <1> 	;xor	edx, edx
 15188 000044C7 C3                  <1> 	retn
 15189                              <1> 
 15190                              <1> fd_init_FAT_sectors_no_load_error:
 15191 000044C8 C605[58810000]01    <1> 	mov	byte [FAT_BuffValidData], 1
 15192 000044CF A1[54810000]        <1> 	mov	eax, [FAT_CurrentCluster]
 15193 000044D4 E967FFFFFF          <1>         jmp     fd_init_get_next_cluster_readnext
 15194                              <1> 
 15195                              <1> get_FAT_volume_name:
 15196                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
 15197                              <1> 	; 12/09/2009
 15198                              <1> 	; INPUT ->
 15199                              <1> 	;	BH = Logical DOS drive number (0,1,2,3,4 ...)
 15200                              <1> 	;       BL = 0
 15201                              <1> 	; OUTPUT ->
 15202                              <1> 	;	CF = 0 -> ESI = Volume name address
 15203                              <1> 	; 	CF = 1 -> Root volume name not found
 15204                              <1> 
 15205                              <1> 	;mov 	ah, 0FFh
 15206                              <1> 	;mov 	al, [Last_Dos_DiskNo]
 15207                              <1> 	;cmp 	al, bh
 15208                              <1> 	;jb     short loc_gfvn_dir_load_err
 15209                              <1> 
 15210 000044D9 89DE                <1> 	mov	esi, ebx
 15211 000044DB 81E600FF0000        <1> 	and	esi, 0FF00h ; esi = bh
 15212 000044E1 81C600010900        <1> 	add	esi, Logical_DOSDisks
 15213 000044E7 8A06                <1> 	mov     al, [esi+LD_Name]
 15214 000044E9 8A6603              <1> 	mov     ah, [esi+LD_FATType]
 15215 000044EC 80FC01              <1> 	cmp     ah, 1
 15216 000044EF 7210                <1> 	jb    	short loc_gfvn_dir_load_err
 15217 000044F1 3C41                <1> 	cmp 	al, 'A'
 15218 000044F3 720C                <1> 	jb      short loc_gfvn_dir_load_err
 15219 000044F5 80FC02              <1> 	cmp 	ah, 2 
 15220 000044F8 7708                <1> 	ja      short get_FAT32_root_cluster
 15221                              <1> 	
 15222 000044FA E85A0E0000          <1> 	call    load_FAT_root_directory
 15223 000044FF 730B                <1> 	jnc     short loc_get_volume_name
 15224                              <1> 
 15225                              <1> loc_gfvn_dir_load_err:
 15226 00004501 C3                  <1> 	retn
 15227                              <1> 
 15228                              <1> get_FAT32_root_cluster:
 15229 00004502 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
 15230 00004505 E8DB0E0000          <1> 	call    load_FAT_sub_directory
 15231 0000450A 7224                <1> 	jc	short loc_get_volume_name_retn
 15232                              <1> 
 15233                              <1> loc_get_volume_name:
 15234 0000450C BE00000800          <1>         mov     esi, Directory_Buffer
 15235 00004511 6631C9              <1> 	xor	cx, cx ; 0
 15236                              <1> check_root_volume_name:
 15237 00004514 8A06                <1> 	mov	al, [esi]
 15238 00004516 08C0                <1> 	or      al, al
 15239 00004518 7416                <1> 	jz      short loc_get_volume_name_retn
 15240 0000451A 807E0B08            <1> 	cmp     byte [esi+0Bh], 08h
 15241 0000451E 7410                <1> 	je      short loc_get_volume_name_retn
 15242 00004520 663B0D[6E810000]    <1> 	cmp     cx, [DirBuff_LastEntry]
 15243 00004527 7308                <1> 	jnb     short pass_check_root_volume_name
 15244 00004529 6641                <1> 	inc     cx
 15245 0000452B 83C620              <1> 	add     esi, 32
 15246 0000452E EBE4                <1> 	jmp     short check_root_volume_name
 15247                              <1> 
 15248                              <1> loc_get_volume_name_retn:
 15249 00004530 C3                  <1> 	retn
 15250                              <1>     
 15251                              <1> pass_check_root_volume_name:
 15252 00004531 803D[6A810000]03    <1> 	cmp	byte [DirBuff_FATType], 3
 15253 00004538 7230                <1> 	jb	short loc_get_volume_name_retn_xor
 15254                              <1> 
 15255 0000453A BB001C0900          <1> 	mov	ebx, FAT_Buffer
 15256 0000453F BE00010900          <1> 	mov	esi, Logical_DOSDisks
 15257 00004544 31C0                <1> 	xor	eax, eax
 15258 00004546 8A25[69810000]      <1> 	mov	ah, [DirBuff_DRV]
 15259 0000454C 80EC41              <1> 	sub	ah, 'A' 
 15260 0000454F 01C6                <1> 	add	esi, eax
 15261 00004551 A1[70810000]        <1> 	mov	eax, [DirBuff_Cluster]
 15262 00004556 E8A80C0000          <1> 	call	get_next_cluster
 15263 0000455B 7305                <1> 	jnc 	short loc_gfvn_load_FAT32_dir_cluster
 15264                              <1>   	
 15265 0000455D 83F801              <1> 	cmp     eax, 1
 15266 00004560 F5                  <1> 	cmc
 15267 00004561 C3                  <1> 	retn
 15268                              <1>   
 15269                              <1> loc_gfvn_load_FAT32_dir_cluster:
 15270 00004562 E87E0E0000          <1> 	call	load_FAT_sub_directory
 15271 00004567 73A3                <1> 	jnc	short loc_get_volume_name
 15272 00004569 C3                  <1> 	retn
 15273                              <1> 
 15274                              <1> loc_get_volume_name_retn_xor:
 15275 0000456A 31C0                <1> 	xor 	eax, eax
 15276 0000456C C3                  <1> 	retn
 15277                              <1> 
 15278                              <1> get_media_change_status:
 15279                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
 15280                              <1> 	; 09/09/2009
 15281                              <1> 	; INPUT:
 15282                              <1> 	;     DL = Drive number (physical)
 15283                              <1> 	; OUTPUT: clc & AH = 6 media changed
 15284                              <1> 	;     clc & AH = 0 media not changed         
 15285                              <1> 	;     stc -> Drive not ready or an error 
 15286                              <1>   
 15287 0000456D B416                <1> 	mov	ah, 16h
 15288 0000456F E8C9E3FFFF          <1>   	call	int13h
 15289 00004574 80FC06              <1> 	cmp	ah, 06h
 15290 00004577 7405                <1> 	je	short loc_gmc_status_retn
 15291 00004579 08E4                <1> 	or	ah, ah
 15292 0000457B 7401                <1> 	jz	short loc_gmc_status_retn
 15293                              <1> loc_gmc_status_stc_retn:    
 15294 0000457D F9                  <1> 	stc
 15295                              <1> loc_gmc_status_retn:
 15296 0000457E C3                  <1> 	retn
 15297                                  %include 'trdosk3.s' ; 06/01/2016
 15298                              <1> ; ****************************************************************************
 15299                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk3.s
 15300                              <1> ; ----------------------------------------------------------------------------
 15301                              <1> ; Last Update: 30/01/2016
 15302                              <1> ; ----------------------------------------------------------------------------
 15303                              <1> ; Beginning: 06/01/2016
 15304                              <1> ; ----------------------------------------------------------------------------
 15305                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 15306                              <1> ; ----------------------------------------------------------------------------
 15307                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 15308                              <1> ; MAINPROG.ASM (09/11/2011)
 15309                              <1> ; ****************************************************************************
 15310                              <1> ; MAINPROG.ASM [ TRDOS KERNEL - COMMAND EXECUTER SECTION - MAIN PROGRAM ]
 15311                              <1> ; (c) 2004-2011  Erdogan TAN  [ 17/01/2004 ]  Last Update: 09/11/2011
 15312                              <1> ; CMD_INTR.ASM [ TRDOS Command Interpreter Procedure ] Last Update: 09/11/2011
 15313                              <1> 
 15314                              <1> change_current_drive:
 15315                              <1> 	; 15/01/2016 (TRDOS 386 = TRDOS v2.0)
 15316                              <1> 	; 18/08/2011
 15317                              <1> 	; 09/09/2009
 15318                              <1> 	; INPUT:
 15319                              <1> 	;   DL = Logical DOS Drive Number
 15320                              <1> 	; OUTPUT:
 15321                              <1> 	;  cf=1 -> Not successfull
 15322                              <1> 	;   EAX = Error code
 15323                              <1> 	;  cf=0 ->
 15324                              <1> 	;   EAX = 0 (successfull)
 15325                              <1> 
 15326 0000457F 31DB                <1> 	xor	ebx, ebx
 15327 00004581 88D7                <1> 	mov	bh, dl
 15328                              <1> 
 15329                              <1> 	;cmp	dl, 1
 15330                              <1> 	;jna	short loc_ccdrv_initial_media_change_check
 15331                              <1> 	;cmp	bh, [Last_Dos_DiskNo]
 15332                              <1> 	;ja	short loc_ccdrv_drive_not_ready_err
 15333                              <1> 
 15334                              <1> loc_ccdrv_initial_media_change_check:
 15335 00004583 BE00010900          <1> 	mov	esi, Logical_DOSDisks
 15336 00004588 01DE                <1> 	add	esi, ebx
 15337                              <1> loc_ccdrv_dos_drive_name_check:
 15338 0000458A 80FA02              <1> 	cmp	dl, 2
 15339 0000458D 720F                <1> 	jb	short loc_ccdrv_dos_drive_name_check_ok
 15340                              <1> 
 15341 0000458F 8A06                <1> 	mov	al, [esi+LD_Name]
 15342 00004591 2C41                <1> 	sub	al, 'A'
 15343 00004593 38D0                <1> 	cmp	al, dl
 15344 00004595 7407                <1> 	je	short loc_ccdrv_dos_drive_name_check_ok
 15345                              <1> 
 15346                              <1> loc_ccdrv_drive_not_ready_err:
 15347 00004597 B815000000          <1> 	mov	eax, 15h ; Drive not ready
 15348                              <1> loc_change_current_drive_stc_retn:
 15349 0000459C F9                  <1> 	stc
 15350 0000459D C3                  <1> 	retn  
 15351                              <1> 
 15352                              <1> loc_ccdrv_dos_drive_name_check_ok:
 15353 0000459E 8A667E              <1> 	mov	ah, [esi+LD_MediaChanged]
 15354 000045A1 80FC06              <1> 	cmp	ah, 6  ; VOLUME NAME CHECK/MOVE SIGN
 15355 000045A4 7452                <1> 	je	short loc_ccdrv_get_FAT_volume_name_0
 15356                              <1> 
 15357 000045A6 80FA01              <1> 	cmp	dl, 1
 15358 000045A9 7779                <1> 	ja	short loc_gmcs_init_drv_hd
 15359                              <1> 
 15360                              <1> loc_gmcs_init_drv_fd:
 15361 000045AB 08E4                <1> 	or	ah, ah 
 15362                              <1> 	; AH = 1 is initialization sign (invalid_fd_parameter)
 15363 000045AD 7517                <1> 	jnz	short loc_ccdrv_call_fd_init
 15364                              <1> 
 15365 000045AF E8B9FFFFFF          <1> 	call	get_media_change_status
 15366 000045B4 72E1                <1> 	jc	short loc_ccdrv_drive_not_ready_err
 15367                              <1> 
 15368 000045B6 20E4                <1> 	and	ah, ah
 15369 000045B8 7471                <1> 	jz	short loc_change_current_drv3
 15370                              <1> 
 15371 000045BA 80F406              <1> 	xor	ah, 6
 15372 000045BD 75D8                <1> 	jnz	short loc_ccdrv_drive_not_ready_err
 15373                              <1> 
 15374                              <1> loc_ccdrv_call_fd_init_check_vol_id:
 15375 000045BF E82B0A0000          <1> 	call	get_volume_serial_number
 15376 000045C4 7308                <1> 	jnc	short loc_ccdrv_check_vol_serial
 15377                              <1> 
 15378                              <1> loc_ccdrv_call_fd_init:
 15379 000045C6 E873FCFFFF          <1> 	call	floppy_drv_init
 15380 000045CB 7317                <1> 	jnc	short loc_reset_drv_fd_current_dir
 15381                              <1> 
 15382                              <1> loc_ccdrv_fdinit_fail_retn:
 15383 000045CD C3                  <1> 	retn
 15384                              <1> 
 15385                              <1> loc_ccdrv_check_vol_serial:
 15386 000045CE A3[84790000]        <1> 	mov	[Current_VolSerial], eax
 15387                              <1> 	;mov	dl, bh
 15388 000045D3 E866FCFFFF          <1> 	call	floppy_drv_init
 15389 000045D8 72F3                <1> 	jc	short loc_ccdrv_fdinit_fail_retn
 15390                              <1> 
 15391 000045DA 28DB                <1> 	sub	bl, bl ; 0
 15392 000045DC 3B05[84790000]      <1> 	cmp	eax, [Current_VolSerial]
 15393 000045E2 7444                <1> 	je	short loc_change_current_drv2
 15394                              <1> 
 15395                              <1> loc_reset_drv_fd_current_dir:
 15396 000045E4 31C0                <1> 	xor	eax, eax              
 15397 000045E6 88467F              <1>         mov	[esi+LD_CDirLevel], al
 15398 000045E9 89F7                <1> 	mov	edi, esi
 15399 000045EB 81C780000000        <1> 	add	edi, LD_CurrentDirectory
 15400 000045F1 B920000000          <1> 	mov	ecx, 32
 15401 000045F6 F3AB                <1> 	rep	stosd   
 15402                              <1>  
 15403                              <1> loc_ccdrv_get_FAT_volume_name_0:
 15404 000045F8 8A4603              <1> 	mov	al, [esi+LD_FATType]
 15405 000045FB 08C0                <1> 	or	al, al
 15406 000045FD 7429                <1> 	jz	short loc_change_current_drv2
 15407                              <1> 
 15408 000045FF 56                  <1> 	push	esi 
 15409 00004600 3C02                <1> 	cmp	al, 2
 15410 00004602 7705                <1> 	ja	short loc_ccdrv_get_FAT32_vol_name
 15411                              <1>              
 15412                              <1> loc_ccdrv_get_FAT2_16_vol_name:
 15413 00004604 83C631              <1> 	add	esi, LD_BPB + VolumeLabel
 15414 00004607 EB03                <1> 	jmp	short loc_ccdrv_get_FAT_volume_name_1
 15415                              <1> 
 15416                              <1> loc_ccdrv_get_FAT32_vol_name:
 15417 00004609 83C64D              <1> 	add	esi, LD_BPB + FAT32_VolLab
 15418                              <1> loc_ccdrv_get_FAT_volume_name_1:
 15419 0000460C 53                  <1> 	push	ebx
 15420 0000460D 56                  <1> 	push	esi
 15421 0000460E E8C6FEFFFF          <1> 	call	get_FAT_volume_name
 15422 00004613 5F                  <1> 	pop	edi
 15423 00004614 5B                  <1> 	pop	ebx
 15424                              <1> 	; BL = 0
 15425 00004615 7211                <1> 	jc	short loc_change_current_drv2
 15426 00004617 20C0                <1> 	and	al, al
 15427 00004619 740D                <1> 	jz	short loc_change_current_drv2
 15428                              <1> 
 15429                              <1> loc_ccdrv_move_FAT_volume_name:
 15430 0000461B B90B000000          <1> 	mov	ecx, 11
 15431 00004620 F3A4                <1> 	rep	movsb
 15432 00004622 EB04                <1> 	jmp	short loc_change_current_drv2
 15433                              <1> 
 15434                              <1> loc_gmcs_init_drv_hd:
 15435 00004624 08E4                <1> 	or	ah, ah
 15436 00004626 7403                <1> 	jz	short loc_change_current_drv3
 15437                              <1> 	; BL = 0, BH = Logical DOS drive number
 15438                              <1> loc_change_current_drv2:
 15439 00004628 885E7E              <1> 	mov	[esi+LD_MediaChanged], bl
 15440                              <1> loc_change_current_drv3:
 15441 0000462B 883D[8E790000]      <1> 	mov	[Current_Drv], bh
 15442                              <1> 
 15443                              <1> 	;call	restore_current_directory
 15444                              <1> 	;retn
 15445                              <1> 
 15446                              <1> restore_current_directory:
 15447                              <1> 	; 15/01/2016 (TRDOS 386 = TRDOS v2.0)
 15448                              <1> 	; 25/01/2010
 15449                              <1> 	; 12/10/2009
 15450                              <1> 	;
 15451                              <1> 	; INPUT:
 15452                              <1> 	;   ESI = Logical DOS Drive Description Table
 15453                              <1> 	;
 15454                              <1> 	; OUTPUT:
 15455                              <1> 	;   ESI = Logical DOS Drive Description Table
 15456                              <1> 	;   EDI = offset Current_Dir_Drv 
 15457                              <1> 
 15458 00004631 8A4603              <1> 	mov	al, [esi+LD_FATType]
 15459 00004634 A2[8D790000]        <1> 	mov	[Current_FATType], al
 15460                              <1> 
 15461 00004639 8A26                <1> 	mov	ah, [esi+LD_Name] 
 15462 0000463B 8825[8F790000]      <1> 	mov	[Current_Dir_Drv], ah
 15463                              <1> 
 15464 00004641 20C0                <1> 	and	al, al
 15465 00004643 741D                <1> 	jz	short loc_restore_FS_current_directory
 15466                              <1> 
 15467                              <1> loc_restore_FAT_current_directory:
 15468 00004645 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
 15469 00004648 8825[8C790000]      <1> 	mov	[Current_Dir_Level], ah
 15470 0000464E 08E4                <1> 	or	ah, ah
 15471 00004650 7416                <1>         jz	short loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster
 15472                              <1> 
 15473 00004652 0FB6D4              <1> 	movzx	edx, ah
 15474 00004655 C0E204              <1> 	shl	dl, 4 ; * 16
 15475 00004658 01F2                <1>         add	edx, esi
 15476 0000465A 8B828C000000        <1> 	mov	eax, [edx+LD_CurrentDirectory+12]
 15477 00004660 EB2C                <1> 	jmp	short loc_ccdrv_reset_cdir_FAT_fcluster
 15478                              <1> 
 15479                              <1> loc_restore_FS_current_directory:
 15480 00004662 E8B90D0000          <1> 	call	load_current_FS_directory 
 15481 00004667 C3                  <1> 	retn 
 15482                              <1> 
 15483                              <1> loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster:
 15484 00004668 3C03                <1> 	cmp	al, 3
 15485 0000466A 7205                <1> 	jb	short loc_ccdrv_reset_cdir_FAT_12_16_fcluster
 15486                              <1> loc_ccdrv_reset_cdir_FAT32_fcluster:
 15487 0000466C 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
 15488 0000466F EB04                <1> 	jmp	short loc_ccdrv_check_rootdir_sign
 15489                              <1> loc_ccdrv_reset_cdir_FAT_12_16_fcluster:   
 15490 00004671 30C0                <1> 	xor	al, al  ; xor eax, eax
 15491 00004673 31D2                <1> 	xor	edx, edx
 15492                              <1> loc_ccdrv_check_rootdir_sign:
 15493 00004675 80BE8000000000      <1> 	cmp	byte [esi+LD_CurrentDirectory], 0
 15494 0000467C 7510                <1> 	jne	short loc_ccdrv_reset_cdir_FAT_fcluster
 15495                              <1> loc_ccdrv_set_rootdir_FAT_fcluster:
 15496 0000467E 89868C000000        <1>         mov     [esi+LD_CurrentDirectory+12], eax
 15497 00004684 C78680000000544F4F- <1> 	mov	dword [esi+LD_CurrentDirectory], 'TOOR'
 15498 0000468D 52                  <1>
 15499                              <1> 
 15500                              <1> loc_ccdrv_reset_cdir_FAT_fcluster:
 15501 0000468E A3[88790000]        <1> 	mov	[Current_Dir_FCluster], eax
 15502                              <1> 
 15503 00004693 BF[A4810000]        <1> 	mov	edi, PATH_Array
 15504 00004698 89F2                <1> 	mov	edx, esi
 15505 0000469A 81C680000000        <1> 	add	esi, LD_CurrentDirectory
 15506 000046A0 B920000000          <1> 	mov	ecx, 32
 15507 000046A5 F3A5                <1> 	rep	movsd
 15508                              <1> 
 15509 000046A7 E8780A0000          <1> 	call	change_prompt_dir_string
 15510                              <1>                
 15511 000046AC 89D6                <1> 	mov	esi, edx
 15512                              <1>                
 15513 000046AE 29C0                <1>         sub	eax, eax
 15514                              <1>        ;sub	edx, edx
 15515 000046B0 BF[8F790000]        <1> 	mov	edi, Current_Dir_Drv
 15516                              <1> 
 15517 000046B5 A2[A66D0000]        <1> 	mov	[Restore_CDIR], al ; 0
 15518 000046BA C3                  <1> 	retn
 15519                              <1> 
 15520                              <1> dos_prompt:
 15521                              <1> 	; 30/01/2016
 15522                              <1> 	; 29/01/2016
 15523                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
 15524                              <1> 	; 15/09/2011
 15525                              <1> 	; 13/09/2009
 15526                              <1> 	; 2004-2005
 15527                              <1> 
 15528                              <1> loc_TRDOS_prompt:
 15529 000046BB BF[407A0000]        <1> 	mov	edi, TextBuffer
 15530 000046C0 C6075B              <1> 	mov	byte [edi], "["
 15531 000046C3 47                  <1> 	inc	edi
 15532 000046C4 BE[F96D0000]        <1> 	mov	esi, TRDOSPromptLabel
 15533                              <1> get_next_prompt_label_char:
 15534 000046C9 803E20              <1> 	cmp	byte [esi], 20h
 15535 000046CC 7203                <1> 	jb	short pass_prompt_label
 15536 000046CE A4                  <1> 	movsb
 15537 000046CF EBF8                <1> 	jmp	short get_next_prompt_label_char
 15538                              <1> pass_prompt_label:
 15539 000046D1 C6075D              <1> 	mov	byte [edi], "]"
 15540 000046D4 47                  <1> 	inc	edi
 15541 000046D5 C60720              <1> 	mov	byte [edi], 20h
 15542 000046D8 47                  <1> 	inc	edi
 15543 000046D9 BE[8F790000]        <1> 	mov	esi, Current_Dir_Drv
 15544 000046DE 66A5                <1> 	movsw
 15545 000046E0 A4                  <1> 	movsb 
 15546                              <1> loc_prompt_current_directory:
 15547 000046E1 803E20              <1> 	cmp	byte [esi], 20h
 15548 000046E4 7203                <1> 	jb	short pass_prompt_current_directory
 15549 000046E6 A4                  <1> 	movsb
 15550 000046E7 EBF8                <1> 	jmp	short loc_prompt_current_directory  
 15551                              <1> pass_prompt_current_directory:
 15552 000046E9 C6073E              <1> 	mov	byte [edi], '>'
 15553 000046EC 47                  <1> 	inc	edi
 15554 000046ED C60700              <1> 	mov	byte [edi], 0  
 15555 000046F0 BE[407A0000]        <1> 	mov	esi, TextBuffer
 15556 000046F5 E8AAF5FFFF          <1> 	call	print_msg
 15557                              <1>         
 15558                              <1> 	;sub	bl, bl ; video page = 0
 15559                              <1> 	;call	get_cpos ; get cursor position
 15560 000046FA 668B15[E8780000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
 15561 00004701 8815[EE790000]      <1> 	mov	[CursorColumn], dl
 15562                              <1> 
 15563                              <1> 	; 30/01/2016 (to show cursor on the row, again)
 15564                              <1> 	; (Initial color attributes of video page 0 is 0)
 15565                              <1> 	; (see: 'StartPMP' in trdos386.s)
 15566                              <1> 	; 
 15567                              <1> 	;mov	edi, 0B8000h ; start of video page 0
 15568                              <1> 	;movzx	ecx, dl ; column	 
 15569                              <1> 	;mov	al, 80
 15570                              <1> 	;mul	dh
 15571                              <1> 	;add	ax, cx
 15572                              <1> 	;shl	ax, 1 ; character + attribute
 15573                              <1> 	;add	di, ax ; (2*80*row) + (2*column)
 15574                              <1> 	;neg	cl
 15575                              <1> 	;add	cl, 80
 15576                              <1> 	;mov	ax, 700h ;  ah = 7 (color attribute)
 15577                              <1> 	;rep	stosw	
 15578                              <1> 
 15579                              <1> loc_rw_char:
 15580 00004707 E899000000          <1> 	call	rw_char
 15581                              <1> loc_move_command:
 15582 0000470C BE[F0790000]        <1> 	mov	esi, CommandBuffer
 15583 00004711 89F7                <1> 	mov	edi, esi
 15584 00004713 31C9                <1> 	xor	ecx, ecx
 15585                              <1> first_command_char:
 15586 00004715 AC                  <1> 	lodsb
 15587 00004716 3C20                <1> 	cmp	al, 20h
 15588 00004718 772E                <1> 	ja	short pass_space_control
 15589 0000471A 7241                <1> 	jb	short loc_move_cmd_arguments_ok
 15590 0000471C 81FE[3F7A0000]      <1> 	cmp	esi, CommandBuffer + 79
 15591 00004722 72F1                <1> 	jb	short first_command_char
 15592 00004724 EB37                <1> 	jmp	short loc_move_cmd_arguments_ok
 15593                              <1> 
 15594                              <1> next_command_char:
 15595 00004726 AC                  <1> 	lodsb
 15596 00004727 3C20                <1> 	cmp	al, 20h
 15597 00004729 771D                <1> 	ja	short pass_space_control
 15598 0000472B 7230                <1> 	jb	short loc_move_cmd_arguments_ok
 15599                              <1> 
 15600                              <1> loc_1st_cmd_arg: ; 30/01/2016
 15601 0000472D AC                  <1> 	lodsb
 15602 0000472E 3C20                <1> 	cmp	al, 20h
 15603 00004730 74FB                <1> 	je	short loc_1st_cmd_arg
 15604 00004732 7229                <1> 	jb	short loc_move_cmd_arguments_ok
 15605                              <1> 	
 15606 00004734 C60700              <1>         mov     byte [edi], 0
 15607 00004737 47                  <1> 	inc	edi
 15608                              <1> 
 15609                              <1> loc_move_cmd_arguments:
 15610 00004738 AA                  <1> 	stosb
 15611 00004739 81FE[3F7A0000]      <1> 	cmp	esi, CommandBuffer + 79
 15612 0000473F 731C                <1> 	jnb	short loc_move_cmd_arguments_ok
 15613 00004741 AC                  <1>         lodsb
 15614 00004742 3C20                <1> 	cmp	al, 20h
 15615 00004744 73F2                <1> 	jnb	short loc_move_cmd_arguments
 15616 00004746 EB15                <1> 	jmp	short loc_move_cmd_arguments_ok
 15617                              <1> 
 15618                              <1> pass_space_control:
 15619 00004748 3C61                <1> 	cmp	al, 61h
 15620 0000474A 7206                <1> 	jb	short pass_capitalize
 15621 0000474C 3C7A                <1> 	cmp	al, 7Ah
 15622 0000474E 7702                <1> 	ja	short pass_capitalize
 15623 00004750 24DF                <1> 	and	al, 0DFh
 15624                              <1> pass_capitalize:
 15625 00004752 AA                  <1> 	stosb   
 15626 00004753 FEC1                <1> 	inc     cl
 15627 00004755 81FE[3F7A0000]      <1>         cmp     esi, CommandBuffer + 79
 15628 0000475B 72C9                <1> 	jb      short next_command_char 
 15629                              <1> 
 15630                              <1> loc_move_cmd_arguments_ok:
 15631 0000475D C60700              <1>         mov     byte [edi], 0
 15632                              <1>        
 15633                              <1> call_command_intepreter:
 15634 00004760 E8C5080000          <1> 	call    command_interpreter
 15635                              <1> 
 15636 00004765 B950000000          <1>         mov	ecx, 80
 15637                              <1> 	;mov	cx, 80
 15638 0000476A BF[F0790000]        <1> 	mov	edi, CommandBuffer
 15639 0000476F 30C0                <1> 	xor	al, al
 15640 00004771 F3AA                <1> 	rep	stosb
 15641                              <1> 	;cmp	byte [Program_Exit], 0
 15642                              <1> 	;ja	short loc_terminate_trdos
 15643                              <1>         
 15644                              <1> 	; 16/01/2016
 15645 00004773 803D[D6720000]03    <1> 	cmp	byte [CRT_MODE], 3 ; 80*25 color
 15646 0000477A 741D                <1> 	je	short pass_set_txt_mode
 15647                              <1> 
 15648 0000477C E8EBCDFFFF          <1> 	call	set_txt_mode ; set vide mode to 03h
 15649                              <1> 
 15650                              <1> loc_check_active_page:
 15651 00004781 30C0                <1> 	xor	al, al
 15652 00004783 3805[F8780000]      <1> 	cmp	[ACTIVE_PAGE], al ; 0
 15653 00004789 0F842CFFFFFF        <1>         je      loc_TRDOS_prompt 
 15654                              <1> 	; AL = 0 = video page 0
 15655 0000478F E872CEFFFF          <1> 	call	set_active_page
 15656 00004794 E922FFFFFF          <1>         jmp     loc_TRDOS_prompt ; infinitive loop
 15657                              <1> 
 15658                              <1> pass_set_txt_mode: 
 15659 00004799 BE[28750000]        <1> 	mov	esi, nextline
 15660 0000479E E801F5FFFF          <1> 	call	print_msg
 15661 000047A3 EBDC                <1> 	jmp     short loc_check_active_page
 15662                              <1> 
 15663                              <1> rw_char:
 15664                              <1> 	; 30/01/2016
 15665                              <1> 	; 29/01/2016
 15666                              <1> 	; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
 15667                              <1> 	; 2004-2005
 15668                              <1> 	
 15669                              <1> 	; DH = cursor row, DL = cursor column
 15670                              <1> 	; BL = 0 = video page number (active page)
 15671                              <1> 
 15672                              <1> readnextchar:
 15673 000047A5 30E4                <1> 	xor     ah, ah
 15674 000047A7 E8AEC4FFFF          <1> 	call	int16h
 15675 000047AC 20C0                <1> 	and	al, al
 15676 000047AE 7439                <1> 	jz	short loc_arrow    
 15677 000047B0 3CE0                <1> 	cmp	al, 0E0h          
 15678 000047B2 7435                <1> 	je	short loc_arrow
 15679 000047B4 3C08                <1> 	cmp	al, 08h             
 15680 000047B6 7549                <1> 	jne	short char_return
 15681                              <1> loc_back:
 15682 000047B8 3A15[EE790000]      <1> 	cmp	dl, [CursorColumn]
 15683 000047BE 76E5                <1> 	jna     short readnextchar
 15684                              <1> prev_column:
 15685 000047C0 FECA                <1> 	dec	dl
 15686                              <1> set_cursor_pos:
 15687 000047C2 6652                <1> 	push	dx
 15688 000047C4 30DB                <1> 	xor	bl, bl ; 0 = video page 0
 15689                              <1> 	; DH = Row, DL = Column
 15690 000047C6 E8F2D0FFFF          <1> 	call	_set_cpos ; 17/01/2016
 15691 000047CB 665A                <1>         pop	dx
 15692 000047CD 0FB6DA              <1> 	movzx	ebx, dl
 15693 000047D0 2A1D[EE790000]      <1> 	sub	bl, [CursorColumn] 
 15694 000047D6 B407                <1> 	mov	ah, 7 ; color attribute
 15695 000047D8 B020                <1> 	mov	al, 20h
 15696 000047DA 8883[F0790000]      <1> 	mov	[CommandBuffer+ebx], al
 15697 000047E0 28DB                <1> 	sub	bl, bl ; video page 0
 15698                              <1> 	;mov	cx, 1
 15699 000047E2 E811D0FFFF          <1> 	call	_write_c_current ; 17/01/2016
 15700                              <1> 	;mov	dx, [CURSOR_POSN]
 15701 000047E7 EBBC                <1> 	jmp	short readnextchar
 15702                              <1> loc_arrow:    
 15703 000047E9 80FC4B              <1> 	cmp	ah, 4Bh
 15704 000047EC 74CA                <1> 	je	short loc_back
 15705 000047EE 80FC53              <1> 	cmp	ah, 53h
 15706 000047F1 74C5                <1> 	je      short loc_back
 15707 000047F3 80FC4D              <1> 	cmp	ah, 4Dh
 15708 000047F6 75AD                <1> 	jne	short readnextchar
 15709 000047F8 80FA4F              <1> 	cmp	dl, 79
 15710 000047FB 73A8                <1> 	jnb	short readnextchar
 15711 000047FD FEC2                <1> 	inc	dl
 15712 000047FF EBC1                <1> 	jmp	short set_cursor_pos
 15713                              <1> char_return:
 15714 00004801 0FB6DA              <1> 	movzx	ebx, dl
 15715 00004804 2A1D[EE790000]      <1> 	sub	bl, [CursorColumn] 
 15716 0000480A 3C20                <1> 	cmp	al, 20h
 15717 0000480C 7220                <1> 	jb	short loc_escape
 15718 0000480E 8883[F0790000]      <1> 	mov	[CommandBuffer+ebx], al
 15719 00004814 28DB                <1> 	sub	bl, bl ; 0
 15720 00004816 80FA4F              <1> 	cmp	dl, 79
 15721 00004819 738A                <1> 	jnb	short readnextchar
 15722 0000481B B407                <1> 	mov	ah, 7 ; color attribute
 15723 0000481D E807D0FFFF          <1> 	call	WRITE_TTY
 15724 00004822 668B15[E8780000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
 15725 00004829 E977FFFFFF          <1>         jmp     readnextchar
 15726                              <1> loc_escape:
 15727 0000482E 3C1B                <1> 	cmp	al, 1Bh
 15728 00004830 741A                <1> 	je	short rw_char_retn
 15729                              <1> 	;
 15730 00004832 3C0D                <1> 	cmp	al, 0Dh ; CR
 15731 00004834 0F856BFFFFFF        <1>         jne     readnextchar
 15732 0000483A 30DB                <1> 	xor	bl, bl ; 0
 15733 0000483C B407                <1> 	mov	ah, 7 ; attribute/color
 15734 0000483E E8E6CFFFFF          <1> 	call	WRITE_TTY
 15735 00004843 B407                <1> 	mov	ah, 7 ; attribute/color
 15736 00004845 B00A                <1> 	mov	al, 0Ah ; LF
 15737 00004847 E8DDCFFFFF          <1> 	call	WRITE_TTY
 15738                              <1> rw_char_retn:
 15739 0000484C C3                  <1> 	retn
 15740                              <1> 
 15741                              <1> show_date:
 15742                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
 15743                              <1>         ; 2004-2005
 15744                              <1> 
 15745                              <1> 	;mov	ah, 04h
 15746                              <1> 	;call	int1Ah
 15747 0000484D E8E9F1FFFF          <1> 	call	RTC_40	; GET RTC DATE
 15748                              <1> 
 15749 00004852 88D0                <1> 	mov	al, dl
 15750 00004854 E8F8C3FFFF          <1>   	call	bcd_to_ascii
 15751 00004859 66A3[A76E0000]      <1> 	mov	[Day], ax
 15752                              <1> 
 15753 0000485F 88F0                <1> 	mov	al, dh
 15754 00004861 E8EBC3FFFF          <1>   	call	bcd_to_ascii
 15755 00004866 66A3[AA6E0000]      <1> 	mov	[Month], ax
 15756                              <1> 
 15757 0000486C 88E8                <1> 	mov	al, ch
 15758 0000486E E8DEC3FFFF          <1>   	call	bcd_to_ascii
 15759 00004873 66A3[AD6E0000]      <1> 	mov	[Century], ax
 15760                              <1> 
 15761 00004879 88C8                <1> 	mov	al, cl
 15762 0000487B E8D1C3FFFF          <1>   	call	bcd_to_ascii
 15763 00004880 66A3[AF6E0000]      <1> 	mov	word [Year], ax
 15764                              <1> 
 15765 00004886 BE[976E0000]        <1> 	mov	esi, Msg_Show_Date
 15766 0000488B E814F4FFFF          <1> 	call	print_msg
 15767                              <1> 
 15768 00004890 C3                  <1> 	retn
 15769                              <1> 
 15770                              <1> set_date:
 15771                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
 15772                              <1>         ; 2004-2005
 15773                              <1> 
 15774 00004891 BE[7B6E0000]        <1> 	mov	esi, Msg_Enter_Date
 15775 00004896 E809F4FFFF          <1> 	call	print_msg
 15776                              <1> 
 15777                              <1> loc_enter_day_1:
 15778 0000489B 30E4                <1> 	xor     ah, ah
 15779 0000489D E8B8C3FFFF          <1> 	call	int16h
 15780                              <1> 	; AL = ASCII Code of the Character
 15781 000048A2 3C0D                <1> 	cmp	al, 13
 15782 000048A4 0F84B7010000        <1> 	je	loc_set_date_retn
 15783 000048AA 3C1B                <1> 	cmp	al, 27
 15784 000048AC 0F84AF010000        <1> 	je	loc_set_date_retn
 15785 000048B2 A2[A76E0000]        <1> 	mov	[Day], al
 15786 000048B7 3C30                <1> 	cmp	al, '0'
 15787 000048B9 0F82AD010000        <1> 	jb	loc_set_date_stc_0
 15788 000048BF 3C33                <1> 	cmp	al, '3'
 15789 000048C1 0F87A5010000        <1> 	ja	loc_set_date_stc_0
 15790                              <1> 	;sub	bl, bl ; 0
 15791 000048C7 B407                <1> 	mov	ah, 7 ; attribute/color
 15792 000048C9 E85BCFFFFF          <1> 	call	WRITE_TTY
 15793                              <1> loc_enter_day_2:
 15794 000048CE 30E4                <1> 	xor     ah, ah
 15795 000048D0 E885C3FFFF          <1> 	call	int16h
 15796                              <1> 	; AL = ASCII Code of the Character
 15797 000048D5 3C1B                <1> 	cmp	al, 27
 15798 000048D7 0F8484010000        <1>         je      loc_set_date_retn
 15799 000048DD A2[A86E0000]        <1> 	mov	[Day+1], al
 15800 000048E2 3C30                <1> 	cmp	al, '0'
 15801 000048E4 0F828C010000        <1>         jb      loc_set_date_stc_1
 15802 000048EA 3C39                <1> 	cmp	al, '9'
 15803 000048EC 0F8784010000        <1>         ja      loc_set_date_stc_1
 15804 000048F2 803D[A76E0000]33    <1> 	cmp	byte [Day], '3'
 15805 000048F9 7208                <1> 	jb	short pass_set_day_31
 15806 000048FB 3C31                <1> 	cmp	al, '1'
 15807 000048FD 0F8773010000        <1>         ja      loc_set_date_stc_1
 15808                              <1> pass_set_day_31:
 15809                              <1> 	;sub	bl, bl ; 0
 15810 00004903 B407                <1> 	mov	ah, 7 ; attribute/color
 15811 00004905 E81FCFFFFF          <1> 	call	WRITE_TTY
 15812                              <1> loc_enter_separator_1:
 15813 0000490A 28E4                <1> 	sub     ah, ah ; 0
 15814 0000490C E849C3FFFF          <1> 	call	int16h
 15815                              <1> 	; AL = ASCII Code of the Character
 15816 00004911 3C1B                <1> 	cmp	al, 27
 15817 00004913 0F8448010000        <1>         je      loc_set_date_retn
 15818 00004919 3C2D                <1> 	cmp	al, '-'
 15819 0000491B 7408                <1> 	je	short pass_set_date_separator_1
 15820 0000491D 3C2F                <1> 	cmp	al, '/'
 15821 0000491F 0F856C010000        <1>         jne     loc_set_date_stc_2
 15822                              <1> pass_set_date_separator_1:
 15823                              <1> 	;xor	bl, bl ; 0
 15824 00004925 B407                <1> 	mov	ah, 7 ; attribute/color
 15825 00004927 E8FDCEFFFF          <1> 	call	WRITE_TTY
 15826                              <1> loc_enter_month_1:
 15827 0000492C 30E4                <1> 	xor     ah, ah ; 0
 15828 0000492E E827C3FFFF          <1> 	call	int16h
 15829                              <1> 	; AL = ASCII Code of the Character
 15830 00004933 3C1B                <1> 	cmp	al, 27
 15831 00004935 0F8426010000        <1>         je      loc_set_date_retn
 15832 0000493B A2[AA6E0000]        <1> 	mov	[Month], al
 15833 00004940 3C30                <1> 	cmp	al, '0'
 15834 00004942 0F8264010000        <1>         jb      loc_set_date_stc_3
 15835 00004948 3C31                <1> 	cmp	al, '1'
 15836 0000494A 0F875C010000        <1>         ja      loc_set_date_stc_3
 15837                              <1> 	;sub	bl, bl
 15838 00004950 B407                <1> 	mov	ah, 7 ; attribute/color
 15839 00004952 E8D2CEFFFF          <1> 	call	WRITE_TTY
 15840                              <1> loc_enter_month_2:
 15841 00004957 30E4                <1> 	xor     ah, ah
 15842 00004959 E8FCC2FFFF          <1> 	call	int16h
 15843                              <1> 	; AL = ASCII Code of the Character
 15844 0000495E 3C1B                <1> 	cmp	al, 27
 15845 00004960 0F84FB000000        <1>         je      loc_set_date_retn
 15846 00004966 A2[AB6E0000]        <1> 	mov	[Month+1], al
 15847 0000496B 3C30                <1> 	cmp	al, '0'
 15848 0000496D 0F8254010000        <1>         jb      loc_set_date_stc_4
 15849 00004973 3C39                <1> 	cmp	al, '9'
 15850 00004975 0F874C010000        <1>         ja      loc_set_date_stc_4
 15851 0000497B 803D[AA6E0000]31    <1> 	cmp	byte [Month], '1'
 15852 00004982 7208                <1> 	jb	short pass_set_month_12
 15853 00004984 3C32                <1> 	cmp	al, '2'
 15854 00004986 0F873B010000        <1>         ja      loc_set_date_stc_4
 15855                              <1> pass_set_month_12:
 15856                              <1> 	;sub	bl, bl
 15857 0000498C B407                <1> 	mov	ah, 7 ; attribute/color
 15858 0000498E E896CEFFFF          <1> 	call	WRITE_TTY
 15859                              <1> loc_enter_separator_2:
 15860 00004993 28E4                <1> 	sub     ah, ah
 15861 00004995 E8C0C2FFFF          <1> 	call	int16h
 15862                              <1> 	; AL = ASCII Code of the Character
 15863 0000499A 3C1B                <1> 	cmp	al, 27
 15864 0000499C 0F84BF000000        <1>         je      loc_set_date_retn
 15865 000049A2 3C2D                <1> 	cmp	al, '-'
 15866 000049A4 7408                <1> 	je	short pass_set_date_separator_2
 15867 000049A6 3C2F                <1> 	cmp	al, '/'
 15868 000049A8 0F8534010000        <1>         jne     loc_set_date_stc_5
 15869                              <1> pass_set_date_separator_2:
 15870                              <1> 	;xor	bl, bl
 15871 000049AE B407                <1> 	mov	ah, 7 ; attribute/color
 15872 000049B0 E874CEFFFF          <1> 	call	WRITE_TTY
 15873                              <1> loc_enter_year_1:
 15874 000049B5 30E4                <1> 	xor    ah, ah
 15875 000049B7 E89EC2FFFF          <1> 	call	int16h
 15876                              <1> 	; AL = ASCII Code of the Character
 15877 000049BC 3C1B                <1> 	cmp	al, 27
 15878 000049BE 0F849D000000        <1>         je      loc_set_date_retn
 15879 000049C4 A2[AF6E0000]        <1> 	mov	[Year], al
 15880 000049C9 3C30                <1> 	cmp	al, '0'
 15881 000049CB 0F822C010000        <1>         jb      loc_set_date_stc_6
 15882 000049D1 3C39                <1> 	cmp	al, '9'
 15883 000049D3 0F8724010000        <1>         ja      loc_set_date_stc_6
 15884                              <1> 	;sub	bl, bl
 15885 000049D9 B407                <1> 	mov	ah, 7 ; attribute/color
 15886 000049DB E849CEFFFF          <1> 	call	WRITE_TTY
 15887                              <1> loc_enter_year_2:
 15888 000049E0 30E4                <1> 	xor	ah, ah
 15889 000049E2 E873C2FFFF          <1> 	call	int16h
 15890                              <1> 	; AL = ASCII Code of the Character
 15891 000049E7 3C1B                <1> 	cmp	al, 27
 15892 000049E9 7476                <1> 	je	short loc_set_date_retn
 15893 000049EB A2[B06E0000]        <1> 	mov	byte [Year+1], al
 15894 000049F0 3C30                <1> 	cmp	al, '0'
 15895 000049F2 0F8220010000        <1>         jb      loc_set_date_stc_7
 15896 000049F8 3C39                <1> 	cmp	al, '9'
 15897 000049FA 0F8718010000        <1>         ja      loc_set_date_stc_7
 15898                              <1> 	;sub	bl, bl
 15899 00004A00 B407                <1> 	mov	ah, 7 ; attribute/color
 15900 00004A02 E822CEFFFF          <1> 	call	WRITE_TTY
 15901                              <1> loc_set_date_get_lchar_again:
 15902 00004A07 28E4                <1> 	sub	ah, ah ; 0
 15903 00004A09 E84CC2FFFF          <1> 	call	int16h
 15904                              <1> 	; AL = ASCII Code of the Character
 15905 00004A0E 3C0D                <1> 	cmp	al, 13 ; ENTER key
 15906 00004A10 7412                <1> 	je	short loc_set_date_progress
 15907 00004A12 3C1B                <1> 	cmp	al, 27 ; ESC key
 15908 00004A14 744B                <1> 	je	short loc_set_date_retn
 15909                              <1> 	;
 15910 00004A16 E82A010000          <1> 	call	check_for_backspace
 15911 00004A1B 75EA                <1> 	jne	short loc_set_date_get_lchar_again
 15912                              <1> 
 15913                              <1> loc_set_date_bs_8:
 15914 00004A1D E811010000          <1> 	call	write_backspace
 15915 00004A22 EBBC                <1> 	jmp	short loc_enter_year_2
 15916                              <1> 
 15917                              <1> loc_set_date_progress:
 15918                              <1> 	; Get Current Date
 15919                              <1> 	;mov	ah, 04h
 15920                              <1> 	;call	int1Ah
 15921 00004A24 E812F0FFFF          <1> 	call	RTC_40	; GET RTC DATE
 15922                              <1> 	; CH = century (in BCD)
 15923                              <1> 
 15924 00004A29 66A1[AF6E0000]      <1> 	mov	ax, [Year]
 15925 00004A2F 662D3030            <1> 	sub	ax, '00'
 15926 00004A33 C0E004              <1> 	shl	al, 4 ; * 16
 15927 00004A36 88C1                <1> 	mov	cl, al
 15928 00004A38 00E1                <1> 	add	cl, ah
 15929 00004A3A 66A1[AA6E0000]      <1> 	mov	ax, [Month]
 15930 00004A40 662D3030            <1> 	sub	ax, '00'
 15931 00004A44 C0E004              <1> 	shl	al, 4 ; * 16
 15932 00004A47 88C6                <1> 	mov	dh, al
 15933 00004A49 00E6                <1> 	add	dh, ah
 15934 00004A4B 66A1[A76E0000]      <1> 	mov	ax, [Day]
 15935 00004A51 662D3030            <1> 	sub	ax, '00'
 15936 00004A55 C0E004              <1> 	shl	al, 4 ; * 16
 15937 00004A58 88C2                <1> 	mov	dl, al
 15938 00004A5A 00E2                <1> 	add	dl, ah
 15939                              <1> 
 15940                              <1> 	;mov	ah, 05h
 15941                              <1> 	;call	int1Ah
 15942 00004A5C E807F0FFFF          <1> 	call	RTC_50	; SET RTC DATE
 15943                              <1> 
 15944                              <1> loc_set_date_retn:
 15945 00004A61 BE[28750000]        <1> 	mov	esi, nextline
 15946 00004A66 E839F2FFFF          <1> 	call	print_msg
 15947 00004A6B C3                  <1> 	retn
 15948                              <1> 
 15949                              <1> loc_set_date_stc_0:
 15950                              <1> 	;xor	bl, bl ; video page 0
 15951 00004A6C E896CEFFFF          <1> 	call	beeper ; BEEP !
 15952 00004A71 E925FEFFFF          <1>         jmp     loc_enter_day_1
 15953                              <1> loc_set_date_stc_1:
 15954 00004A76 E8CA000000          <1> 	call	check_for_backspace
 15955 00004A7B 740A                <1> 	je	short loc_set_date_bs_1
 15956                              <1> 	;xor	bl, bl ; video page 0
 15957 00004A7D E885CEFFFF          <1> 	call	beeper ; BEEP !
 15958 00004A82 E947FEFFFF          <1>         jmp     loc_enter_day_2
 15959                              <1> loc_set_date_bs_1:
 15960 00004A87 E8A7000000          <1> 	call	write_backspace
 15961 00004A8C E90AFEFFFF          <1>         jmp     loc_enter_day_1
 15962                              <1> loc_set_date_stc_2:
 15963 00004A91 E8AF000000          <1> 	call	check_for_backspace
 15964 00004A96 740A                <1> 	je	short loc_set_date_bs_2
 15965                              <1> 	;xor	bl, bl ; video page 0
 15966 00004A98 E86ACEFFFF          <1> 	call	beeper ; BEEP !
 15967 00004A9D E968FEFFFF          <1>         jmp     loc_enter_separator_1
 15968                              <1> loc_set_date_bs_2:
 15969 00004AA2 E88C000000          <1> 	call	write_backspace
 15970 00004AA7 E922FEFFFF          <1>         jmp     loc_enter_day_2
 15971                              <1> loc_set_date_stc_3:
 15972 00004AAC E894000000          <1> 	call	check_for_backspace	
 15973 00004AB1 740A                <1> 	je short loc_set_date_bs_3
 15974                              <1> 	;xor	bl, bl ; video page 0
 15975 00004AB3 E84FCEFFFF          <1> 	call	beeper ; BEEP !
 15976 00004AB8 E96FFEFFFF          <1>         jmp     loc_enter_month_1
 15977                              <1> loc_set_date_bs_3:
 15978 00004ABD E871000000          <1> 	call	write_backspace
 15979 00004AC2 E943FEFFFF          <1>         jmp     loc_enter_separator_1
 15980                              <1> loc_set_date_stc_4:
 15981 00004AC7 E879000000          <1> 	call	check_for_backspace	
 15982 00004ACC 740A                <1> 	je	short loc_set_date_bs_4
 15983                              <1> 	;xor	bl, bl ; video page 0
 15984 00004ACE E834CEFFFF          <1> 	call	beeper ; BEEP !
 15985 00004AD3 E97FFEFFFF          <1>         jmp     loc_enter_month_2
 15986                              <1> loc_set_date_bs_4:
 15987 00004AD8 E856000000          <1> 	call	write_backspace
 15988 00004ADD E94AFEFFFF          <1>         jmp     loc_enter_month_1
 15989                              <1> loc_set_date_stc_5:
 15990 00004AE2 E85E000000          <1> 	call	check_for_backspace
 15991 00004AE7 740A                <1> 	je	short loc_set_date_bs_5
 15992                              <1> 	;xor	bl, bl ; video page 0
 15993 00004AE9 E819CEFFFF          <1> 	call	beeper ; BEEP !
 15994 00004AEE E9A0FEFFFF          <1>         jmp     loc_enter_separator_2
 15995                              <1> loc_set_date_bs_5:
 15996 00004AF3 E83B000000          <1> 	call	write_backspace
 15997 00004AF8 E95AFEFFFF          <1>         jmp     loc_enter_month_2
 15998                              <1> loc_set_date_stc_6:
 15999 00004AFD E843000000          <1> 	call	check_for_backspace
 16000 00004B02 740A                <1>         je      short  loc_set_date_bs_6
 16001                              <1> 	;xor	bl, bl ; video page 0
 16002 00004B04 E8FECDFFFF          <1> 	call	beeper ; BEEP !
 16003 00004B09 E9A7FEFFFF          <1>         jmp     loc_enter_year_1
 16004                              <1> loc_set_date_bs_6:
 16005 00004B0E E820000000          <1> 	call	write_backspace
 16006 00004B13 E97BFEFFFF          <1>         jmp     loc_enter_separator_2
 16007                              <1> loc_set_date_stc_7:
 16008 00004B18 E828000000          <1> 	call	check_for_backspace
 16009 00004B1D 740A                <1> 	je	short loc_set_date_bs_7
 16010                              <1> 	;xor	bl, bl ; video page 0
 16011 00004B1F E8E3CDFFFF          <1> 	call	beeper ; BEEP !
 16012 00004B24 E9B7FEFFFF          <1>         jmp     loc_enter_year_2
 16013                              <1> loc_set_date_bs_7:
 16014 00004B29 E805000000          <1> 	call	write_backspace
 16015 00004B2E E982FEFFFF          <1>         jmp     loc_enter_year_1
 16016                              <1> 
 16017                              <1> write_backspace:
 16018                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
 16019 00004B33 B008                <1> 	mov	al, 08h ; BACKSPACE
 16020                              <1> 	;xor	bl, bl
 16021 00004B35 B407                <1> 	mov	ah, 7 ; attribute/color
 16022 00004B37 E8EDCCFFFF          <1> 	call	WRITE_TTY
 16023 00004B3C B020                <1> 	mov	al, 20h ; BLANK/SPACE char 
 16024                              <1> 	;xor	bl, bl
 16025 00004B3E B407                <1> 	mov	ah, 7 ; attribute/color
 16026                              <1> 	;call	_write_c_current
 16027                              <1> 	;retn
 16028 00004B40 E9B3CCFFFF          <1> 	jmp	_write_c_current
 16029                              <1> 
 16030                              <1> check_for_backspace:
 16031                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
 16032 00004B45 663D080E            <1> 	cmp	ax, 0E08h
 16033 00004B49 7410                <1> 	je	short cfbs_retn
 16034 00004B4B 663DE04B            <1> 	cmp	ax, 4BE0h
 16035 00004B4F 740A                <1> 	je	short cfbs_retn
 16036 00004B51 663D004B            <1> 	cmp	ax, 4B00h
 16037 00004B55 7404                <1> 	je	short cfbs_retn
 16038 00004B57 663DE053            <1> 	cmp	ax, 53E0h
 16039                              <1> cfbs_retn:
 16040 00004B5B C3                  <1> 	retn
 16041                              <1> 
 16042                              <1> show_time:
 16043                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
 16044                              <1>         ; 2004-2005
 16045                              <1> 
 16046                              <1> 	;mov	ah, 02h
 16047                              <1> 	;call	int1Ah
 16048 00004B5C E869EEFFFF          <1> 	call	RTC_20	; GET RTC TIME
 16049                              <1> 	
 16050 00004B61 88E8                <1> 	mov	al, ch
 16051 00004B63 E8E9C0FFFF          <1> 	call	bcd_to_ascii
 16052 00004B68 66A3[D56E0000]      <1> 	mov	[Hour], ax
 16053                              <1> 
 16054 00004B6E 88C8                <1> 	mov	al, cl
 16055 00004B70 E8DCC0FFFF          <1> 	call	bcd_to_ascii
 16056 00004B75 66A3[D86E0000]      <1> 	mov	[Minute], ax
 16057                              <1> 
 16058 00004B7B 88F0                <1> 	mov	al, dh
 16059 00004B7D E8CFC0FFFF          <1> 	call	bcd_to_ascii
 16060 00004B82 66A3[DB6E0000]      <1> 	mov	[Second], ax
 16061                              <1> 
 16062 00004B88 BE[C56E0000]        <1> 	mov	esi, Msg_Show_Time
 16063 00004B8D E812F1FFFF          <1> 	call	print_msg
 16064 00004B92 C3                  <1> 	retn
 16065                              <1> 
 16066                              <1> set_time:
 16067                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
 16068                              <1>         ; 2004-2005
 16069                              <1> 
 16070 00004B93 BE[B46E0000]        <1> 	mov 	esi, Msg_Enter_Time
 16071 00004B98 E807F1FFFF          <1> 	call	print_msg
 16072                              <1> 
 16073                              <1> loc_enter_hour_1:
 16074 00004B9D 30E4                <1> 	xor     ah, ah
 16075 00004B9F E8B6C0FFFF          <1> 	call	int16h
 16076                              <1> 	; AL = ASCII Code of the Character
 16077 00004BA4 3C0D                <1> 	cmp	al, 13 ; ENTER key
 16078 00004BA6 0F84AE010000        <1>         je      loc_set_time_retn
 16079 00004BAC 3C1B                <1> 	cmp	al, 27 ; ESC key
 16080 00004BAE 0F84A6010000        <1>         je      loc_set_time_retn
 16081 00004BB4 A2[D56E0000]        <1> 	mov	[Hour], al
 16082 00004BB9 3C30                <1> 	cmp	al, '0'
 16083 00004BBB 0F82A4010000        <1>         jb      loc_set_time_stc_0
 16084 00004BC1 3C32                <1> 	cmp	al, '2'
 16085 00004BC3 0F879C010000        <1>         ja      loc_set_time_stc_0
 16086                              <1> 	;sub	bl, bl ; 0
 16087 00004BC9 B407                <1> 	mov	ah, 7 ; attribute/color
 16088 00004BCB E859CCFFFF          <1> 	call	WRITE_TTY
 16089                              <1> loc_enter_hour_2:
 16090 00004BD0 30E4                <1> 	xor     ah, ah
 16091 00004BD2 E883C0FFFF          <1> 	call	int16h
 16092                              <1> 	; AL = ASCII Code of the Character
 16093 00004BD7 3C1B                <1> 	cmp	al, 27
 16094 00004BD9 0F847B010000        <1>         je      loc_set_time_retn
 16095 00004BDF A2[D66E0000]        <1> 	mov	[Hour+1], al
 16096 00004BE4 3C30                <1> 	cmp	al, '0'
 16097 00004BE6 0F8283010000        <1>         jb      loc_set_time_stc_1
 16098 00004BEC 3C39                <1> 	cmp	al, '9'
 16099 00004BEE 0F877B010000        <1> 	ja	loc_set_time_stc_1
 16100 00004BF4 803D[D56E0000]32    <1>         cmp     byte [Hour], '2'
 16101 00004BFB 7208                <1> 	jb	short pass_set_time_24
 16102 00004BFD 3C34                <1> 	cmp	al, '4'
 16103 00004BFF 0F876A010000        <1>         ja      loc_set_time_stc_1
 16104                              <1> pass_set_time_24:
 16105                              <1> 	;sub	bl, bl ; 0
 16106 00004C05 B407                <1> 	mov	ah, 7 ; attribute/color
 16107 00004C07 E81DCCFFFF          <1> 	call	WRITE_TTY
 16108                              <1> loc_enter_time_separator_1:
 16109 00004C0C 28E4                <1> 	sub    ah, ah ; 0
 16110 00004C0E E847C0FFFF          <1> 	call	int16h
 16111                              <1> 	; AL = ASCII Code of the Character
 16112 00004C13 3C1B                <1> 	cmp	al, 27
 16113 00004C15 0F843F010000        <1>         je      loc_set_time_retn
 16114 00004C1B 3C3A                <1> 	cmp	al, ':'
 16115 00004C1D 0F8567010000        <1>         jne     loc_set_time_stc_2
 16116                              <1> 	;xor	bl, bl
 16117 00004C23 B407                <1> 	mov	ah, 7 ; attribute/color
 16118 00004C25 E8FFCBFFFF          <1> 	call	WRITE_TTY
 16119                              <1> loc_enter_minute_1:
 16120 00004C2A 30E4                <1> 	xor     ah, ah
 16121 00004C2C E829C0FFFF          <1> 	call	int16h
 16122                              <1> 	; AL = ASCII Code of the Character
 16123 00004C31 3C1B                <1> 	cmp	al, 27
 16124 00004C33 0F8421010000        <1>         je      loc_set_time_retn
 16125 00004C39 A2[D86E0000]        <1> 	mov	[Minute], al
 16126 00004C3E 3C30                <1> 	cmp	al, '0'
 16127 00004C40 0F825F010000        <1>         jb      loc_set_time_stc_3
 16128 00004C46 3C35                <1> 	cmp	al, '5'
 16129 00004C48 0F8757010000        <1>         ja      loc_set_time_stc_3
 16130                              <1> 	;sub	bl, bl
 16131 00004C4E B407                <1> 	mov	ah, 7 ; attribute/color
 16132 00004C50 E8D4CBFFFF          <1> 	call	WRITE_TTY
 16133                              <1> loc_enter_minute_2:
 16134 00004C55 30E4                <1> 	xor     ah, ah
 16135 00004C57 E8FEBFFFFF          <1> 	call	int16h
 16136                              <1> 	; AL = ASCII Code of the Character
 16137 00004C5C 3C1B                <1> 	cmp	al, 27
 16138 00004C5E 0F84F6000000        <1>         je      loc_set_time_retn
 16139 00004C64 A2[D96E0000]        <1> 	mov	[Minute+1], al
 16140 00004C69 3C30                <1> 	cmp	al, '0'
 16141 00004C6B 0F824F010000        <1>         jb      loc_set_time_stc_4
 16142 00004C71 3C39                <1> 	cmp	al, '9'
 16143 00004C73 0F8747010000        <1>         ja      loc_set_time_stc_4
 16144                              <1> 	;sub	bl, bl
 16145 00004C79 B407                <1> 	mov	ah, 7 ; attribute/color
 16146 00004C7B E8A9CBFFFF          <1> 	call	WRITE_TTY
 16147                              <1> loc_enter_time_separator_2:
 16148 00004C80 66C705[DB6E0000]30- <1> 	mov	word [Second], 3030h
 16149 00004C88 30                  <1>
 16150 00004C89 28E4                <1> 	sub     ah, ah
 16151 00004C8B E8CABFFFFF          <1> 	call	int16h
 16152                              <1> 	; AL = ASCII Code of the Character
 16153 00004C90 3C0D                <1> 	cmp	al, 13
 16154 00004C92 0F8485000000        <1>         je      loc_set_time_progress
 16155 00004C98 3C1B                <1> 	cmp	al, 27
 16156 00004C9A 0F84BA000000        <1>         je      loc_set_time_retn
 16157 00004CA0 3C3A                <1> 	cmp	al, ':'
 16158 00004CA2 0F8533010000        <1>         jne     loc_set_time_stc_5
 16159                              <1> 	;xor	bl, bl
 16160 00004CA8 B407                <1> 	mov	ah, 7 ; attribute/color
 16161 00004CAA E87ACBFFFF          <1> 	call	WRITE_TTY
 16162                              <1> loc_enter_second_1:
 16163 00004CAF 30E4                <1> 	xor     ah, ah
 16164 00004CB1 E8A4BFFFFF          <1> 	call	int16h
 16165                              <1> 	; AL = ASCII Code of the Character
 16166 00004CB6 3C0D                <1> 	cmp	al, 13
 16167 00004CB8 7463                <1> 	je	short loc_set_time_progress
 16168 00004CBA 3C1B                <1> 	cmp	al, 27
 16169 00004CBC 0F8498000000        <1>         je      loc_set_time_retn
 16170 00004CC2 A2[DB6E0000]        <1> 	mov	[Second], al
 16171 00004CC7 3C30                <1> 	cmp	al, '0'
 16172 00004CC9 0F8227010000        <1>         jb      loc_set_time_stc_6
 16173 00004CCF 3C35                <1> 	cmp	al, '5'
 16174 00004CD1 0F871F010000        <1>         ja      loc_set_time_stc_6
 16175                              <1> 	;sub	bl, bl
 16176 00004CD7 B407                <1> 	mov	ah, 7 ; attribute/color
 16177 00004CD9 E84BCBFFFF          <1> 	call	WRITE_TTY
 16178                              <1> loc_enter_second_2:
 16179 00004CDE 30E4                <1> 	xor     ah, ah
 16180 00004CE0 E875BFFFFF          <1> 	call	int16h
 16181                              <1> 	; AL = ASCII Code of the Character
 16182 00004CE5 3C1B                <1> 	cmp	al, 27
 16183 00004CE7 7471                <1> 	je	short loc_set_time_retn
 16184 00004CE9 3C30                <1> 	cmp	al, '0'
 16185 00004CEB 0F8229010000        <1>         jb      loc_set_time_stc_7
 16186 00004CF1 3C39                <1> 	cmp	al, '9'
 16187 00004CF3 0F8721010000        <1>         ja      loc_set_time_stc_7
 16188                              <1> 	;sub	bl, bl
 16189 00004CF9 B407                <1> 	mov	ah, 7 ; attribute/color
 16190 00004CFB E829CBFFFF          <1> 	call	WRITE_TTY
 16191                              <1> loc_set_time_get_lchar_again:
 16192 00004D00 28E4                <1> 	sub	ah, ah ; 0
 16193 00004D02 E853BFFFFF          <1> 	call	int16h
 16194                              <1> 	; AL = ASCII Code of the Character
 16195 00004D07 3C0D                <1> 	cmp	al, 13
 16196 00004D09 7412                <1> 	je	short loc_set_time_progress
 16197 00004D0B 3C1B                <1> 	cmp	al, 27
 16198 00004D0D 744B                <1> 	je	short loc_set_time_retn
 16199                              <1> 	;
 16200 00004D0F E831FEFFFF          <1> 	call	check_for_backspace
 16201 00004D14 75EA                <1> 	jne	short loc_set_time_get_lchar_again
 16202                              <1> 
 16203                              <1> loc_set_time_bs_8:
 16204 00004D16 E818FEFFFF          <1> 	call	write_backspace
 16205 00004D1B EBC1                <1> 	jmp	short loc_enter_second_2
 16206                              <1> 
 16207                              <1> loc_set_time_progress:
 16208                              <1> 	; Get Current Time
 16209                              <1> 	;mov 	ah, 02h
 16210                              <1> 	;call	int1Ah
 16211 00004D1D E8A8ECFFFF          <1> 	call	RTC_20	; GET RTC TIME
 16212                              <1> 	;DL = Daylight Savings Enable option (0-1)	
 16213                              <1> 
 16214 00004D22 66A1[D56E0000]      <1> 	mov	ax, [Hour]
 16215 00004D28 662D3030            <1> 	sub	ax, '00'
 16216 00004D2C C0E004              <1> 	shl	al, 4 ; * 16
 16217 00004D2F 88C5                <1> 	mov	ch, al
 16218 00004D31 00E5                <1> 	add	ch, ah
 16219 00004D33 66A1[D86E0000]      <1> 	mov	ax, [Minute]
 16220 00004D39 662D3030            <1> 	sub	ax, '00'
 16221 00004D3D C0E004              <1> 	shl	al, 4 ; * 16
 16222 00004D40 88C1                <1> 	mov	cl, al
 16223 00004D42 00E1                <1> 	add	cl, ah
 16224 00004D44 66A1[DB6E0000]      <1> 	mov	ax, [Second]
 16225 00004D4A 662D3030            <1> 	sub	ax, '00'
 16226 00004D4E C0E004              <1> 	shl	al, 4 ; * 16
 16227 00004D51 88C6                <1> 	mov	dh, al
 16228 00004D53 00E6                <1> 	add	dh, ah
 16229                              <1> 	
 16230                              <1> 	;mov	ah, 03h
 16231                              <1> 	;call	int1Ah
 16232 00004D55 E89FECFFFF          <1> 	call	RTC_30	; SET RTC TIME
 16233                              <1> 
 16234                              <1> loc_set_time_retn:
 16235 00004D5A BE[28750000]        <1> 	mov 	esi, nextline
 16236 00004D5F E840EFFFFF          <1> 	call	print_msg
 16237 00004D64 C3                  <1> 	retn
 16238                              <1> 
 16239                              <1> loc_set_time_stc_0:
 16240                              <1> 	;xor	bl, bl ; video page 0
 16241 00004D65 E89DCBFFFF          <1> 	call	beeper ; BEEP !
 16242 00004D6A E92EFEFFFF          <1>         jmp     loc_enter_hour_1
 16243                              <1> loc_set_time_stc_1:
 16244 00004D6F E8D1FDFFFF          <1> 	call	check_for_backspace
 16245 00004D74 740A                <1> 	je	short loc_set_time_bs_1
 16246                              <1> 	;xor	bl, bl ; video page 0
 16247 00004D76 E88CCBFFFF          <1> 	call	beeper ; BEEP !
 16248 00004D7B E950FEFFFF          <1>         jmp     loc_enter_hour_2
 16249                              <1> loc_set_time_bs_1:
 16250 00004D80 E8AEFDFFFF          <1> 	call	write_backspace
 16251 00004D85 E913FEFFFF          <1>         jmp     loc_enter_hour_1
 16252                              <1> loc_set_time_stc_2:
 16253 00004D8A E8B6FDFFFF          <1> 	call	check_for_backspace
 16254 00004D8F 740A                <1> 	je	short loc_set_time_bs_2
 16255                              <1> 	;xor	bl, bl ; video page 0
 16256 00004D91 E871CBFFFF          <1> 	call	beeper ; BEEP !
 16257 00004D96 E971FEFFFF          <1>         jmp     loc_enter_time_separator_1
 16258                              <1> loc_set_time_bs_2:
 16259 00004D9B E893FDFFFF          <1> 	call	write_backspace
 16260 00004DA0 E92BFEFFFF          <1>         jmp     loc_enter_hour_2
 16261                              <1> loc_set_time_stc_3:
 16262 00004DA5 E89BFDFFFF          <1> 	call	check_for_backspace
 16263 00004DAA 740A                <1> 	je	short loc_set_time_bs_3
 16264                              <1> 	;xor	bl, bl ; video page 0
 16265 00004DAC E856CBFFFF          <1> 	call	beeper ; BEEP !6
 16266 00004DB1 E974FEFFFF          <1>         jmp     loc_enter_minute_1
 16267                              <1> loc_set_time_bs_3:
 16268 00004DB6 E878FDFFFF          <1> 	call	write_backspace
 16269 00004DBB E94CFEFFFF          <1>         jmp     loc_enter_time_separator_1
 16270                              <1> loc_set_time_stc_4:
 16271 00004DC0 E880FDFFFF          <1> 	call	check_for_backspace
 16272 00004DC5 740A                <1> 	je	short loc_set_time_bs_4
 16273                              <1> 	;xor	bl, bl ; video page 0
 16274 00004DC7 E83BCBFFFF          <1> 	call	beeper ; BEEP !
 16275 00004DCC E984FEFFFF          <1>         jmp     loc_enter_minute_2
 16276                              <1> loc_set_time_bs_4:
 16277 00004DD1 E85DFDFFFF          <1> 	call	write_backspace
 16278 00004DD6 E94FFEFFFF          <1>         jmp     loc_enter_minute_1
 16279                              <1> loc_set_time_stc_5:
 16280 00004DDB E865FDFFFF          <1> 	call	check_for_backspace
 16281 00004DE0 740A                <1> 	je	short loc_set_time_bs_5
 16282                              <1> 	;xor	bl, bl ; video page 0
 16283 00004DE2 E820CBFFFF          <1> 	call	beeper ; BEEP !
 16284 00004DE7 E994FEFFFF          <1>         jmp     loc_enter_time_separator_2
 16285                              <1> loc_set_time_bs_5:
 16286 00004DEC E842FDFFFF          <1> 	call	write_backspace
 16287 00004DF1 E95FFEFFFF          <1>         jmp     loc_enter_minute_2
 16288                              <1> loc_set_time_stc_6:
 16289 00004DF6 E84AFDFFFF          <1> 	call	check_for_backspace
 16290 00004DFB 7413                <1> 	je	short loc_set_time_bs_6
 16291                              <1> 	;xor	bl, bl ; video page 0
 16292 00004DFD E805CBFFFF          <1> 	call	beeper ; BEEP !
 16293 00004E02 66C705[DB6E0000]30- <1> 	mov	word [Second], 3030h
 16294 00004E0A 30                  <1>
 16295 00004E0B E99FFEFFFF          <1>         jmp     loc_enter_second_1
 16296                              <1> loc_set_time_bs_6:
 16297 00004E10 E81EFDFFFF          <1> 	call	write_backspace
 16298 00004E15 E966FEFFFF          <1>         jmp     loc_enter_time_separator_2
 16299                              <1> loc_set_time_stc_7:
 16300 00004E1A E826FDFFFF          <1> 	call	check_for_backspace
 16301 00004E1F 740A                <1> 	je	short loc_set_time_bs_7
 16302                              <1> 	;xor	bl, bl ; video page 0
 16303 00004E21 E8E1CAFFFF          <1> 	call	beeper ; BEEP !
 16304 00004E26 E9B3FEFFFF          <1>         jmp     loc_enter_second_2
 16305                              <1> loc_set_time_bs_7:
 16306 00004E2B E803FDFFFF          <1> 	call	write_backspace
 16307 00004E30 E97AFEFFFF          <1>         jmp     loc_enter_second_1
 16308                              <1> 
 16309                              <1> print_volume_info:
 16310                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
 16311                              <1> 	; 25/10/2009
 16312                              <1> 	;
 16313                              <1> 	; "Volume Serial No: "
 16314                              <1>  	;
 16315                              <1> 	; INPUT  : AL = DOS Drive Number
 16316                              <1> 	; OUTPUT : AH = FS Type
 16317                              <1> 	;          AL = DOS Drive Name
 16318                              <1> 	; CF = 0 -> OK
 16319                              <1> 	; CF = 1 -> Drive not ready 
 16320                              <1> 
 16321 00004E35 0FB6F0              <1> 	movzx	esi, al
 16322 00004E38 81C600010900        <1> 	add	esi, Logical_DOSDisks
 16323 00004E3E 8A06                <1> 	mov	al, [esi]
 16324 00004E40 3C41                <1> 	cmp	al, 'A'  
 16325 00004E42 7304                <1> 	jnb	short loc_pvi_reset_vol_name
 16326 00004E44 8A6604              <1> 	mov	ah, [esi+LD_FSType]
 16327 00004E47 C3                  <1> 	retn
 16328                              <1> 
 16329                              <1> loc_pvi_reset_vol_name:
 16330 00004E48 A2[0F6F0000]        <1> 	mov	[Vol_Drv_Name], al
 16331 00004E4D B910000000          <1> 	mov	ecx, 16
 16332 00004E52 BF[176F0000]        <1> 	mov	edi, Vol_Vol_Name
 16333 00004E57 57                  <1> 	push	edi
 16334 00004E58 B820202020          <1> 	mov	eax, 20202020h
 16335 00004E5D F3AB                <1> 	rep	stosd 
 16336 00004E5F 5F                  <1> 	pop	edi
 16337                              <1> 	;
 16338 00004E60 56                  <1> 	push	esi
 16339                              <1> 	;mov	ah, [esi+LD_FSType]
 16340                              <1> 	;mov	al, [esi+LD_FATType]
 16341 00004E61 668B4603            <1> 	mov	ax, [esi+LD_FATType]
 16342 00004E65 80FCA1              <1> 	cmp	ah, 0A1h
 16343 00004E68 740D                <1> 	je	short loc_pvi_mov_fs_vol_name
 16344 00004E6A 08E4                <1> 	or	ah, ah
 16345 00004E6C 7404                <1> 	jz	short loc_pvi_pop_si_stc_retn 
 16346 00004E6E 08C0                <1> 	or	al, al
 16347 00004E70 750C                <1> 	jnz	short loc_pass_mov_vol_name_0
 16348                              <1> loc_pvi_pop_si_stc_retn:
 16349 00004E72 5E                  <1> 	pop	esi
 16350 00004E73 8A06                <1> 	mov	al, [esi]
 16351 00004E75 F9                  <1> 	stc
 16352 00004E76 C3                  <1> 	retn
 16353                              <1>                
 16354                              <1> loc_pvi_mov_fs_vol_name:
 16355 00004E77 83C62C              <1> 	add	esi, LD_FS_VolumeName
 16356                              <1> 	;mov	ecx, 64
 16357 00004E7A B140                <1> 	mov	cl, 64
 16358 00004E7C EB20                <1> 	jmp	short loc_vol_move_volume_name
 16359                              <1> loc_pass_mov_vol_name_0:
 16360                              <1> 	;mov	ecx, 11
 16361 00004E7E B10B                <1> 	mov	cl, 11  
 16362 00004E80 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
 16363 00004E84 770D                <1> 	ja	short loc_pass_mov_vol_name_2
 16364 00004E86 8B462D              <1> 	mov	eax, [esi+LD_BPB+VolumeID]
 16365 00004E89 A3[84790000]        <1> 	mov	[Current_VolSerial], eax  
 16366 00004E8E 83C631              <1> 	add	esi, LD_BPB+VolumeLabel
 16367 00004E91 EB0B                <1> 	jmp	short loc_vol_move_volume_name
 16368                              <1> loc_pass_mov_vol_name_2:
 16369 00004E93 8B4649              <1> 	mov	eax, [esi+LD_BPB+FAT32_VolID]
 16370 00004E96 A3[84790000]        <1> 	mov	[Current_VolSerial], eax  
 16371 00004E9B 83C64D              <1> 	add	esi, LD_BPB+FAT32_VolLab
 16372                              <1> loc_vol_move_volume_name:
 16373 00004E9E AC                  <1> 	lodsb
 16374 00004E9F 84C0                <1> 	test	al, al
 16375 00004EA1 7403                <1> 	jz	short pass_vol_move_volume_name 
 16376 00004EA3 AA                  <1> 	stosb
 16377 00004EA4 E2F8                <1> 	loop	loc_vol_move_volume_name
 16378                              <1> pass_vol_move_volume_name:
 16379                              <1> 	;pop	esi
 16380                              <1> 	;push	esi
 16381 00004EA6 8B3424              <1> 	mov	esi, [esp]
 16382 00004EA9 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
 16383 00004EAD 7511                <1> 	jne	short loc_pvi_fat_vol_size
 16384 00004EAF 8B4628              <1> 	mov	eax, [esi+LD_FS_VolumeSerial]
 16385 00004EB2 A3[84790000]        <1> 	mov	[Current_VolSerial], eax  
 16386 00004EB7 8B4670              <1> 	mov	eax, [esi+LD_FS_VolumeSize]
 16387 00004EBA 0FB75E11            <1> 	movzx	ebx, word [esi+LD_FS_BytesPerSec]
 16388 00004EBE EB07                <1> 	jmp	short loc_vol_size_mul32
 16389                              <1> loc_pvi_fat_vol_size:
 16390 00004EC0 8B4670              <1> 	mov	eax, [esi+LD_TotalSectors]
 16391 00004EC3 0FB75E11            <1> 	movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
 16392                              <1> loc_vol_size_mul32:
 16393 00004EC7 F7E3                <1> 	mul	ebx
 16394 00004EC9 09D2                <1> 	or	edx, edx
 16395 00004ECB 7507                <1> 	jnz	short loc_vol_size_in_kbytes
 16396                              <1> loc_vol_size_in_bytes:
 16397 00004ECD B9[ED6E0000]        <1> 	mov	ecx, VolSize_Bytes
 16398 00004ED2 EB0D                <1> 	jmp	short loc_write_vol_size_str
 16399                              <1> loc_vol_size_in_kbytes:
 16400 00004ED4 66BB0004            <1> 	mov	bx, 1024
 16401 00004ED8 F7F3                <1> 	div	ebx
 16402 00004EDA B9[E06E0000]        <1> 	mov 	ecx, VolSize_KiloBytes
 16403 00004EDF 31D2                <1> 	xor	edx, edx ; 0
 16404                              <1> loc_write_vol_size_str:
 16405 00004EE1 890D[7C810000]      <1> 	mov	[VolSize_Unit1], ecx
 16406                              <1> 	; 
 16407 00004EE7 BF[92810000]        <1> 	mov	edi, Vol_Tot_Sec_Str_End
 16408                              <1>         ;mov	byte [edi], 0
 16409 00004EEC B90A000000          <1> 	mov	ecx, 10
 16410                              <1> loc_write_vol_size_chr:
 16411 00004EF1 F7F1                <1> 	div	ecx
 16412 00004EF3 80C230              <1> 	add	dl, '0'
 16413 00004EF6 4F                  <1> 	dec	edi	
 16414 00004EF7 8817                <1> 	mov	[edi], dl
 16415 00004EF9 85C0                <1> 	test	eax, eax
 16416 00004EFB 7404                <1> 	jz	short loc_write_vol_size_str_ok
 16417 00004EFD 28D2                <1> 	sub	dl, dl ; 0
 16418 00004EFF EBF0                <1> 	jmp	short loc_write_vol_size_chr
 16419                              <1> 
 16420                              <1> loc_write_vol_size_str_ok:
 16421 00004F01 893D[84810000]      <1> 	mov	[Vol_Tot_Sec_Str_Start], edi
 16422                              <1> 	;
 16423 00004F07 BF[F86E0000]        <1> 	mov	edi, Vol_FS_Name
 16424 00004F0C 8A4E03              <1> 	mov	cl, [esi+LD_FATType]
 16425 00004F0F 20C9                <1> 	and	cl, cl ; 0 ?
 16426 00004F11 7515                <1> 	jnz	short loc_write_vol_FAT_str_1
 16427 00004F13 66C7075254          <1> 	mov	word [edi], 'RT'
 16428 00004F18 C7470431534620      <1> 	mov	dword [edi+4], '1SF '
 16429                              <1> 	;movzx	ebx, word [esi+LD_FS_BytesPerSec]
 16430 00004F1F 668B5E11            <1> 	mov	bx, [esi+LD_FS_BytesPerSec]
 16431 00004F23 8B4674              <1> 	mov	eax, [esi+LD_FS_FreeSectors]
 16432 00004F26 EB22                <1> 	jmp	short loc_vol_freespace_mul32
 16433                              <1> 
 16434                              <1> loc_write_vol_FAT_str_1:
 16435 00004F28 66B83233            <1> 	mov	ax, '23' ; FAT32
 16436 00004F2C 80F902              <1> 	cmp	cl, 2 ; [esi+LD_FATType]
 16437 00004F2F 7708                <1> 	ja	short loc_write_vol_FAT_str_2
 16438 00004F31 66B83231            <1> 	mov	ax, '21' ; FAT12
 16439 00004F35 7202                <1> 	jb	short loc_write_vol_FAT_str_2
 16440 00004F37 B436                <1> 	mov	ah, '6'  ; FAT16
 16441                              <1> loc_write_vol_FAT_str_2:
 16442 00004F39 C70720544146        <1> 	mov	dword [edi], ' TAF'
 16443 00004F3F 66894704            <1> 	mov	word [edi+4], ax
 16444                              <1> 	;
 16445                              <1> 	;movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
 16446 00004F43 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec]
 16447 00004F47 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
 16448                              <1> 
 16449                              <1> loc_vol_freespace_mul32:
 16450 00004F4A F7E3                <1> 	mul	ebx
 16451 00004F4C 09D2                <1> 	or	edx, edx
 16452 00004F4E 7507                <1> 	jnz	short loc_vol_fspace_in_kbytes
 16453                              <1> loc_vol_fspace_in_bytes:
 16454 00004F50 B9[ED6E0000]        <1> 	mov	ecx, VolSize_Bytes
 16455 00004F55 EB0D                <1> 	jmp	short loc_write_vol_fspace_str
 16456                              <1> loc_vol_fspace_in_kbytes:
 16457 00004F57 66BB0004            <1> 	mov	bx, 1024
 16458 00004F5B F7F3                <1> 	div	ebx
 16459 00004F5D B9[E06E0000]        <1> 	mov 	ecx, VolSize_KiloBytes
 16460 00004F62 31D2                <1> 	xor	edx, edx ; 0
 16461                              <1> loc_write_vol_fspace_str:
 16462 00004F64 890D[80810000]      <1> 	mov	[VolSize_Unit2], ecx
 16463                              <1> 	;	
 16464 00004F6A BF[A2810000]        <1> 	mov	edi, Vol_Free_Sectors_Str_End
 16465                              <1>         ;mov	byte [edi], 0
 16466 00004F6F B90A000000          <1> 	mov	ecx, 10
 16467                              <1> loc_write_vol_fspace_chr:
 16468 00004F74 F7F1                <1> 	div	ecx
 16469 00004F76 80C230              <1> 	add	dl, '0'
 16470 00004F79 4F                  <1> 	dec	edi	
 16471 00004F7A 8817                <1> 	mov	[edi], dl
 16472 00004F7C 85C0                <1> 	test	eax, eax
 16473 00004F7E 7404                <1> 	jz	short loc_write_vol_fspace_str_ok
 16474 00004F80 28D2                <1> 	sub	dl, dl ; 0
 16475 00004F82 EBF0                <1> 	jmp	short loc_write_vol_fspace_chr
 16476                              <1> 
 16477                              <1> loc_write_vol_fspace_str_ok:
 16478 00004F84 893D[94810000]      <1> 	mov	[Vol_Free_Sectors_Str_Start], edi
 16479                              <1> 	;
 16480 00004F8A A1[84790000]        <1> 	mov	eax, [Current_VolSerial]
 16481 00004F8F E8C5CAFFFF          <1> 	call	dwordtohex
 16482 00004F94 8915[726F0000]      <1> 	mov  	[Vol_Vol_Serial1], edx
 16483 00004F9A A3[6D6F0000]        <1> 	mov  	[Vol_Vol_Serial2], eax	
 16484                              <1> 	;
 16485 00004F9F BE[F66E0000]        <1> 	mov	esi, Volume_in_drive
 16486 00004FA4 E8FBECFFFF          <1> 	call	print_msg
 16487                              <1> 	;
 16488 00004FA9 BE[796F0000]        <1> 	mov	esi, Vol_Total_Sector_Header
 16489 00004FAE E8F1ECFFFF          <1> 	call	print_msg
 16490 00004FB3 8B35[84810000]      <1> 	mov	esi, [Vol_Tot_Sec_Str_Start]
 16491 00004FB9 E8E6ECFFFF          <1> 	call	print_msg
 16492 00004FBE 8B35[7C810000]      <1> 	mov	esi, [VolSize_Unit1]
 16493 00004FC4 E8DBECFFFF          <1> 	call	print_msg
 16494                              <1> 	;
 16495 00004FC9 BE[8A6F0000]        <1> 	mov	esi, Vol_Free_Sectors_Header
 16496 00004FCE E8D1ECFFFF          <1> 	call	print_msg
 16497 00004FD3 8B35[94810000]      <1> 	mov	esi, [Vol_Free_Sectors_Str_Start]
 16498 00004FD9 E8C6ECFFFF          <1> 	call	print_msg
 16499 00004FDE 8B35[80810000]      <1> 	mov	esi, [VolSize_Unit2]
 16500 00004FE4 E8BBECFFFF          <1> 	call	print_msg
 16501                              <1> 	;
 16502 00004FE9 5E                  <1> 	pop	esi
 16503                              <1> 	
 16504                              <1> 	;mov	ah, [esi+LD_FSType]
 16505                              <1> 	;mov	al, [esi+LD_FATType]
 16506 00004FEA 668B4603            <1> 	mov	ax, [esi+LD_FATType]
 16507                              <1> 
 16508 00004FEE C3                  <1> 	retn
 16509                              <1> 
 16510                              <1> get_volume_serial_number:
 16511                              <1> 	; 19/01/2016 (TRDOS 386 = TRDOS v2.0)
 16512                              <1> 	; 08/08/2010
 16513                              <1> 	;
 16514                              <1> 	; INPUT -> DL = Logical DOS Drive number
 16515                              <1> 	; OUTPUT -> EAX = Volume serial number
 16516                              <1> 	;          BL= FAT Type                    
 16517                              <1> 	;          BH = Logical DOS drv Number (DL input)
 16518                              <1> 	; cf = 1 -> Drive not ready
 16519                              <1> 
 16520 00004FEF 31DB                <1> 	xor	ebx, ebx
 16521 00004FF1 88D7                <1> 	mov	bh, dl
 16522 00004FF3 3815[407F0000]      <1> 	cmp	[Last_DOS_DiskNo], dl
 16523 00004FF9 7304                <1> 	jnb	short loc_gvsn_start
 16524                              <1> loc_gvsn_stc_retn:
 16525 00004FFB 31C0                <1> 	xor	eax, eax
 16526 00004FFD F9                  <1> 	stc 
 16527 00004FFE C3                  <1>         retn 
 16528                              <1> loc_gvsn_start:
 16529 00004FFF 56                  <1> 	push	esi
 16530 00005000 BE00010900          <1> 	mov	esi, Logical_DOSDisks
 16531 00005005 01DE                <1> 	add	esi, ebx
 16532 00005007 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
 16533 0000500A 20DB                <1> 	and	bl, bl
 16534 0000500C 740F                <1> 	jz	short loc_gvsn_fs
 16535 0000500E 80FB02              <1> 	cmp	bl, 2
 16536 00005011 7705                <1> 	ja	short loc_gvsn_fat32
 16537                              <1> loc_gvsn_fat:
 16538 00005013 83C62D              <1> 	add	esi, LD_BPB + VolumeID
 16539 00005016 EB0E                <1> 	jmp	short loc_gvsn_return
 16540                              <1> loc_gvsn_fat32: 
 16541 00005018 83C649              <1> 	add	esi, LD_BPB + FAT32_VolID
 16542 0000501B EB09                <1> 	jmp	short loc_gvsn_return 
 16543                              <1> loc_gvsn_fs:
 16544 0000501D 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
 16545 00005021 75D8                <1> 	jne	short loc_gvsn_stc_retn 
 16546 00005023 83C628              <1> 	add	esi, LD_FS_VolumeSerial
 16547                              <1> loc_gvsn_return:
 16548 00005026 8B06                <1> 	mov	eax, [esi]
 16549 00005028 5E                  <1> 	pop	esi
 16550 00005029 C3                  <1> 	retn
 16551                              <1> 
 16552                              <1> ; CMD_INTR.ASM [ TRDOS Command Interpreter Procedure ]
 16553                              <1> ; 09/11/2011
 16554                              <1> ; 29/01/2005
 16555                              <1> 
 16556                              <1> command_interpreter:
 16557                              <1> 	; 30/01/2016
 16558                              <1> 	; 29/01/2016 (TRDOS 386 = TRDOS 2.0)
 16559                              <1> 	; 15/09/2011         
 16560                              <1> 	; 29/01/2005
 16561                              <1>         
 16562                              <1> 	; Input: ecx = command word length
 16563                              <1> 	;	 Commandbuffer = Command string offset
 16564                              <1>  
 16565 0000502A C605[24820000]00    <1> 	mov	byte [Program_Exit],0
 16566 00005031 6683F908            <1> 	cmp	cx, 8
 16567 00005035 0F87BD000000        <1> 	ja	cmp_cmd_external
 16568                              <1> 	; Significiant improvement is needed at the last 
 16569                              <1>         ; development stage of current tr-dos kernel version
 16570                              <1>         ; because of internal command handling procedures
 16571                              <1>         ; are not good sequenced ! 
 16572                              <1> cmp_cmd_ver:
 16573 0000503B 66B90300            <1> 	mov	cx, 3
 16574 0000503F BF[086E0000]        <1> 	mov	edi, Cmd_Ver
 16575 00005044 E8C3000000          <1> 	call	cmp_cmd	
 16576 00005049 720B                <1> 	jc	short cmp_cmd_exit
 16577                              <1> 
 16578 0000504B BE[AD6D0000]        <1> 	mov	esi, mainprog_Version
 16579 00005050 E84FECFFFF          <1> 	call	print_msg
 16580 00005055 C3                  <1> 	retn
 16581                              <1> 
 16582                              <1> cmp_cmd_exit:
 16583 00005056 66B90400            <1> 	mov	cx, 4
 16584 0000505A BF[0B6E0000]        <1> 	mov	edi, Cmd_Exit
 16585 0000505F E8A8000000          <1> 	call	cmp_cmd	
 16586 00005064 7208                <1> 	jc	short cmp_cmd_prompt
 16587                              <1> 
 16588 00005066 C605[24820000]01    <1>         mov     byte [Program_Exit], 1
 16589 0000506D C3                  <1>         retn
 16590                              <1> 
 16591                              <1> cmp_cmd_prompt:
 16592 0000506E 66B90600            <1> 	mov	cx, 6
 16593 00005072 BF[0F6E0000]        <1> 	mov	edi, Cmd_Prompt
 16594 00005077 E890000000          <1> 	call	cmp_cmd	
 16595                              <1>         ;jc	short cmp_cmd_volume
 16596 0000507C 722E                <1> 	jc	short cmp_cmd_date
 16597                              <1> get_prompt_name_fchar:
 16598 0000507E AC                  <1> 	lodsb
 16599 0000507F 3C20                <1> 	cmp	al, 20h
 16600 00005081 74FB                <1> 	je	short get_prompt_name_fchar
 16601 00005083 7712                <1> 	ja	short loc_change_prompt_label
 16602 00005085 BE[F96D0000]        <1> 	mov	esi, TRDOSPromptLabel
 16603 0000508A C7065452444F        <1> 	mov	dword [esi], "TRDO"
 16604 00005090 66C746045300        <1>        	mov	word [esi+4], "S" 
 16605                              <1> loc_cmd_prompt_return:
 16606 00005096 C3                  <1> 	retn
 16607                              <1> loc_change_prompt_label:
 16608 00005097 66B90B00            <1> 	mov	cx, 11
 16609 0000509B BF[F96D0000]        <1> 	mov	edi, TRDOSPromptLabel
 16610                              <1> put_char_new_prompt_label:
 16611 000050A0 AA                  <1> 	stosb
 16612 000050A1 AC                  <1> 	lodsb
 16613 000050A2 3C20                <1> 	cmp	al, 20h
 16614 000050A4 7202                <1> 	jb	short pass_put_new_prompt_label
 16615 000050A6 E2F8                <1> 	loop	put_char_new_prompt_label
 16616                              <1> pass_put_new_prompt_label:
 16617 000050A8 C60700              <1> 	mov	byte [edi], 0
 16618 000050AB C3                  <1> 	retn
 16619                              <1>               
 16620                              <1> cmp_cmd_date:
 16621 000050AC 66B90400            <1> 	mov	cx, 4
 16622 000050B0 BF[236E0000]        <1> 	mov	edi, Cmd_Date
 16623 000050B5 E852000000          <1> 	call	cmp_cmd	
 16624 000050BA 720B                <1>         jc	short cmp_cmd_time
 16625                              <1> 	
 16626 000050BC E88CF7FFFF          <1> 	call	show_date
 16627 000050C1 E8CBF7FFFF          <1> 	call	set_date
 16628 000050C6 C3                  <1> 	retn
 16629                              <1> 
 16630                              <1> cmp_cmd_time:
 16631 000050C7 66B90400            <1> 	mov	cx, 4
 16632 000050CB BF[276E0000]        <1> 	mov	edi, Cmd_Time
 16633 000050D0 E837000000          <1>    	call	cmp_cmd	
 16634 000050D5 720B                <1> 	jc	short cmp_cmd_cls
 16635                              <1> 
 16636 000050D7 E880FAFFFF          <1> 	call	show_time
 16637 000050DC E8B2FAFFFF          <1> 	call	set_time
 16638 000050E1 C3                  <1> 	retn
 16639                              <1> 
 16640                              <1> cmp_cmd_cls:
 16641 000050E2 66B90300            <1> 	mov	cx, 3
 16642 000050E6 BF[2E6E0000]        <1> 	mov	edi, Cmd_Cls
 16643 000050EB E81C000000          <1> 	call	cmp_cmd	
 16644                              <1>         ;jc	short cmp_cmd_mem
 16645 000050F0 7206                <1> 	jc	short loc_cmd_failed
 16646                              <1> 
 16647 000050F2 E8C4EBFFFF          <1> 	call	clear_screen
 16648 000050F7 C3                  <1> 	retn
 16649                              <1> 
 16650                              <1> cmp_cmd_external:
 16651                              <1> loc_cmd_failed:
 16652 000050F8 803D[F0790000]20    <1> 	cmp	byte [CommandBuffer], 20h
 16653 000050FF 760A                <1> 	jna	short loc_cmd_return
 16654 00005101 BE[996F0000]        <1> 	mov	esi, Msg_Bad_Command
 16655 00005106 E899EBFFFF          <1> 	call	print_msg
 16656                              <1> loc_cmd_return:
 16657 0000510B C3                  <1> 	retn
 16658                              <1> 
 16659                              <1> cmp_cmd:
 16660                              <1> 	 ; 29/01/2016  (TRDOS 386 = TRDOS v2.0)
 16661 0000510C BE[F0790000]        <1>          mov  esi, CommandBuffer
 16662                              <1>          ; edi = internal command word (ASCIIZ)
 16663                              <1> 	 ; ecx = command length (<=8)
 16664                              <1> cmp_cmd_1:
 16665 00005111 AC                  <1> 	lodsb
 16666 00005112 AE                  <1> 	scasb
 16667 00005113 750D                <1> 	jne	short cmp_cmd_3
 16668 00005115 E2FA                <1> 	loop	cmp_cmd_1
 16669 00005117 AC                  <1>  	lodsb
 16670 00005118 3C20                <1> 	cmp	al, 20h
 16671 0000511A 7703                <1> 	ja	short cmp_cmd_2
 16672 0000511C 30C0                <1> 	xor	al, al
 16673                              <1> 	; ZF = 1 -> internal command word matches
 16674 0000511E C3                  <1> 	retn
 16675                              <1> cmp_cmd_2:
 16676                              <1> 	; ZF = 0 (CF = 0) -> external command word 	
 16677 0000511F 58                  <1> 	pop	eax ; no return to the caller from here 
 16678 00005120 EBD6                <1> 	jmp	cmp_cmd_external	
 16679                              <1> cmp_cmd_3:
 16680 00005122 F9                  <1> 	stc
 16681                              <1> 	; CF = 1 -> internal command word does not match
 16682 00005123 C3                  <1> 	retn
 16683                                  %include 'trdosk4.s' ; 24/01/2016
 16684                              <1> ; ****************************************************************************
 16685                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk4.s
 16686                              <1> ; ----------------------------------------------------------------------------
 16687                              <1> ; Last Update: 24/01/2016
 16688                              <1> ; ----------------------------------------------------------------------------
 16689                              <1> ; Beginning: 24/01/2016
 16690                              <1> ; ----------------------------------------------------------------------------
 16691                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 16692                              <1> ; ----------------------------------------------------------------------------
 16693                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 16694                              <1> ; DIR.ASM (09/10/2011)
 16695                              <1> ; ****************************************************************************
 16696                              <1> 
 16697                              <1> ; DIR.ASM  [ TRDOS KERNEL - COMMAND EXECUTER SECTION - DIRECTORY FUNCTIONS ]
 16698                              <1> ; (c) 2004-2010  Erdogan TAN  [ 17/01/2004 ]  Last Update: 09/10/2011
 16699                              <1> 
 16700                              <1> change_prompt_dir_string:
 16701                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
 16702                              <1> 	; 27/03/2011
 16703                              <1> 	; 09/10/2009
 16704                              <1> 	; INPUT/OUTPUT => none
 16705                              <1> 	; this procedure changes current directory string/text  
 16706                              <1> 	; 2005
 16707                              <1> 
 16708 00005124 BF[92790000]        <1> 	mov	edi, Current_Directory
 16709 00005129 8A25[8C790000]      <1> 	mov	ah, [Current_Dir_Level]
 16710 0000512F BE[A4810000]        <1> 	mov	esi, PATH_Array
 16711 00005134 E807000000          <1> 	call	set_current_directory_string
 16712 00005139 880D[ED790000]      <1> 	mov	[Current_Dir_StrLen], cl
 16713                              <1> 
 16714 0000513F C3                  <1> 	retn
 16715                              <1> 
 16716                              <1> set_current_directory_string:
 16717                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
 16718                              <1> 	; 27/03/2011
 16719                              <1> 	; 09/10/2009
 16720                              <1> 	; INPUT:
 16721                              <1> 	;    ESI = Path Array Address 
 16722                              <1> 	;    EDI = Current Directory String Buffer
 16723                              <1> 	;    AH = Current Directory Level
 16724                              <1> 	; OUTPUT => EAX, EBX, ESI will be changed
 16725                              <1> 	;    EDI will be same with input
 16726                              <1> 	;    ECX = Current Directory String Length 
 16727                              <1> 
 16728 00005140 57                  <1> 	push    edi
 16729 00005141 80FC00              <1> 	cmp     ah, 0
 16730 00005144 7652                <1> 	jna	short pass_write_path
 16731 00005146 83C610              <1> 	add	esi, 16
 16732 00005149 89F3                <1> 	mov	ebx, esi
 16733                              <1> loc_write_path:
 16734 0000514B B908000000          <1> 	mov	ecx, 8
 16735                              <1> path_write_dirname1:
 16736 00005150 AC                  <1> 	lodsb
 16737 00005151 3C20                <1> 	cmp	al, 20h
 16738 00005153 7612                <1> 	jna	short pass_write_dirname1
 16739 00005155 AA                  <1> 	stosb
 16740 00005156 81FF[EC790000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
 16741 0000515C 733A                <1> 	jnb	short pass_write_path
 16742 0000515E E2F0                <1> 	loop	path_write_dirname1
 16743 00005160 803E20              <1> 	cmp	byte [esi], 20h
 16744 00005163 7624                <1> 	jna	short pass_write_dirname2
 16745 00005165 EB0A                <1> 	jmp     short loc_put_dot_cont_ext
 16746                              <1> pass_write_dirname1:
 16747 00005167 89DE                <1> 	mov	esi, ebx
 16748 00005169 83C608              <1> 	add	esi, 8
 16749 0000516C 803E20              <1> 	cmp	byte [esi], 20h
 16750 0000516F 7618                <1> 	jna	short pass_write_dirname2
 16751                              <1> loc_put_dot_cont_ext:
 16752 00005171 C6072E              <1> 	mov	byte [edi], "."
 16753                              <1> 	;mov	ecx, 3
 16754 00005174 B103                <1> 	mov	cl, 3
 16755                              <1> loc_check_dir_name_ext:
 16756 00005176 AC                  <1> 	lodsb
 16757 00005177 47                  <1> 	inc	edi
 16758 00005178 3C20                <1> 	cmp	al, 20h
 16759 0000517A 760D                <1> 	jna	short pass_write_dirname2
 16760 0000517C 8807                <1> 	mov	[edi], al
 16761 0000517E 81FF[EC790000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
 16762 00005184 7312                <1> 	jnb	short pass_write_path
 16763 00005186 E2EE                <1> 	loop    loc_check_dir_name_ext
 16764 00005188 47                  <1> 	inc	edi
 16765                              <1> pass_write_dirname2:
 16766 00005189 FECC                <1> 	dec	ah
 16767 0000518B 740B                <1> 	jz      short pass_write_path
 16768 0000518D 83C310              <1> 	add	ebx, 16
 16769 00005190 89DE                <1> 	mov	esi, ebx
 16770 00005192 C6072F              <1> 	mov	byte [edi],"/"
 16771 00005195 47                  <1> 	inc	edi
 16772 00005196 EBB3                <1> 	jmp	short loc_write_path
 16773                              <1> pass_write_path:
 16774 00005198 C60700              <1> 	mov	byte [edi], 0
 16775 0000519B 47                  <1> 	inc	edi
 16776 0000519C 89F9                <1> 	mov	ecx, edi
 16777 0000519E 5F                  <1> 	pop	edi
 16778 0000519F 29F9                <1> 	sub	ecx, edi
 16779                              <1> 	; ECX = Current Directory String Length
 16780 000051A1 C3                  <1> 	retn
 16781                              <1> 
 16782                              <1> get_current_directory:
 16783                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
 16784                              <1> 	; 27/03/2011
 16785                              <1> 	;
 16786                              <1> 	; INPUT-> ESI = Current Directory Buffer
 16787                              <1> 	;         DL = TRDOS Logical Dos Drive Number + 1
 16788                              <1> 	;              (0= Default/Current Drive)
 16789                              <1> 	;           
 16790                              <1> 	;   Note: Required dir buffer length may be <= 92 bytes
 16791                              <1> 	;         for TRDOS (7*12 name chars + 7 slash + 0)
 16792                              <1> 	; OUTPUT ->  ESI = Current Directory Buffer
 16793                              <1> 	;            EAX, EBX, ECX, EDX, EDI will be changed
 16794                              <1> 	;            CX/CL = Current Directory String Length
 16795                              <1> 	;	     DL = Drive Number (1 based)
 16796                              <1> 	;            (If input is 0, output is current drv number) 
 16797                              <1> 	;            DH = same with input 
 16798                              <1> 	;   cf = 0 -> AL = 0
 16799                              <1> 	;   cf = 1 -> error code in AL 
 16800                              <1>               
 16801                              <1> loc_get_current_drive_0:
 16802 000051A2 80FA00              <1> 	cmp	dl, 0
 16803 000051A5 7708                <1> 	ja	short loc_get_current_drive_1
 16804 000051A7 8A15[8E790000]      <1> 	mov	dl, [Current_Drv]
 16805 000051AD EB14                <1> 	jmp short loc_get_current_drive_3
 16806                              <1> loc_get_current_drive_1:
 16807 000051AF 80FA0D              <1> 	cmp	dl, 13
 16808 000051B2 760D                <1> 	jna	short loc_get_current_drive_2
 16809 000051B4 B80F000000          <1> 	mov	eax, 0Fh ; Invalid drive
 16810 000051B9 F5                  <1> 	cmc 	; stc
 16811 000051BA C3                  <1> 	retn
 16812                              <1> 
 16813                              <1> loc_get_current_drive_not_ready_retn:
 16814 000051BB 5E                  <1> 	pop	esi
 16815                              <1> 	;mov	eax, 15h
 16816 000051BC 66B81500            <1> 	mov	ax, 15h ; Drive not ready
 16817 000051C0 C3                  <1> 	retn  
 16818                              <1>  
 16819                              <1> loc_get_current_drive_2:
 16820 000051C1 FECA                <1> 	dec	dl ; Zero based (TRDOS Logical Dos Drive Number)
 16821                              <1> loc_get_current_drive_3:
 16822 000051C3 31C0                <1> 	xor	eax, eax
 16823 000051C5 88D4                <1> 	mov	ah, dl
 16824 000051C7 56                  <1> 	push	esi
 16825 000051C8 BE00010900          <1> 	mov	esi, Logical_DOSDisks
 16826 000051CD 01C6                <1> 	add	esi, eax
 16827 000051CF 8A06                <1> 	mov	al, [esi+LD_Name] 
 16828 000051D1 3C41                <1> 	cmp	al, 'A'
 16829 000051D3 72E6                <1> 	jb	short loc_get_current_drive_not_ready_retn
 16830                              <1> 
 16831                              <1> loc_get_current_drive_4:
 16832 000051D5 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
 16833 000051D8 08E4                <1> 	or	ah, ah
 16834 000051DA 7506                <1> 	jnz	short loc_get_current_drive_6
 16835                              <1> loc_get_current_drive_5:
 16836                              <1> 	;xor	ah, ah ; mov ah, 0
 16837 000051DC 8826                <1> 	mov	[esi], ah
 16838 000051DE 31C9                <1> 	xor	ecx, ecx
 16839 000051E0 EB1C                <1> 	jmp	short loc_get_current_drive_7
 16840                              <1> 
 16841                              <1> loc_get_current_drive_6:
 16842 000051E2 BF[A4810000]        <1>         mov     edi, PATH_Array
 16843 000051E7 57                  <1> 	push	edi
 16844 000051E8 81C680000000        <1> 	add	esi, LD_CurrentDirectory
 16845 000051EE B920000000          <1> 	mov	ecx, 32
 16846 000051F3 F3A5                <1> 	rep	movsd
 16847 000051F5 5E                  <1> 	pop	esi ; Path Array Address
 16848 000051F6 5F                  <1> 	pop	edi ; pushed esi (current dir buffer offset) 
 16849                              <1> 	;
 16850 000051F7 E844FFFFFF          <1> 	call	set_current_directory_string
 16851 000051FC 89FE                <1> 	mov	esi, edi
 16852                              <1> 
 16853                              <1> loc_get_current_drive_7:
 16854 000051FE 30C0                <1> 	xor	al, al
 16855 00005200 FEC2                <1> 	inc	dl ; 1 based drive number  
 16856 00005202 C3                  <1> 	retn
 16857                              <1> 
 16858                                  %include 'trdosk5.s' ; 24/01/2016
 16859                              <1> ; ****************************************************************************
 16860                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - File System Procedures : trdosk5s
 16861                              <1> ; ----------------------------------------------------------------------------
 16862                              <1> ; Last Update: 02/02/2016
 16863                              <1> ; ----------------------------------------------------------------------------
 16864                              <1> ; Beginning: 24/01/2016
 16865                              <1> ; ----------------------------------------------------------------------------
 16866                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 16867                              <1> ; ----------------------------------------------------------------------------
 16868                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 16869                              <1> ; DRV_FAT.ASM (21/08/2011)
 16870                              <1> ; ****************************************************************************
 16871                              <1> ; DRV_FAT.ASM (c) 2005-2011 Erdogan TAN [ 07/07/2009 ] Last Update: 21/08/2011
 16872                              <1> 
 16873                              <1> get_next_cluster:
 16874                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
 16875                              <1> 	; 05/07/2011
 16876                              <1> 	; 07/07/2009
 16877                              <1> 	; 2005
 16878                              <1> 	; INPUT ->
 16879                              <1> 	;	EAX = Cluster Number (32 bit)
 16880                              <1> 	;	ESI = Logical DOS Drive Parameters Table
 16881                              <1> 	; OUTPUT ->
 16882                              <1> 	;	cf = 0 -> No Error, EAX valid
 16883                              <1> 	;	cf = 1 & EAX = 0 -> End Of Cluster Chain
 16884                              <1> 	;	cf = 1 & EAX > 0 -> Error
 16885                              <1> 	;	ECX = Current/Previous cluster (if CF =  0)
 16886                              <1> 	;	EAX = Next Cluster Number (32 bit)
 16887                              <1> 	;
 16888                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
 16889                              <1> 
 16890 00005203 A3[54810000]        <1> 	mov	[FAT_CurrentCluster], eax
 16891                              <1> check_next_cluster_fat_type:
 16892 00005208 29D2                <1> 	sub	edx, edx ; 0
 16893 0000520A 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
 16894 0000520E 7250                <1> 	jb	short get_FAT12_next_cluster
 16895 00005210 0F87AF000000        <1>         ja      get_FAT32_next_cluster
 16896                              <1> get_FAT16_next_cluster:
 16897 00005216 BB00030000          <1> 	mov	ebx, 300h ;768
 16898 0000521B F7F3                <1> 	div	ebx
 16899                              <1> 	; EAX = Count of 3 FAT sectors
 16900                              <1> 	; EDX = Cluster Offset (< 768)
 16901 0000521D 66D1E2              <1> 	shl	dx, 1 ; Multiply by 2
 16902 00005220 89D3                <1> 	mov	ebx, edx ; Byte Offset
 16903 00005222 81C3001C0900        <1> 	add	ebx, FAT_Buffer
 16904 00005228 66BA0300            <1> 	mov	dx, 3
 16905 0000522C F7E2                <1> 	mul	edx  
 16906                              <1> 	; EAX = FAT Sector (<= 256)
 16907                              <1> 	; EDX = 0
 16908 0000522E 8A0E                <1> 	mov	cl, [esi+LD_Name]
 16909 00005230 803D[58810000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
 16910 00005237 0F86CC000000        <1>         jna     load_FAT_sectors0
 16911 0000523D 3A0D[59810000]      <1> 	cmp	cl, [FAT_BuffDrvName]
 16912 00005243 0F85C0000000        <1>         jne     load_FAT_sectors0
 16913 00005249 3B05[5C810000]      <1> 	cmp	eax, [FAT_BuffSector]
 16914 0000524F 0F85BA000000        <1>         jne     load_FAT_sectors1
 16915                              <1> 	;movzx	eax, word [ebx]
 16916 00005255 668B03              <1> 	mov	ax, [ebx]
 16917                              <1> 	; 01/02/2016
 16918                              <1> 	; DRV_FAT.ASM (21/08/2011) had a FATal bug here !
 16919                              <1> 	; (cmp ah, 0Fh) ! (ax >= FF7h)
 16920                              <1> 	; (how can i do a such mistake!?)
 16921                              <1> 	;cmp	al, 0F7h
 16922                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
 16923                              <1> 	;cmp	ah, 0FFh
 16924                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
 16925 00005258 6683F8F7            <1> 	cmp	ax, 0FFF7h
 16926 0000525C 725A                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
 16927                              <1> 	; ax >= FFF7h (cluster 0002h to FFF6h is valid, in use)
 16928 0000525E EB56                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
 16929                              <1> 
 16930                              <1> get_FAT12_next_cluster:
 16931 00005260 BB00040000          <1> 	mov	ebx, 400h ;1024
 16932 00005265 F7F3                <1> 	div	ebx
 16933                              <1> 	; EAX = Count of 3 FAT sectors
 16934                              <1> 	; EDX = Cluster Offset (< 1024)
 16935 00005267 6650                <1> 	push	ax
 16936 00005269 66B80300            <1> 	mov	ax, 3	
 16937 0000526D 66F7E2              <1> 	mul	dx    	; Multiply by 3
 16938 00005270 66D1E8              <1> 	shr	ax, 1	; Divide by 2
 16939 00005273 6689C3              <1>         mov	bx, ax 	; Byte Offset
 16940 00005276 81C3001C0900        <1> 	add	ebx, FAT_Buffer
 16941 0000527C 6658                <1> 	pop	ax
 16942 0000527E 66BA0300            <1> 	mov	dx, 3
 16943 00005282 F7E2                <1> 	mul	edx 
 16944                              <1> 	; EAX = FAT Sector (<= 12)
 16945                              <1> 	; EDX = 0
 16946 00005284 8A0E                <1> 	mov	cl, [esi+LD_Name]
 16947 00005286 803D[58810000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
 16948 0000528D 767A                <1> 	jna	short load_FAT_sectors0
 16949 0000528F 3A0D[59810000]      <1> 	cmp	cl, [FAT_BuffDrvName]
 16950 00005295 7572                <1> 	jne	short load_FAT_sectors0
 16951 00005297 3B05[5C810000]      <1> 	cmp	eax, [FAT_BuffSector]
 16952 0000529D 7570                <1> 	jne	short load_FAT_sectors1
 16953 0000529F A1[54810000]        <1> 	mov	eax, [FAT_CurrentCluster]
 16954 000052A4 66D1E8              <1> 	shr	ax, 1
 16955                              <1> 	;movzx	eax, word [ebx]
 16956 000052A7 668B03              <1> 	mov	ax, [ebx]
 16957 000052AA 7314                <1> 	jnc	short get_FAT12_nc_even
 16958 000052AC 66C1E804            <1> 	shr	ax, 4
 16959                              <1> loc_gnc_fat12_eoc_check:
 16960                              <1> 	;cmp	al, 0F7h
 16961                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
 16962                              <1> 	;cmp	ah, 0Fh
 16963                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
 16964 000052B0 663DF70F            <1> 	cmp	ax, 0FF7h
 16965 000052B4 7202                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
 16966                              <1> 	; ax >= FF7h (cluster 0002h to FF6h is valid, in use)
 16967                              <1> 
 16968                              <1> loc_pass_gnc_FAT16_eoc_check_xor_eax:
 16969 000052B6 31C0                <1> 	xor	eax, eax ; 0
 16970                              <1> loc_pass_gnc_FAT16_eoc_check:
 16971                              <1> loc_pass_gnc_FAT32_eoc_check:
 16972 000052B8 8B0D[54810000]      <1> 	mov	ecx, [FAT_CurrentCluster]
 16973 000052BE F5                  <1> 	cmc
 16974 000052BF C3                  <1> 	retn
 16975                              <1> 
 16976                              <1> get_FAT12_nc_even:
 16977 000052C0 80E40F              <1> 	and	ah, 0Fh
 16978 000052C3 EBEB                <1> 	jmp	short loc_gnc_fat12_eoc_check
 16979                              <1> 
 16980                              <1> get_FAT32_next_cluster:
 16981 000052C5 BB80010000          <1> 	mov	ebx, 180h ;384
 16982 000052CA F7F3                <1> 	div	ebx
 16983                              <1> 	; EAX = Count of 3 FAT sectors
 16984                              <1> 	; EDX = Cluster Offset (< 384)
 16985 000052CC 66C1E202            <1> 	shl	dx, 2	 ; Multiply by 4
 16986 000052D0 89D3                <1> 	mov	ebx, edx ; Byte Offset
 16987 000052D2 81C3001C0900        <1> 	add	ebx, FAT_Buffer
 16988 000052D8 66BA0300            <1> 	mov	dx, 3
 16989 000052DC F7E2                <1> 	mul	edx	
 16990                              <1>         ; EAX = FAT Sector (<= 2097152) ; (FFFFFF7h * 4) / 512
 16991                              <1> 	; 	for 32KB cluster size:
 16992                              <1> 	;	EAX <= 1024 = (FFFFFFFFh / 8000h) * 4) / 512 	
 16993                              <1> 	; EDX = 0
 16994 000052DE 8A0E                <1> 	mov	cl, [esi+LD_Name]
 16995 000052E0 803D[58810000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
 16996 000052E7 7620                <1> 	jna	short load_FAT_sectors0
 16997 000052E9 3A0D[59810000]      <1> 	cmp	cl, [FAT_BuffDrvName]
 16998 000052EF 7518                <1> 	jne	short load_FAT_sectors0
 16999 000052F1 3B05[5C810000]      <1> 	cmp	eax, [FAT_BuffSector]
 17000 000052F7 7516                <1> 	jne	short load_FAT_sectors1
 17001 000052F9 8B03                <1> 	mov	eax, [ebx]
 17002 000052FB 25FFFFFF0F          <1>  	and	eax, 0FFFFFFFh ; 28 bit Cluster
 17003 00005300 3DF7FFFF0F          <1> 	cmp	eax, 0FFFFFF7h
 17004 00005305 72B1                <1> 	jb	short loc_pass_gnc_FAT32_eoc_check
 17005                              <1> 	; eax >= FFFFFF7h (cluster 0002h to FFFFFF6h is valid)
 17006 00005307 EBAD                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
 17007                              <1> 
 17008                              <1> load_FAT_sectors0:
 17009 00005309 880D[59810000]      <1> 	mov	[FAT_BuffDrvName], cl
 17010                              <1> load_FAT_sectors1:
 17011 0000530F A3[5C810000]        <1> 	mov	[FAT_BuffSector], eax
 17012 00005314 89C3                <1> 	mov	ebx, eax
 17013 00005316 034660              <1>         add     eax, [esi+LD_FATBegin]
 17014 00005319 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
 17015 0000531D 7706                <1>         ja      short load_FAT_sectors3
 17016 0000531F 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
 17017 00005323 EB03                <1> 	jmp	short load_FAT_sectors4
 17018                              <1> load_FAT_sectors3:
 17019 00005325 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+BPB_FATSz32]
 17020                              <1> load_FAT_sectors4:
 17021 00005328 29D9                <1> 	sub	ecx, ebx ; [FAT_BuffSector]
 17022 0000532A 83F903              <1>         cmp     ecx, 3
 17023 0000532D 7605                <1>         jna     short load_FAT_sectors5
 17024 0000532F B903000000          <1> 	mov	ecx, 3
 17025                              <1> load_FAT_sectors5:
 17026 00005334 BB001C0900          <1> 	mov	ebx, FAT_Buffer
 17027 00005339 E852170000          <1> 	call	disk_read
 17028 0000533E 7308                <1> 	jnc	short load_FAT_sectors_ok
 17029 00005340 C605[58810000]00    <1> 	mov	byte [FAT_BuffValidData], 0
 17030 00005347 C3                  <1> 	retn
 17031                              <1> load_FAT_sectors_ok:
 17032 00005348 C605[58810000]01    <1> 	mov	byte [FAT_BuffValidData], 1
 17033 0000534F A1[54810000]        <1> 	mov	eax, [FAT_CurrentCluster]
 17034 00005354 E9AFFEFFFF          <1>         jmp     check_next_cluster_fat_type
 17035                              <1> 
 17036                              <1> load_FAT_root_directory:
 17037                              <1> 	; 02/02/2016
 17038                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
 17039                              <1> 	; 21/05/2011
 17040                              <1> 	; 22/08/2009
 17041                              <1> 	;
 17042                              <1> 	; INPUT ->
 17043                              <1> 	;	ESI = Logical DOS Drive Description Table
 17044                              <1> 	; OUTPUT ->
 17045                              <1> 	;	cf = 1 -> Root directory could not be loaded
 17046                              <1> 	;	     EAX > 0 -> Error number
 17047                              <1> 	;	cf = 0 -> EAX = 0
 17048                              <1> 	;	ECX = Directory buffer size in sectors (CL)
 17049                              <1> 	;	EBX = Directory buffer address
 17050                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
 17051                              <1> 	;
 17052                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
 17053                              <1> 
 17054                              <1> 	; NOTE: Only for FAT12 and FAT16 file systems !
 17055                              <1> 	; (FAT32 fs root dir must be loaded as sub directory)
 17056                              <1> 
 17057 00005359 8A1E                <1> 	mov	bl, [esi+LD_Name]
 17058 0000535B 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
 17059                              <1> 
 17060                              <1> 	;mov	[DirBuff_DRV], bl
 17061                              <1> 	;mov	[DirBuff_FATType], bh
 17062 0000535E 66891D[69810000]    <1> 	mov	[DirBuff_DRV], bx
 17063                              <1> 	
 17064                              <1> 	;cmp	bh, 2
 17065                              <1> 	;ja	short load_FAT32_root_dir0 ; FAT32 root dir
 17066                              <1> 
 17067 00005365 0FB75617            <1> 	movzx	edx, word [esi+LD_BPB+RootDirEnts]
 17068                              <1> 
 17069                              <1> 	;or	dx, dx ; 0 for FAT32 file systems
 17070                              <1> 	;jz	short load_FAT32_root_dir0 ; FAT32 root dir
 17071                              <1> 
 17072 00005369 6681FA0002          <1> 	cmp	dx, 512 ; Number of Root Dir Entries
 17073 0000536E 7415                <1> 	je	short lrd_mov_ecx_32
 17074 00005370 6689D0              <1> 	mov	ax, dx
 17075 00005373 6683C00F            <1> 	add	ax, 15 ; round up 
 17076 00005377 66C1E804            <1> 	shr	ax, 4  ; 16 entries per sector (512/32)
 17077 0000537B 89C1                <1> 	mov	ecx, eax ; Root directory size in sectors
 17078 0000537D 66C1E009            <1> 	shl	ax, 9 ; Root directory size in bytes
 17079 00005381 664A                <1> 	dec	dx    ; Last entry number of root dir
 17080                              <1> 	; cx = Dir Buffer sector count             
 17081 00005383 EB0B                <1> 	jmp	short lrd_check_dir_buffer
 17082                              <1> 
 17083                              <1> lrd_mov_ecx_32:
 17084 00005385 B920000000          <1> 	mov	ecx, 32
 17085 0000538A 664A                <1> 	dec	dx ; 511
 17086 0000538C 66B80040            <1> 	mov	ax, 32*512 
 17087                              <1>  
 17088                              <1> lrd_check_dir_buffer:
 17089 00005390 29DB                <1> 	sub	ebx, ebx ; 0
 17090 00005392 881D[6B810000]      <1> 	mov	[DirBuff_ValidData], bl ; 0
 17091 00005398 668915[6E810000]    <1> 	mov	[DirBuff_LastEntry], dx
 17092 0000539F 891D[70810000]      <1> 	mov	[DirBuff_Cluster], ebx ; 0
 17093 000053A5 66A3[74810000]      <1> 	mov	[DirBuffer_Size], ax
 17094                              <1> 
 17095 000053AB 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin]
 17096                              <1> read_directory:
 17097 000053AE BB00000800          <1> 	mov	ebx, Directory_Buffer
 17098 000053B3 51                  <1> 	push	ecx ; Directory buffer sector count
 17099 000053B4 53                  <1> 	push	ebx
 17100 000053B5 E8D6160000          <1> 	call	disk_read
 17101 000053BA 5B                  <1> 	pop	ebx
 17102 000053BB 720B                <1> 	jc	short load_DirBuff_error
 17103                              <1> 
 17104                              <1> validate_DirBuff_and_return:
 17105 000053BD 59                  <1> 	pop	ecx ; Number of loaded sectors
 17106 000053BE C605[6B810000]01    <1> 	mov	byte [DirBuff_ValidData], 1
 17107 000053C5 31C0                <1> 	xor	eax, eax ; 0 = no error
 17108 000053C7 C3                  <1> 	retn
 17109                              <1> 
 17110                              <1> load_DirBuff_error:
 17111 000053C8 89C8                <1> 	mov	eax, ecx ; remaining sectors
 17112 000053CA 59                  <1> 	pop	ecx ; sector count
 17113 000053CB 29C1                <1> 	sub	ecx, eax ; Number of loaded sectors
 17114 000053CD B815000000          <1> 	mov	eax, 15h ; DRV NOT READY OR READ ERROR !
 17115 000053D2 F9                  <1> 	stc
 17116 000053D3 C3                  <1>         retn
 17117                              <1> 
 17118                              <1> load_FAT32_root_directory:
 17119                              <1> 	; 02/02/2016 (TRDOS 386 =  TRDOS v2.0)
 17120                              <1> 	;
 17121                              <1> 	; INPUT ->
 17122                              <1> 	;	ESI = Logical DOS Drive Description Table
 17123                              <1> 	; OUTPUT ->
 17124                              <1> 	;	cf = 1 -> Root directory could not be loaded
 17125                              <1> 	;	     EAX > 0 -> Error number
 17126                              <1> 	;	cf = 0 -> EAX = 0
 17127                              <1> 	;	ECX = Directory buffer size in sectors (CL)
 17128                              <1> 	;	EBX = Directory buffer address
 17129                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
 17130                              <1> 	;
 17131                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
 17132                              <1> 
 17133                              <1> 
 17134 000053D4 8A1E                <1> 	mov	bl, [esi+LD_Name]
 17135 000053D6 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
 17136                              <1> 
 17137                              <1> 	;mov	[DirBuff_DRV], bl
 17138                              <1> 	;mov	[DirBuff_FATType], bh
 17139 000053D9 66891D[69810000]    <1> 	mov	[DirBuff_DRV], bx
 17140                              <1> 
 17141                              <1> load_FAT32_root_dir0:
 17142 000053E0 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
 17143 000053E3 EB0C                <1> 	jmp	short load_FAT_sub_dir0
 17144                              <1> 	
 17145                              <1> 
 17146                              <1> load_FAT_sub_directory:
 17147                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
 17148                              <1> 	; 05/07/2011
 17149                              <1> 	; 23/08/2009
 17150                              <1> 	;
 17151                              <1> 	; INPUT ->
 17152                              <1> 	;	ESI = Logical DOS Drive Description Table
 17153                              <1> 	;	EAX = Cluster Number
 17154                              <1> 	; OUTPUT ->
 17155                              <1> 	;	cf = 1 -> Sub directory could not be loaded
 17156                              <1> 	;	     EAX > 0 -> Error number
 17157                              <1> 	;	cf = 0 -> EAX = 0
 17158                              <1> 	;	ECX = Directory buffer size in sectors (CL)
 17159                              <1> 	;	EBX = Directory buffer address
 17160                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
 17161                              <1> 	;
 17162                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
 17163                              <1> 
 17164 000053E5 8A1E                <1> 	mov	bl, [esi+LD_Name]
 17165 000053E7 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
 17166                              <1> 
 17167                              <1> 	;mov	[DirBuff_DRV], bl
 17168                              <1> 	;mov	[DirBuff_FATType], bh
 17169 000053EA 66891D[69810000]    <1> 	mov	[DirBuff_DRV], bx
 17170                              <1> 
 17171                              <1> load_FAT_sub_dir0:
 17172 000053F1 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
 17173                              <1> 
 17174 000053F5 882D[6B810000]      <1> 	mov	[DirBuff_ValidData], ch ; 0
 17175 000053FB A3[70810000]        <1> 	mov	[DirBuff_Cluster], eax
 17176                              <1> 
 17177 00005400 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
 17178 00005404 F7E1                <1> 	mul	ecx
 17179 00005406 C1E805              <1> 	shr	eax, 5 ; directory entry count (dir size / 32)
 17180 00005409 6648                <1> 	dec	ax ; last entry
 17181 0000540B 66A3[6E810000]      <1> 	mov	[DirBuff_LastEntry], ax
 17182                              <1> 
 17183 00005411 A1[70810000]        <1> 	mov	eax, [DirBuff_Cluster]
 17184 00005416 83E802              <1> 	sub	eax, 2
 17185 00005419 F7E1                <1> 	mul	ecx
 17186 0000541B 034668              <1> 	add	eax, [esi+LD_DATABegin]
 17187                              <1> 	; ecx = sector per cluster (dir buffer size = 32 sectors)
 17188 0000541E EB8E                <1> 	jmp	short read_directory
 17189                              <1> 
 17190                              <1> ; DRV_FS.ASM
 17191                              <1> 
 17192                              <1> load_current_FS_directory:
 17193 00005420 C3                  <1> 	retn
 17194                                  %include 'trdosk6.s' ; 24/01/2016
 17195                              <1> ; ****************************************************************************
 17196                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk6.s
 17197                              <1> ; ----------------------------------------------------------------------------
 17198                              <1> ; Last Update: 24/01/2016
 17199                              <1> ; ----------------------------------------------------------------------------
 17200                              <1> ; Beginning: 24/01/2016
 17201                              <1> ; ----------------------------------------------------------------------------
 17202                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 17203                              <1> ; ----------------------------------------------------------------------------
 17204                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 17205                              <1> ; XXXXXXXX.ASM (XX/XX/2011)
 17206                              <1> ;
 17207                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 17208                              <1> ; u1.s (27/17/2015)
 17209                              <1> ; ****************************************************************************
 17210                              <1> 
 17211                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u1.s
 17212                              <1> ; Last Modification: 27/12/2015
 17213                              <1> 
 17214                              <1> sysent: ; < enter to system call >
 17215                              <1> 	 ;19/10/2015
 17216                              <1> 	; 21/09/2015
 17217                              <1> 	; 01/07/2015
 17218                              <1> 	; 19/05/2015
 17219                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 17220                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 17221                              <1> 	;
 17222                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
 17223                              <1> 	; The trap type is determined and an indirect jump is made to 
 17224                              <1> 	; the appropriate system call handler. If there is a trap inside
 17225                              <1> 	; the system a jump to panic is made. All user registers are saved 
 17226                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
 17227                              <1> 	; instructor is decoded to get the the system code part (see
 17228                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
 17229                              <1> 	; the indirect jump address is calculated. If a bad system call is
 17230                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
 17231                              <1> 	; is called. If the call is legitimate control passes to the
 17232                              <1> 	; appropriate system routine.
 17233                              <1> 	;
 17234                              <1> 	; Calling sequence:
 17235                              <1> 	;	Through a trap caused by any sys call outside the system.
 17236                              <1> 	; Arguments:
 17237                              <1> 	;	Arguments of particular system call.	
 17238                              <1> 	; ...............................................................
 17239                              <1> 	;	
 17240                              <1> 	; Retro UNIX 8086 v1 modification: 
 17241                              <1> 	;       System call number is in EAX register.
 17242                              <1> 	;
 17243                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 17244                              <1> 	;	registers depending of function details.
 17245                              <1>   	;
 17246                              <1> 	; 16/04/2015
 17247 00005421 368925[50850000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
 17248                              <1> 	; save user registers
 17249 00005428 1E                  <1> 	push	ds
 17250 00005429 06                  <1> 	push	es
 17251 0000542A 0FA0                <1> 	push	fs
 17252 0000542C 0FA8                <1> 	push	gs
 17253 0000542E 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
 17254                              <1> 	;
 17255                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
 17256                              <1> 	; 	(ESPACE is size of space in kernel stack 
 17257                              <1> 	;	for saving/restoring user registers.)
 17258                              <1> 	;
 17259 0000542F 50                  <1> 	push	eax ; 01/07/2015
 17260 00005430 66B81000            <1> 	mov     ax, KDATA
 17261 00005434 8ED8                <1>         mov     ds, ax
 17262 00005436 8EC0                <1>         mov     es, ax
 17263 00005438 8EE0                <1>         mov     fs, ax
 17264 0000543A 8EE8                <1>         mov     gs, ax
 17265 0000543C A1[C8780000]        <1> 	mov	eax, [k_page_dir]
 17266 00005441 0F22D8              <1> 	mov	cr3, eax
 17267 00005444 58                  <1> 	pop	eax ; 01/07/2015
 17268                              <1> 	; 19/10/2015
 17269 00005445 FC                  <1> 	cld
 17270                              <1> 	;
 17271 00005446 FE05[4D850000]      <1> 	inc	byte [sysflg]
 17272                              <1> 		; incb sysflg / indicate a system routine is in progress
 17273 0000544C FB                  <1>         sti 	; 18/01/2014
 17274 0000544D 0F85A4E8FFFF        <1> 	jnz     panic ; 24/05/2013
 17275                              <1> 		; beq 1f
 17276                              <1> 		; jmp panic ; / called if trap inside system
 17277                              <1> ;1:
 17278                              <1> 	; 16/04/2015
 17279 00005453 A3[58850000]        <1> 	mov	[u.r0], eax
 17280 00005458 8925[54850000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
 17281                              <1> 	;
 17282                              <1> 		; mov $s.syst+2,clockp
 17283                              <1> 		; mov r0,-(sp) / save user registers 
 17284                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
 17285                              <1> 			   ; / in u.r0
 17286                              <1> 		; mov r1,-(sp)
 17287                              <1> 		; mov r2,-(sp)
 17288                              <1> 		; mov r3,-(sp)
 17289                              <1> 		; mov r4,-(sp)
 17290                              <1> 		; mov r5,-(sp)
 17291                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
 17292                              <1> 		             ; / arithmetic unit
 17293                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
 17294                              <1> 		             ; / extended arithmetic unit
 17295                              <1> 		; mov sc,-(sp) / "step count" register for the extended
 17296                              <1> 		             ; / arithmetic unit
 17297                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
 17298                              <1> 		; mov 18.(sp),r0 / store pc in r0
 17299                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
 17300                              <1> 		; sub $sys,r0 / get xxx code
 17301 0000545E C1E002              <1> 	shl	eax, 2
 17302                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
 17303 00005461 3D94000000          <1> 	cmp	eax, end_of_syscalls - syscalls
 17304                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
 17305                              <1> 	;jnb	short badsys
 17306                              <1> 		; bhis badsys / yes, bad system call
 17307 00005466 F5                  <1> 	cmc
 17308 00005467 9C                  <1> 	pushf	
 17309 00005468 50                  <1> 	push	eax
 17310 00005469 8B2D[50850000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
 17311 0000546F B0FE                <1> 	mov	al, 0FEh ; 11111110b
 17312 00005471 1400                <1> 	adc	al, 0 ; al = al + cf
 17313 00005473 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
 17314                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
 17315                              <1> 				 ; / and clear carry bit
 17316 00005476 5D                  <1> 	pop	ebp ; eax
 17317 00005477 9D                  <1> 	popf
 17318 00005478 0F8248010000        <1>         jc      badsys
 17319 0000547E A1[58850000]        <1> 	mov	eax, [u.r0]
 17320                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
 17321 00005483 FFA5[89540000]      <1> 	jmp	dword [ebp+syscalls]
 17322                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
 17323                              <1> 		            ; / to proper system routine.
 17324                              <1> syscalls: ; 1:
 17325                              <1> 	; 21/09/2015
 17326                              <1> 	; 01/07/2015
 17327                              <1> 	; 16/04/2015 (32 bit address modification) 
 17328 00005489 [90550000]          <1> 	dd sysrele	; / 0
 17329 0000548D [36560000]          <1> 	dd sysexit 	; / 1
 17330 00005491 [5B570000]          <1> 	dd sysfork 	; / 2
 17331 00005495 [6E580000]          <1> 	dd sysread 	; / 3
 17332 00005499 [89580000]          <1> 	dd syswrite 	; / 4
 17333 0000549D [F3580000]          <1> 	dd sysopen 	; / 5
 17334 000054A1 [2D5A0000]          <1> 	dd sysclose 	; / 6
 17335 000054A5 [DD560000]          <1> 	dd syswait 	; / 7
 17336 000054A9 [A3590000]          <1> 	dd syscreat 	; / 8
 17337 000054AD [545D0000]          <1> 	dd syslink 	; / 9
 17338 000054B1 [165E0000]          <1> 	dd sysunlink 	; / 10
 17339 000054B5 [E95E0000]          <1> 	dd sysexec 	; / 11
 17340 000054B9 [50650000]          <1> 	dd syschdir 	; / 12
 17341 000054BD [34660000]          <1> 	dd systime 	; / 13
 17342 000054C1 [E4590000]          <1> 	dd sysmkdir 	; / 14
 17343 000054C5 [A2650000]          <1> 	dd syschmod 	; / 15
 17344 000054C9 [04660000]          <1> 	dd syschown 	; / 16
 17345 000054CD [67660000]          <1> 	dd sysbreak 	; / 17
 17346 000054D1 [C1620000]          <1> 	dd sysstat 	; / 18
 17347 000054D5 [2C670000]          <1> 	dd sysseek 	; / 19
 17348 000054D9 [3E670000]          <1> 	dd systell 	; / 20
 17349 000054DD [3F680000]          <1> 	dd sysmount 	; / 21
 17350 000054E1 [F1680000]          <1> 	dd sysumount 	; / 22
 17351 000054E5 [BC670000]          <1> 	dd syssetuid 	; / 23
 17352 000054E9 [ED670000]          <1> 	dd sysgetuid 	; / 24
 17353 000054ED [43660000]          <1> 	dd sysstime 	; / 25
 17354 000054F1 [B0670000]          <1> 	dd sysquit 	; / 26
 17355 000054F5 [A4670000]          <1> 	dd sysintr 	; / 27
 17356 000054F9 [9D620000]          <1> 	dd sysfstat 	; / 28
 17357 000054FD [495A0000]          <1> 	dd sysemt 	; / 29
 17358 00005501 [775A0000]          <1> 	dd sysmdate 	; / 30
 17359 00005505 [C25A0000]          <1> 	dd sysstty 	; / 31
 17360 00005509 [415C0000]          <1> 	dd sysgtty 	; / 32
 17361 0000550D [725A0000]          <1> 	dd sysilgins 	; / 33
 17362 00005511 [4C690000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
 17363                              <1> 			     ; 11/06/2014
 17364 00005515 [7B690000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
 17365                              <1> 			     ; 01/07/2015
 17366 00005519 [526A0000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
 17367                              <1> 			     ; 21/09/2015 - get last error number
 17368                              <1> end_of_syscalls:
 17369                              <1> 
 17370                              <1> error:
 17371                              <1> 	; 17/09/2015
 17372                              <1> 	; 03/09/2015
 17373                              <1> 	; 01/09/2015
 17374                              <1> 	; 09/06/2015
 17375                              <1> 	; 13/05/2015
 17376                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 17377                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 17378                              <1> 	;
 17379                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
 17380                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
 17381                              <1> 	;
 17382                              <1> 	; INPUTS -> none
 17383                              <1> 	; OUTPUTS ->
 17384                              <1> 	;	processor status - carry (c) bit is set (means error)
 17385                              <1> 	;
 17386                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
 17387                              <1> 	; 	      Because, jumps to error procedure
 17388                              <1> 	;	      disrupts push-pop nesting balance)
 17389                              <1> 	;
 17390 0000551D 8B2D[50850000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
 17391 00005523 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
 17392                              <1> 				 ; (system call will return with cf = 1)
 17393                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
 17394                              <1> 		               ; / users stack
 17395                              <1> 	; 17/09/2015
 17396 00005527 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
 17397                              <1> 				 ; for saving/restoring user registers	
 17398                              <1> 	;cmp	ebp, [u.usp]
 17399                              <1> 	;je	short err0	
 17400 0000552A 892D[54850000]      <1> 	mov	[u.usp], ebp
 17401                              <1> ;err0:
 17402                              <1> 	; 01/09/2015
 17403 00005530 8B25[54850000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
 17404                              <1> 				    ; 10/04/2013
 17405                              <1> 				    ; (If an I/O error occurs during disk I/O,
 17406                              <1> 				    ; related procedures will jump to 'error'
 17407                              <1> 				    ; procedure directly without returning to 
 17408                              <1> 				    ; the caller procedure. So, stack pointer
 17409                              <1>                                     ; must be restored here.)
 17410                              <1> 	; 13/05/2015
 17411                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
 17412                              <1> 	;	'get last error' system call later. 	
 17413                              <1> 
 17414                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
 17415 00005536 C605[BF850000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
 17416                              <1> 
 17417                              <1> sysret: ; < return from system call>
 17418                              <1> 	; 10/09/2015
 17419                              <1> 	; 29/07/2015
 17420                              <1> 	; 25/06/2015
 17421                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 17422                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 17423                              <1> 	;
 17424                              <1> 	; 'sysret' first checks to see if process is about to be 
 17425                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
 17426                              <1> 	; If not, following happens:	 
 17427                              <1> 	; 	1) The user's stack pointer is restored.
 17428                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
 17429                              <1> 	;	   i-node has been modified. If it has, it is written out
 17430                              <1> 	;	   via 'ppoke'.
 17431                              <1> 	;	3) If the super block has been modified, it is written out
 17432                              <1> 	;	   via 'ppoke'.				
 17433                              <1> 	;	4) If the dismountable file system's super block has been
 17434                              <1> 	;	   modified, it is written out to the specified device
 17435                              <1> 	;	   via 'ppoke'.
 17436                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
 17437                              <1> 	;	   during his execution. If so, 'tswap' is called to give
 17438                              <1> 	;	   another user a chance to run.
 17439                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
 17440                              <1> 	;	    (See 'sysrele' for conclusion.)		
 17441                              <1> 	;
 17442                              <1> 	; Calling sequence:
 17443                              <1> 	;	jump table or 'br sysret'
 17444                              <1> 	; Arguments: 
 17445                              <1> 	;	-	
 17446                              <1> 	; ...............................................................
 17447                              <1> 	;	
 17448                              <1> 	; ((AX=r1 for 'iget' input))
 17449                              <1> 	;	
 17450 0000553D 6631C0              <1> 	xor	ax, ax ; 04/05/2013
 17451                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
 17452 00005540 FEC0                <1> 	inc	al ; 04/05/2013
 17453 00005542 3805[A6850000]      <1> 	cmp	[u.bsys], al ; 1
 17454                              <1> 		; tstb u.bsys / is a process about to be terminated because
 17455 00005548 0F83E8000000        <1>         jnb     sysexit ; 04/05/2013
 17456                              <1> 		; bne sysexit / of an error? yes, go to sysexit
 17457                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
 17458                              <1> 		; mov u.sp,sp / no point stack to users stack
 17459 0000554E FEC8                <1> 	dec 	al ; mov ax, 0
 17460                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
 17461 00005550 E820150000          <1> 	call	iget
 17462                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
 17463                              <1> 		            ; / it is written out
 17464 00005555 6631C0              <1> 	xor 	ax, ax ; 0
 17465 00005558 3805[4B850000]      <1> 	cmp	[smod], al ; 0
 17466                              <1> 		; tstb	smod / has the super block been modified
 17467 0000555E 7614                <1> 	jna	short sysret1
 17468                              <1> 		; beq	1f / no, 1f
 17469 00005560 A2[4B850000]        <1> 	mov	[smod], al ; 0
 17470                              <1> 		; clrb smod / yes, clear smod
 17471 00005565 BB[FD8D0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
 17472 0000556A 66810B0002          <1>    	or	word [ebx], 200h ;;
 17473                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
 17474                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
 17475                              <1> 		      	      ; / output
 17476                              <1> 	; AX = 0
 17477 0000556F E802150000          <1> 	call 	poke ; 07/08/2013
 17478                              <1> 	; call	ppoke
 17479                              <1> 	; AX = 0
 17480                              <1> 		; jsr r0,ppoke / write out modified super block to disk
 17481                              <1> sysret1: ;1:
 17482 00005574 3805[4C850000]      <1> 	cmp	[mmod], al ; 0
 17483                              <1> 		; tstb	mmod / has the super block for the dismountable file
 17484                              <1> 		           ; / system
 17485 0000557A 7614                <1> 	jna	short sysrel0
 17486                              <1> 		; beq 1f / been modified?  no, 1f
 17487 0000557C A2[4C850000]        <1> 	mov	[mmod], al ; 0	
 17488                              <1> 		; clrb	mmod / yes, clear mmod
 17489                              <1>         ;mov    ax, [mntd]
 17490                              <1>         ;;mov   al, [mdev] ; 26/04/2013
 17491 00005581 BB[05900000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
 17492                              <1>         ;;mov	[ebx], al
 17493                              <1> 	;mov    [sb1], al
 17494                              <1> 		; movb	mntd,sb1 / set the I/O queue
 17495 00005586 66810B0002          <1> 	or	word [ebx], 200h
 17496                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
 17497                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
 17498 0000558B E8E6140000          <1> 	call	poke ; 07/08/2013
 17499                              <1> 	;call	ppoke 
 17500                              <1> 		; jsr r0,ppoke / write it out to its device
 17501                              <1>         ;xor    al, al ; 26/04/2013       
 17502                              <1> ;1:
 17503                              <1> 		; tstb uquant / is the time quantum 0?
 17504                              <1> 		; bne 1f / no, don't swap it out
 17505                              <1> 
 17506                              <1> sysrele: ; < release >
 17507                              <1> 	; 14/10/2015
 17508                              <1> 	; 01/09/2015
 17509                              <1> 	; 24/07/2015
 17510                              <1> 	; 14/05/2015
 17511                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 17512                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
 17513                              <1> 	;
 17514                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
 17515                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
 17516                              <1> 	; turns off the system flag. It then checked to see if there is
 17517                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
 17518                              <1> 	; the output gets flashed (see isintr) and interrupt action is
 17519                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
 17520                              <1> 	; the user, a rti is made.
 17521                              <1> 	;
 17522                              <1> 	; Calling sequence:
 17523                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
 17524                              <1> 	; Arguments:
 17525                              <1> 	;	-	
 17526                              <1> 	; ...............................................................
 17527                              <1> 	;	
 17528                              <1> 	; 23/02/2014 (swapret)
 17529                              <1> 	; 22/09/2013
 17530                              <1> sysrel0: ;1:
 17531 00005590 803D[9A850000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
 17532                              <1> 		; tstb uquant / is the time quantum 0?
 17533 00005597 7705                <1>         ja      short swapret
 17534                              <1> 		; bne 1f / no, don't swap it out
 17535                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
 17536 00005599 E8D9140000          <1> 	call	tswap
 17537                              <1> 		; jsr r0,tswap / yes, swap it out
 17538                              <1> ;
 17539                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
 17540                              <1> swapret: ;1:
 17541                              <1> 	; 10/09/2015
 17542                              <1> 	; 01/09/2015
 17543                              <1> 	; 14/05/2015
 17544                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
 17545                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
 17546                              <1> 	; cli
 17547                              <1> 	; 24/07/2015
 17548                              <1> 	;
 17549                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
 17550                              <1> 	;; mov	esp, [u.usp]
 17551                              <1> 
 17552                              <1> 	; 22/09/2013
 17553 0000559E E8D5140000          <1> 	call	isintr
 17554                              <1> 	; 20/10/2013
 17555 000055A3 7405                <1> 	jz	short sysrel1
 17556 000055A5 E875000000          <1> 	call	intract
 17557                              <1> 		; jsr r0,isintr / is there an interrupt from the user
 17558                              <1> 		;     br intract / yes, output gets flushed, take interrupt
 17559                              <1> 		               ; / action
 17560                              <1> sysrel1:
 17561 000055AA FA                  <1> 	cli ; 14/10/2015
 17562 000055AB FE0D[4D850000]      <1> 	dec	byte [sysflg]
 17563                              <1> 		; decb sysflg / turn system flag off
 17564 000055B1 A1[B1850000]        <1> 	mov     eax, [u.pgdir]
 17565 000055B6 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
 17566                              <1> 			  ; (others are different than kernel page tables) 
 17567                              <1> 	; 10/09/2015
 17568 000055B9 61                  <1> 	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
 17569                              <1> 		; mov (sp)+,sc / restore user registers
 17570                              <1> 		; mov (sp)+,mq
 17571                              <1> 		; mov (sp)+,ac
 17572                              <1> 		; mov (sp)+,r5
 17573                              <1> 		; mov (sp)+,r4
 17574                              <1> 		; mov (sp)+,r3
 17575                              <1> 		; mov (sp)+,r2
 17576                              <1> 	;
 17577 000055BA A1[58850000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
 17578 000055BF 0FA9                <1> 	pop	gs
 17579 000055C1 0FA1                <1> 	pop	fs
 17580 000055C3 07                  <1> 	pop	es
 17581 000055C4 1F                  <1> 	pop	ds
 17582 000055C5 CF                  <1> 	iretd	
 17583                              <1> 		; rti / no, return from interrupt
 17584                              <1> 
 17585                              <1> badsys:
 17586                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 17587                              <1> 	; (Major Modification: 'core' dumping procedure in
 17588                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
 17589                              <1> 	;	has been changed to print 'Invalid System Call !'
 17590                              <1> 	;	message on the user's console tty.)
 17591                              <1> 	; (EIP, EAX values will be shown on screen with error message)
 17592                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
 17593                              <1> 	; (EAX = Function number)  
 17594                              <1> 	;
 17595 000055C6 FE05[A6850000]      <1> 	inc	byte [u.bsys]
 17596                              <1> 	;
 17597 000055CC 8B1D[50850000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
 17598 000055D2 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
 17599 000055D4 E880C4FFFF          <1> 	call	dwordtohex
 17600 000055D9 8915[75750000]      <1> 	mov	[bsys_msg_eip], edx
 17601 000055DF A3[79750000]        <1> 	mov	[bsys_msg_eip+4], eax
 17602 000055E4 A1[58850000]        <1> 	mov	eax, [u.r0]
 17603 000055E9 E86BC4FFFF          <1> 	call	dwordtohex
 17604 000055EE 8915[65750000]      <1> 	mov	[bsys_msg_eax], edx
 17605 000055F4 A3[69750000]        <1> 	mov	[bsys_msg_eax+4], eax
 17606 000055F9 31C0                <1> 	xor	eax, eax
 17607 000055FB C705[78850000]-     <1>         mov     dword [u.base], badsys_msg ; "Invalid System call !"
 17608 00005601 [46750000]          <1>
 17609 00005605 8B1D[68850000]      <1> 	mov	ebx, [u.fofp]
 17610 0000560B 8903                <1> 	mov	[ebx], eax
 17611                              <1> 	;mov	eax, 1 ; inode number of console tty (for user)	
 17612 0000560D 40                  <1> 	inc	eax
 17613 0000560E C705[7C850000]3B00- <1> 	mov	dword [u.count], BSYS_M_SIZE
 17614 00005616 0000                <1>
 17615                              <1> 		; writei
 17616                              <1> 		; INPUTS ->
 17617                              <1> 		;    r1 - inode number
 17618                              <1> 		;    u.count - byte count to be written
 17619                              <1> 		;    u.base - points to user buffer
 17620                              <1> 		;    u.fofp - points to word with current file offset
 17621                              <1> 		; OUTPUTS ->
 17622                              <1> 		;    u.count - cleared
 17623                              <1> 		;    u.nread - accumulates total bytes passed back	
 17624                              <1> 		;
 17625                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
 17626 00005618 E85C140000          <1> 	call	writei
 17627                              <1> 	;mov	eax, 1
 17628 0000561D EB17                <1> 	jmp	sysexit
 17629                              <1> 
 17630                              <1> 		; incb u.bsys / turn on the user's bad-system flag
 17631                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
 17632                              <1> 		; jsr r0,namei / get the i-number for the core image file
 17633                              <1> 		; br 1f / error
 17634                              <1> 		; neg r1 / negate the i-number to open the core image file
 17635                              <1> 		       ; / for writing
 17636                              <1> 		; jsr r0,iopen / open the core image file
 17637                              <1> 		; jsr r0,itrunc / free all associated blocks
 17638                              <1> 		; br 2f
 17639                              <1> ;1:
 17640                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
 17641                              <1> 		; jsr r0,maknod / make an i-node
 17642                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
 17643                              <1> ;2:
 17644                              <1> 		; mov $core,u.base / move address core to u.base
 17645                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
 17646                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
 17647                              <1> 		; clr u.off / clear user offset
 17648                              <1> 		; jsr r0,writei / write out the core image to the user
 17649                              <1> 		; mov $user,u.base / pt. u.base to user
 17650                              <1> 		; mov $64.,u.count / u.count = 64
 17651                              <1> 		; jsr r0,writei / write out all the user parameters
 17652                              <1> 		; neg r1 / make i-number positive
 17653                              <1> 		; jsr r0,iclose / close the core image file
 17654                              <1> 		; br sysexit /
 17655                              <1> ;3:
 17656                              <1> 		; <core\0\0>
 17657                              <1> 
 17658                              <1> intract: ; / interrupt action
 17659                              <1> 	; 14/10/2015
 17660                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 17661                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
 17662                              <1> 	;
 17663                              <1> 	; Retro UNIX 8086 v1 modification !
 17664                              <1> 	; (Process/task switching and quit routine by using
 17665                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 17666                              <1> 	;
 17667                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
 17668                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
 17669                              <1> 	;		'intract' will jump to 'sysexit'.
 17670                              <1> 	;	    Intract will return to the caller 
 17671                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
 17672                              <1> 	; 14/10/2015
 17673 0000561F FB                  <1> 	sti
 17674                              <1> 	; 07/12/2013	
 17675 00005620 66FF05[9E850000]    <1> 	inc 	word [u.quit]
 17676 00005627 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
 17677 00005629 66FF0D[9E850000]    <1> 	dec	word [u.quit]
 17678                              <1> 	; 16/04/2015
 17679 00005630 C3                  <1> 	retn
 17680                              <1> intrct0:	
 17681 00005631 58                  <1> 	pop	eax ; call intract -> retn
 17682                              <1> 	;
 17683 00005632 31C0                <1> 	xor 	eax, eax
 17684 00005634 FEC0                <1> 	inc	al  ; mov ax, 1
 17685                              <1> ;;;
 17686                              <1> 	; UNIX v1 original 'intract' routine... 
 17687                              <1> 	; / interrupt action
 17688                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
 17689                              <1> 		; bne 1f / no, 1f
 17690                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
 17691                              <1> 	; 1: / now in user area
 17692                              <1> 		; mov r1,-(sp) / save r1
 17693                              <1> 		; mov u.ttyp,r1 
 17694                              <1> 			; / pointer to tty buffer in control-to r1
 17695                              <1> 		; cmpb 6(r1),$177
 17696                              <1> 			; / is the interrupt char equal to "del"
 17697                              <1> 		; beq 1f / yes, 1f
 17698                              <1> 		; clrb 6(r1) 
 17699                              <1> 		        ; / no, clear the byte 
 17700                              <1> 			; / (must be a quit character)
 17701                              <1> 		; mov (sp)+,r1 / restore r1
 17702                              <1> 		; clr u.quit / clear quit flag
 17703                              <1> 		; bis $20,2(sp) 
 17704                              <1> 		    	; / set trace for quit (sets t bit of 
 17705                              <1> 			; / ps-trace trap)
 17706                              <1> 		; rti   ;  / return from interrupt
 17707                              <1> 	; 1: / interrupt char = del
 17708                              <1> 		; clrb 6(r1) / clear the interrupt byte 
 17709                              <1> 			   ; / in the buffer
 17710                              <1> 		; mov (sp)+,r1 / restore r1
 17711                              <1> 		; cmp u.intr,$core / should control be 
 17712                              <1> 				; / transferred to loc core?
 17713                              <1> 		; blo 1f
 17714                              <1> 		; jmp *u.intr / user to do rti yes, 
 17715                              <1> 				; / transfer to loc core
 17716                              <1> 	; 1:
 17717                              <1> 		; sys 1 / exit
 17718                              <1> 
 17719                              <1> sysexit: ; <terminate process>
 17720                              <1> 	; 01/09/2015
 17721                              <1> 	; 31/08/2015
 17722                              <1> 	; 14/05/2015
 17723                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 17724                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 17725                              <1> 	;
 17726                              <1> 	; 'sysexit' terminates a process. First each file that
 17727                              <1> 	; the process has opened is closed by 'flose'. The process
 17728                              <1> 	; status is then set to unused. The 'p.pid' table is then
 17729                              <1> 	; searched to find children of the dying process. If any of
 17730                              <1> 	; children are zombies (died by not waited for), they are
 17731                              <1> 	; set free. The 'p.pid' table is then searched to find the
 17732                              <1> 	; dying process's parent. When the parent is found, it is
 17733                              <1> 	; checked to see if it is free or it is a zombie. If it is
 17734                              <1> 	; one of these, the dying process just dies. If it is waiting
 17735                              <1> 	; for a child process to die, it notified that it doesn't 
 17736                              <1> 	; have to wait anymore by setting it's status from 2 to 1
 17737                              <1> 	; (waiting to active). It is awakened and put on runq by
 17738                              <1> 	; 'putlu'. The dying process enters a zombie state in which
 17739                              <1> 	; it will never be run again but stays around until a 'wait'
 17740                              <1> 	; is completed by it's parent process. If the parent is not
 17741                              <1> 	; found, process just dies. This means 'swap' is called with
 17742                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
 17743                              <1> 	; to write out the process and 'rswap' reads the new process
 17744                              <1> 	; over the one that dies..i.e., the dying process is 
 17745                              <1> 	; overwritten and destroyed.	
 17746                              <1>  	;
 17747                              <1> 	; Calling sequence:
 17748                              <1> 	;	sysexit or conditional branch.
 17749                              <1> 	; Arguments:
 17750                              <1> 	;	-	
 17751                              <1> 	; ...............................................................
 17752                              <1> 	;	
 17753                              <1> 	; Retro UNIX 8086 v1 modification: 
 17754                              <1> 	;       System call number (=1) is in EAX register.
 17755                              <1> 	;
 17756                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 17757                              <1> 	;       registers depending of function details.
 17758                              <1> 	;
 17759                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
 17760                              <1> 	;
 17761                              <1> ; / terminate process
 17762                              <1> 	; AX = 1
 17763 00005636 6648                <1> 	dec 	ax ; 0
 17764 00005638 66A3[9C850000]      <1> 	mov	[u.intr], ax ; 0
 17765                              <1> 		; clr u.intr / clear interrupt control word
 17766                              <1> 		; clr r1 / clear r1
 17767                              <1> 	; AX = 0
 17768                              <1> sysexit_1: ; 1:
 17769                              <1> 	; AX = File descriptor
 17770                              <1> 		; / r1 has file descriptor (index to u.fp list)
 17771                              <1> 		; / Search the whole list
 17772 0000563E E8140D0000          <1> 	call	fclose
 17773                              <1> 		; jsr r0,fclose / close all files the process opened
 17774                              <1> 	;; ignore error return
 17775                              <1> 		; br .+2 / ignore error return
 17776                              <1> 	;inc	ax
 17777 00005643 FEC0                <1> 	inc	al
 17778                              <1> 		; inc r1 / increment file descriptor
 17779                              <1> 	;cmp	ax, 10
 17780 00005645 3C0A                <1> 	cmp	al, 10
 17781                              <1> 		; cmp r1,$10. / end of u.fp list?
 17782 00005647 72F5                <1> 	jb	short sysexit_1
 17783                              <1> 		; blt 1b / no, go back
 17784 00005649 0FB61D[A7850000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 17785                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
 17786 00005650 88A3[DB820000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 17787                              <1> 		; clrb p.stat-1(r1) / free the process
 17788                              <1> 	;shl	bx, 1
 17789 00005656 D0E3                <1> 	shl	bl, 1
 17790                              <1> 		; asl r1 / use r1 for index into the below tables
 17791 00005658 668B8B[4A820000]    <1> 	mov	cx, [ebx+p.pid-2]
 17792                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
 17793 0000565F 668B93[6A820000]    <1> 	mov	dx, [ebx+p.ppid-2]
 17794                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
 17795                              <1> 	; xor 	bx, bx ; 0
 17796 00005666 30DB                <1> 	xor	bl, bl ; 0
 17797                              <1> 		; clr r2
 17798 00005668 31F6                <1> 	xor	esi, esi ; 0
 17799                              <1> 		; clr r5 / initialize reg
 17800                              <1> sysexit_2: ; 1:
 17801                              <1> 	        ; / find children of this dying process, 
 17802                              <1> 		; / if they are zombies, free them
 17803                              <1> 	;add	bx, 2
 17804 0000566A 80C302              <1> 	add	bl, 2
 17805                              <1> 		; add $2,r2 / search parent process table 
 17806                              <1> 		          ; / for dying process's name
 17807 0000566D 66398B[6A820000]    <1> 	cmp	[ebx+p.ppid-2], cx
 17808                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
 17809 00005674 7513                <1> 	jne	short sysexit_4
 17810                              <1> 		; bne 3f / no
 17811                              <1> 	;shr	bx, 1
 17812 00005676 D0EB                <1> 	shr	bl, 1
 17813                              <1> 		; asr r2 / yes, it is a parent
 17814 00005678 80BB[DB820000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
 17815                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
 17816                              <1> 				     ; / dying process a zombie
 17817 0000567F 7506                <1> 	jne	short sysexit_3 
 17818                              <1> 		; bne 2f / no
 17819 00005681 88A3[DB820000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 17820                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
 17821                              <1> sysexit_3: ; 2:
 17822                              <1> 	;shr	bx, 1
 17823 00005687 D0E3                <1> 	shl	bl, 1
 17824                              <1> 		; asl r2
 17825                              <1> sysexit_4: ; 3:
 17826                              <1> 		; / search the process name table 
 17827                              <1> 		; / for the dying process's parent
 17828 00005689 663993[4A820000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
 17829                              <1> 		; cmp p.pid-2(r2),r4 / found it?
 17830 00005690 7502                <1> 	jne	short sysexit_5
 17831                              <1> 		; bne 3f / no
 17832 00005692 89DE                <1> 	mov	esi, ebx
 17833                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
 17834                              <1> 		          ; / process # x2) in r5
 17835                              <1> sysexit_5: ; 3:
 17836                              <1> 	;cmp	bx, nproc + nproc
 17837 00005694 80FB20              <1> 	cmp	bl, nproc + nproc
 17838                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
 17839 00005697 72D1                <1> 	jb	short sysexit_2
 17840                              <1> 		; blt 1b / no, go back
 17841                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
 17842 00005699 21F6                <1> 	and	esi, esi ; r5=r1
 17843 0000569B 7431                <1> 	jz	short sysexit_6
 17844                              <1> 		; beq 2f / no parent has been found. 
 17845                              <1> 		       ; / The process just dies
 17846 0000569D 66D1EE              <1> 	shr	si, 1
 17847                              <1> 		; asr r1 / set up index to p.stat
 17848 000056A0 8A86[DB820000]      <1> 	mov	al, [esi+p.stat-1]
 17849                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
 17850 000056A6 20C0                <1> 	and	al, al
 17851 000056A8 7424                <1> 	jz	short sysexit_6
 17852                              <1> 		; beq 2f / if its been freed, 2f
 17853 000056AA 3C03                <1> 	cmp	al, 3
 17854                              <1> 		; cmp r2,$3 / is parent a zombie?
 17855 000056AC 7420                <1> 	je	short sysexit_6
 17856                              <1> 		; beq 2f / yes, 2f
 17857                              <1> 	; BH = 0
 17858 000056AE 8A1D[A7850000]      <1> 	mov	bl, [u.uno]
 17859                              <1> 		; movb u.uno,r3 / move dying process's number to r3
 17860 000056B4 C683[DB820000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
 17861                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
 17862                              <1> 	; 05/02/2014
 17863 000056BB 3C01                <1> 	cmp	al, 1 ; SRUN
 17864 000056BD 740F                <1> 	je	short sysexit_6
 17865                              <1> 	;cmp	al, 2
 17866                              <1> 		; cmp r2,$2 / is the parent waiting for 
 17867                              <1> 			  ; / this child to die
 17868                              <1> 	;jne	short sysexit_6	
 17869                              <1> 		; bne 2f / yes, notify parent not to wait any more
 17870                              <1> 	; 05/02/2014
 17871                              <1> 	; p.stat = 2 --> waiting
 17872                              <1> 	; p.stat = 4 --> sleeping
 17873 000056BF C686[DB820000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
 17874                              <1> 	;dec	byte [esi+p.stat-1]
 17875                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
 17876 000056C6 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
 17877                              <1> 	; 
 17878                              <1> 	;mov	ebx, runq + 4
 17879                              <1> 		; mov $runq+4,r2 / on the runq
 17880 000056C9 E8AD130000          <1> 	call	putlu
 17881                              <1> 		; jsr r0, putlu
 17882                              <1> sysexit_6: ; 2:
 17883                              <1> 	; 31/08/2015
 17884                              <1> 		; / the process dies
 17885 000056CE C605[A7850000]00    <1> 	mov	byte [u.uno], 0
 17886                              <1> 		; clrb u.uno / put zero as the process number, 
 17887                              <1> 	           ; / so "swap" will
 17888 000056D5 E8A2130000          <1> 	call	swap
 17889                              <1> 		; jsr r0,swap / overwrite process with another process
 17890                              <1> hlt_sys:
 17891                              <1> 	;sti ; 18/01/2014
 17892                              <1> hlts0:
 17893 000056DA F4                  <1> 	hlt
 17894 000056DB EBFD                <1> 	jmp	short hlts0
 17895                              <1> 		; 0 / and thereby kill it; halt?
 17896                              <1> 
 17897                              <1> 
 17898                              <1> syswait: ; < wait for a processs to die >
 17899                              <1> 	; 17/09/2015
 17900                              <1> 	; 02/09/2015
 17901                              <1> 	; 01/09/2015
 17902                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 17903                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
 17904                              <1> 	;
 17905                              <1> 	; 'syswait' waits for a process die. 
 17906                              <1> 	; It works in following way:
 17907                              <1> 	;    1) From the parent process number, the parent's 
 17908                              <1> 	; 	process name is found. The p.ppid table of parent
 17909                              <1> 	;	names is then searched for this process name.
 17910                              <1> 	;	If a match occurs, r2 contains child's process
 17911                              <1> 	;	number. The child status is checked to see if it is
 17912                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
 17913                              <1> 	;	If it is, the child process is freed and it's name
 17914                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
 17915                              <1> 	;	If the child is not a zombie, nothing happens and
 17916                              <1> 	;	the search goes on through the p.ppid table until
 17917                              <1> 	;	all processes are checked or a zombie is found.
 17918                              <1> 	;    2) If no zombies are found, a check is made to see if
 17919                              <1> 	;	there are any children at all. If there are none,
 17920                              <1> 	;	an error return is made. If there are, the parent's
 17921                              <1> 	;	status is set to 2 (waiting for child to die),
 17922                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
 17923                              <1> 	;	is made to wait on the next process.
 17924                              <1> 	;
 17925                              <1> 	; Calling sequence:
 17926                              <1> 	;	?
 17927                              <1> 	; Arguments:
 17928                              <1> 	;	-
 17929                              <1> 	; Inputs: - 
 17930                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
 17931                              <1> 	; ...............................................................
 17932                              <1> 	;				
 17933                              <1> 	
 17934                              <1> ; / wait for a process to die
 17935                              <1> 
 17936                              <1> syswait_0:
 17937 000056DD 0FB61D[A7850000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 17938                              <1> 		; movb u.uno,r1 / put parents process number in r1
 17939 000056E4 D0E3                <1> 	shl	bl, 1
 17940                              <1> 	;shl	bx, 1
 17941                              <1> 		; asl r1 / x2 to get index into p.pid table
 17942 000056E6 668B83[4A820000]    <1> 	mov	ax, [ebx+p.pid-2]
 17943                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
 17944 000056ED 31F6                <1> 	xor	esi, esi
 17945                              <1> 		; clr r2
 17946 000056EF 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
 17947                              <1> 	;xor 	cl, cl
 17948                              <1> 		; clr r3 / initialize reg 3
 17949                              <1> syswait_1: ; 1:
 17950 000056F1 6683C602            <1> 	add	si, 2
 17951                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
 17952                              <1> 			  ; / search table of parent processes 
 17953                              <1> 			  ; / for this process name
 17954 000056F5 663B86[6A820000]    <1> 	cmp	ax, [esi+p.ppid-2]
 17955                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
 17956                              <1> 			            ; / process number
 17957 000056FC 7535                <1> 	jne	short syswait_3
 17958                              <1> 		;bne 3f / branch if no match of parent process name
 17959                              <1> 	;inc	cx
 17960 000056FE FEC1                <1> 	inc	cl
 17961                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
 17962 00005700 66D1EE              <1> 	shr	si, 1
 17963                              <1> 		; asr r2 / r2/2 to get index to p.stat table
 17964                              <1> 	; The possible states ('p.stat' values) of a process are:
 17965                              <1> 	;	0 = free or unused
 17966                              <1> 	;	1 = active
 17967                              <1> 	;	2 = waiting for a child process to die
 17968                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
 17969 00005703 80BE[DB820000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
 17970                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
 17971 0000570A 7524                <1> 	jne	short syswait_2
 17972                              <1> 		; bne 2f / no, skip it
 17973 0000570C 88BE[DB820000]      <1> 	mov	[esi+p.stat-1], bh ; 0
 17974                              <1> 		; clrb p.stat-1(r2) / yes, free it
 17975 00005712 66D1E6              <1> 	shl	si, 1
 17976                              <1> 		; asl r2 / r2x2 to get index into p.pid table
 17977 00005715 0FB786[4A820000]    <1> 	movzx	eax, word [esi+p.pid-2]
 17978 0000571C A3[58850000]        <1> 	mov	[u.r0], eax
 17979                              <1> 		; mov p.pid-2(r2),*u.r0 
 17980                              <1> 			      ; / put childs process name in (u.r0)
 17981                              <1> 	;
 17982                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
 17983                              <1> 	;
 17984                              <1> 	; Parent process ID -p.ppid- field (of the child process)
 17985                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
 17986                              <1> 	; system call loop from the application/program if it calls
 17987                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
 17988                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
 17989                              <1> 	;
 17990                              <1> 	; Note: syswait will return with error if there is not a
 17991                              <1> 	;       zombie or running process to wait.	
 17992                              <1> 	;
 17993 00005721 6629C0              <1> 	sub	ax, ax
 17994 00005724 668986[6A820000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
 17995 0000572B E910FEFFFF          <1> 	jmp	sysret0 ; ax = 0
 17996                              <1> 	;
 17997                              <1> 	;jmp	sysret
 17998                              <1> 		; br sysret1 / return cause child is dead
 17999                              <1> syswait_2: ; 2:
 18000 00005730 66D1E6              <1> 	shl	si, 1
 18001                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
 18002                              <1> syswait_3: ; 3:
 18003 00005733 6683FE20            <1> 	cmp	si, nproc+nproc
 18004                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
 18005 00005737 72B8                <1> 	jb	short syswait_1
 18006                              <1> 		; blt 1b / no, continue search
 18007                              <1> 	;and	cx, cx
 18008 00005739 20C9                <1> 	and	cl, cl
 18009                              <1> 		; tst r3 / one gets here if there are no children 
 18010                              <1> 		       ; / or children that are still active
 18011                              <1> 	; 30/10/2013
 18012 0000573B 750B                <1> 	jnz	short syswait_4
 18013                              <1> 	;jz	error
 18014                              <1> 		; beq error1 / there are no children, error
 18015 0000573D 890D[58850000]      <1> 	mov	[u.r0], ecx ; 0
 18016 00005743 E9D5FDFFFF          <1> 	jmp	error
 18017                              <1> syswait_4:
 18018 00005748 8A1D[A7850000]      <1> 	mov	bl, [u.uno]
 18019                              <1> 		; movb u.uno,r1 / there are children so put 
 18020                              <1> 			      ; / parent process number in r1
 18021 0000574E FE83[DB820000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
 18022                              <1> 		; incb p.stat-1(r1) / it is waiting for 
 18023                              <1> 				  ; / other children to die
 18024                              <1> 	; 04/11/2013
 18025 00005754 E823130000          <1> 	call	swap
 18026                              <1> 		; jsr r0,swap / swap it out, because it's waiting
 18027 00005759 EB82                <1> 	jmp	syswait_0
 18028                              <1> 		; br syswait / wait on next process
 18029                              <1> 
 18030                              <1> sysfork: ; < create a new process >
 18031                              <1> 	; 18/09/2015
 18032                              <1> 	; 04/09/2015
 18033                              <1> 	; 02/09/2015
 18034                              <1> 	; 01/09/2015
 18035                              <1> 	; 28/08/2015
 18036                              <1> 	; 14/05/2015
 18037                              <1> 	; 10/05/2015
 18038                              <1> 	; 09/05/2015
 18039                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
 18040                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 18041                              <1> 	;
 18042                              <1> 	; 'sysfork' creates a new process. This process is referred
 18043                              <1> 	; to as the child process. This new process core image is
 18044                              <1> 	; a copy of that of the caller of 'sysfork'. The only
 18045                              <1> 	; distinction is the return location and the fact that (u.r0)
 18046                              <1> 	; in the old process (parent) contains the process id (p.pid)
 18047                              <1> 	; of the new process (child). This id is used by 'syswait'.
 18048                              <1> 	; 'sysfork' works in the following manner: 	
 18049                              <1> 	;    1) The process status table (p.stat) is searched to find
 18050                              <1> 	;	a process number that is unused. If none are found
 18051                              <1> 	;	an error occurs.
 18052                              <1> 	;    2) when one is found, it becomes the child process number
 18053                              <1> 	;	and it's status (p.stat) is set to active.
 18054                              <1> 	;    3) If the parent had a control tty, the interrupt 
 18055                              <1> 	;	character in that tty buffer is cleared.
 18056                              <1> 	;    4) The child process is put on the lowest priority run 
 18057                              <1> 	;	queue via 'putlu'.
 18058                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
 18059                              <1> 	;	it is a unique number) and is put in the child's unique
 18060                              <1> 	;	identifier; process id (p.pid).
 18061                              <1> 	;    6) The process name of the parent is then obtained and
 18062                              <1> 	;	placed in the unique identifier of the parent process
 18063                              <1> 	;	name is then put in 'u.r0'.	
 18064                              <1> 	;    7) The child process is then written out on disk by
 18065                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
 18066                              <1> 	;	and the child is born. (The child process is written 
 18067                              <1> 	;	out on disk/drum with 'u.uno' being the child process
 18068                              <1> 	;	number.)
 18069                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
 18070                              <1> 	;    9) The child process name is put in 'u.r0'.
 18071                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
 18072                              <1> 	;	create the return address for the parent process.
 18073                              <1> 	;   11) The 'u.fp' list as then searched to see what files
 18074                              <1> 	;	the parent has opened. For each file the parent has
 18075                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
 18076                              <1> 	;	to indicate that the child process also has opened
 18077                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
 18078                              <1> 	;
 18079                              <1> 	; Calling sequence:
 18080                              <1> 	;	from shell ?
 18081                              <1> 	; Arguments:
 18082                              <1> 	;	-
 18083                              <1> 	; Inputs: -
 18084                              <1> 	; Outputs: *u.r0 - child process name
 18085                              <1> 	; ...............................................................
 18086                              <1> 	;	
 18087                              <1> 	; Retro UNIX 8086 v1 modification: 
 18088                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
 18089                              <1> 	;	= process id of child a parent process returns
 18090                              <1> 	;	= process id of parent when a child process returns
 18091                              <1> 	;
 18092                              <1> 	;       In original UNIX v1, sysfork is called and returns as
 18093                              <1> 	;	in following manner: (with an example: c library, fork)
 18094                              <1> 	;	
 18095                              <1> 	;	1:
 18096                              <1> 	;		sys	fork
 18097                              <1> 	;			br 1f  / child process returns here
 18098                              <1> 	;		bes	2f     / parent process returns here
 18099                              <1> 	;		/ pid of new process in r0
 18100                              <1> 	;		rts	pc
 18101                              <1> 	;	2: / parent process condionally branches here
 18102                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
 18103                              <1> 	;		rts	pc
 18104                              <1> 	;
 18105                              <1> 	;	1: / child process brances here
 18106                              <1> 	;		clr	r0   / pid = 0 in child process
 18107                              <1> 	;		rts	pc
 18108                              <1> 	;
 18109                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
 18110                              <1> 	;		// pid = fork();
 18111                              <1> 	;		//
 18112                              <1> 	;		// pid == 0 in child process; 
 18113                              <1> 	;		// pid == -1 means error return
 18114                              <1> 	;		// in child, 
 18115                              <1> 	;		//	parents id is in par_uid if needed
 18116                              <1> 	;		
 18117                              <1> 	;		_fork:
 18118                              <1> 	;			mov	$.fork,eax
 18119                              <1> 	;			int	$0x30
 18120                              <1> 	;			jmp	1f
 18121                              <1> 	;			jnc	2f
 18122                              <1> 	;			jmp	cerror
 18123                              <1> 	;		1:
 18124                              <1> 	;			mov	eax,_par_uid
 18125                              <1> 	;			xor	eax,eax
 18126                              <1> 	;		2:
 18127                              <1> 	;			ret
 18128                              <1> 	;
 18129                              <1> 	;	In Retro UNIX 8086 v1,
 18130                              <1> 	;	'sysfork' returns in following manner:
 18131                              <1> 	;	
 18132                              <1> 	;		mov	ax, sys_fork
 18133                              <1> 	;		mov	bx, offset @f ; routine for child
 18134                              <1> 	;		int	20h
 18135                              <1> 	;		jc	error
 18136                              <1> 	;		
 18137                              <1> 	;	; Routine for parent process here (just after 'jc')
 18138                              <1> 	;		mov	word ptr [pid_of_child], ax
 18139                              <1> 	;		jmp	next_routine_for_parent	
 18140                              <1> 	;
 18141                              <1> 	;	@@: ; routine for child process here				
 18142                              <1> 	;		....	
 18143                              <1> 	;	NOTE: 'sysfork' returns to specified offset
 18144                              <1> 	;	       for child process by using BX input.
 18145                              <1> 	;	      (at first, parent process will return then 
 18146                              <1> 	;	      child process will return -after swapped in-
 18147                              <1> 	;	      'syswait' is needed in parent process
 18148                              <1> 	;	      if return from child process will be waited for.)
 18149                              <1> 	;	  				
 18150                              <1> 	
 18151                              <1> ; / create a new process
 18152                              <1> 	; EBX = return address for child process 
 18153                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
 18154 0000575B 31F6                <1> 	xor 	esi, esi
 18155                              <1> 		; clr r1
 18156                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
 18157 0000575D 46                  <1> 	inc	esi
 18158                              <1> 		; inc r1
 18159 0000575E 80BE[DB820000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
 18160                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
 18161 00005765 760B                <1> 	jna	short sysfork_2	
 18162                              <1> 		; beq 1f / it's unused so branch
 18163 00005767 6683FE10            <1> 	cmp	si, nproc
 18164                              <1> 		; cmp r1,$nproc / all processes checked
 18165 0000576B 72F0                <1> 	jb	short sysfork_1
 18166                              <1> 		; blt 1b / no, branch back
 18167                              <1> 	;
 18168                              <1> 	; Retro UNIX 8086 v1. modification:
 18169                              <1> 	;	Parent process returns from 'sysfork' to address 
 18170                              <1> 	;	which is just after 'sysfork' system call in parent
 18171                              <1> 	;	process. Child process returns to address which is put
 18172                              <1> 	;	in BX register by parent process for 'sysfork'. 
 18173                              <1> 	;
 18174                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
 18175                              <1> 		             ; / to old process return
 18176                              <1> 		; br error1 / no room for a new process
 18177 0000576D E9ABFDFFFF          <1> 	jmp	error
 18178                              <1> sysfork_2: ; 1:
 18179 00005772 E8FAD9FFFF          <1> 	call	allocate_page
 18180 00005777 0F82A0FDFFFF        <1> 	jc	error
 18181 0000577D 50                  <1> 	push	eax   ; UPAGE (user structure page) address
 18182                              <1> 	; Retro UNIX 386 v1 modification!
 18183 0000577E E8F7DBFFFF          <1> 	call	duplicate_page_dir
 18184                              <1> 		; EAX = New page directory 
 18185 00005783 730B                <1> 	jnc	short sysfork_3
 18186 00005785 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 18187 00005786 E8BEDBFFFF          <1> 	call 	deallocate_page
 18188 0000578B E98DFDFFFF          <1> 	jmp	error
 18189                              <1> sysfork_3:
 18190                              <1> 	; Retro UNIX 386 v1 modification !
 18191 00005790 56                  <1> 	push	esi
 18192 00005791 E8E7120000          <1> 	call	wswap ; save current user (u) structure, user registers
 18193                              <1> 		      ; and interrupt return components (for IRET)
 18194 00005796 8705[B1850000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
 18195 0000579C A3[B5850000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
 18196 000057A1 5E                  <1> 	pop	esi
 18197 000057A2 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 18198                              <1> 		; [u.usp] = esp
 18199 000057A3 89F7                <1> 	mov	edi, esi
 18200 000057A5 66C1E702            <1> 	shl	di, 2
 18201 000057A9 8987[E8820000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
 18202 000057AF A3[A8850000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
 18203                              <1> 	; 28/08/2015
 18204 000057B4 0FB605[A7850000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
 18205                              <1> 		; movb u.uno,-(sp) / save parent process number
 18206 000057BB 89C7                <1> 	mov	edi, eax
 18207 000057BD 50                  <1>         push	eax ; ** 
 18208 000057BE 8A87[AB820000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
 18209                              <1> 	; 18/09/2015
 18210                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
 18211                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
 18212 000057C4 668986[AB820000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
 18213                              <1> 				   ; ah - reset child's wait channel	
 18214 000057CB 89F0                <1> 	mov	eax, esi
 18215 000057CD A2[A7850000]        <1> 	mov	[u.uno], al ; child process number
 18216                              <1> 		;movb r1,u.uno / set child process number to r1
 18217 000057D2 FE86[DB820000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
 18218                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
 18219                              <1> 				; / process to active status
 18220                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
 18221                              <1> 			      ; / control tty buffer in r2
 18222                              <1>                 ; beq 2f / branch, if no such tty assigned
 18223                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
 18224                              <1> 	; 2:
 18225 000057D8 53                  <1> 	push	ebx  ; * return address for the child process
 18226                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 18227                              <1> 	; (Retro UNIX 8086 v1 modification!)
 18228                              <1> 		; mov $runq+4,r2
 18229 000057D9 E89D120000          <1> 	call	putlu 
 18230                              <1>  		; jsr r0,putlu / put child process on lowest priority 
 18231                              <1> 			   ; / run queue
 18232 000057DE 66D1E6              <1> 	shl	si, 1
 18233                              <1> 		; asl r1 / multiply r1 by 2 to get index 
 18234                              <1> 		       ; / into p.pid table
 18235 000057E1 66FF05[44850000]    <1> 	inc	word [mpid]
 18236                              <1> 		; inc mpid / increment m.pid; get a new process name
 18237 000057E8 66A1[44850000]      <1> 	mov	ax, [mpid]
 18238 000057EE 668986[4A820000]    <1> 	mov	[esi+p.pid-2], ax
 18239                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
 18240                              <1> 				    ; / in child process' name slot
 18241 000057F5 5A                  <1> 	pop	edx  ; * return address for the child process
 18242                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 18243 000057F6 5B                  <1>   	pop	ebx  ; **
 18244                              <1> 	;mov	ebx, [esp] ; ** parent process number
 18245                              <1> 		; movb (sp),r2 / put parent process number in r2
 18246 000057F7 66D1E3              <1> 	shl 	bx, 1
 18247                              <1> 		;asl r2 / multiply by 2 to get index into below tables
 18248                              <1> 	;movzx eax, word [ebx+p.pid-2]
 18249 000057FA 668B83[4A820000]    <1> 	mov	ax, [ebx+p.pid-2]
 18250                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
 18251                              <1> 				   ; / process
 18252 00005801 668986[6A820000]    <1> 	mov	[esi+p.ppid-2], ax
 18253                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
 18254                              <1> 			  ; / in parent process slot for child
 18255 00005808 A3[58850000]        <1> 	mov	[u.r0], eax	
 18256                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
 18257                              <1> 			     ; / at location where r0 was saved
 18258 0000580D 8B2D[50850000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
 18259 00005813 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
 18260                              <1> 			   ; * return address for the child process
 18261                              <1> 		; mov $sysret1,-(sp) /
 18262                              <1> 		; mov sp,u.usp / contents of sp at the time when 
 18263                              <1> 			      ; / user is swapped out
 18264                              <1> 		; mov $sstack,sp / point sp to swapping stack space
 18265                              <1> 	; 04/09/2015 - 01/09/2015
 18266                              <1> 	; [u.usp] = esp
 18267 00005816 68[3D550000]        <1> 	push	sysret ; ***
 18268 0000581B 8925[54850000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
 18269                              <1> 			     ; (for child process)	
 18270 00005821 31C0                <1> 	xor 	eax, eax
 18271 00005823 66A3[88850000]      <1> 	mov 	[u.ttyp], ax ; 0
 18272                              <1> 	;
 18273 00005829 E84F120000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
 18274                              <1> 		;jsr r0,wswap / put child process out on drum
 18275                              <1> 		;jsr r0,unpack / unpack user stack
 18276                              <1> 		;mov u.usp,sp / restore user stack pointer
 18277                              <1> 		; tst (sp)+ / bump stack pointer
 18278                              <1> 	; Retro UNIX 386 v1 modification !
 18279 0000582E 58                  <1> 	pop	eax ; ***
 18280 0000582F 66D1E3              <1> 	shl	bx, 1
 18281 00005832 8B83[E8820000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
 18282 00005838 E841120000          <1> 	call	rswap ; restore parent process 'u' structure, 
 18283                              <1> 		      ; registers and return address (for IRET)
 18284                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
 18285 0000583D 0FB705[44850000]    <1>         movzx   eax, word [mpid]
 18286 00005844 A3[58850000]        <1> 	mov	[u.r0], eax
 18287                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
 18288                              <1> 			       ; / where r0 was saved
 18289                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
 18290                              <1> 			          ; / process return
 18291                              <1> 	;xor	ebx, ebx
 18292 00005849 31F6                <1> 	xor     esi, esi
 18293                              <1> 		;clr r1
 18294                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
 18295                              <1> 	      ; / opened by the parent process
 18296                              <1> 	; 01/09/2015
 18297                              <1> 	;xor	bh, bh
 18298                              <1> 	;mov 	bl, [esi+u.fp]
 18299 0000584B 8A86[5E850000]      <1> 	mov 	al, [esi+u.fp]
 18300                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
 18301                              <1>         ;or      bl, bl
 18302 00005851 08C0                <1> 	or	al, al
 18303 00005853 740D                <1> 	jz	short sysfork_5	
 18304                              <1> 		; beq 2f / file has not been opened by parent, 
 18305                              <1> 		       ; / so branch
 18306 00005855 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
 18307 00005857 F6E4                <1> 	mul	ah
 18308                              <1> 	;movzx	ebx, ax
 18309 00005859 6689C3              <1> 	mov	bx, ax
 18310                              <1> 	;shl     bx, 3
 18311                              <1> 		; asl r2 / multiply by 8
 18312                              <1>        		; asl r2 / to get index into fsp table
 18313                              <1>        		; asl r2
 18314 0000585C FE83[2A830000]      <1>   	inc     byte [ebx+fsp-2]
 18315                              <1> 		; incb fsp-2(r2) / increment number of processes
 18316                              <1> 			     ; / using file, because child will now be
 18317                              <1> 			     ; / using this file
 18318                              <1> sysfork_5: ; 2:
 18319 00005862 46                  <1>         inc     esi
 18320                              <1> 		; inc r1 / get next open file
 18321 00005863 6683FE0A            <1>         cmp     si, 10
 18322                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
 18323                              <1> 			  ; / can be opened
 18324 00005867 72E2                <1> 	jb	short sysfork_4	
 18325                              <1> 		; blt 1b / check next entry
 18326 00005869 E9CFFCFFFF          <1> 	jmp	sysret
 18327                              <1> 		; br sysret1
 18328                              <1> 
 18329                              <1> sysread: ; < read from file >
 18330                              <1> 	; 13/05/2015
 18331                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 18332                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 18333                              <1> 	;
 18334                              <1> 	; 'sysread' is given a buffer to read into and the number of
 18335                              <1> 	; characters to be read. If finds the file from the file
 18336                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
 18337                              <1> 	; is returned from a successful open call (sysopen).
 18338                              <1> 	; The i-number of file is obtained via 'rw1' and the data
 18339                              <1> 	; is read into core via 'readi'.
 18340                              <1> 	;
 18341                              <1> 	; Calling sequence:
 18342                              <1> 	;	sysread; buffer; nchars
 18343                              <1> 	; Arguments:
 18344                              <1> 	;	buffer - location of contiguous bytes where 
 18345                              <1> 	;		 input will be placed.
 18346                              <1> 	;	nchars - number of bytes or characters to be read.
 18347                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 18348                              <1> 	; Outputs: *u.r0 - number of bytes read.	
 18349                              <1> 	; ...............................................................
 18350                              <1> 	;				
 18351                              <1> 	; Retro UNIX 8086 v1 modification: 
 18352                              <1> 	;       'sysread' system call has three arguments; so,
 18353                              <1> 	;	* 1st argument, file descriptor is in BX register
 18354                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 18355                              <1> 	;	* 3rd argument, number of bytes is in DX register
 18356                              <1> 	;
 18357                              <1> 	;	AX register (will be restored via 'u.r0') will return
 18358                              <1> 	;	to the user with number of bytes read. 
 18359                              <1> 	;
 18360 0000586E E83D000000          <1> 	call	rw1
 18361 00005873 0F82A4FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
 18362                              <1> 		; jsr r0,rw1 / get i-number of file to be read into r1
 18363 00005879 F6C480              <1> 	test	ah, 80h
 18364                              <1> 		; tst r1 / negative i-number?
 18365 0000587C 0F859BFCFFFF        <1> 	jnz	error
 18366                              <1> 		; ble error1 / yes, error 1 to read
 18367                              <1> 			   ; / it should be positive
 18368 00005882 E8F3110000          <1> 	call	readi
 18369                              <1> 		; jsr r0,readi / read data into core
 18370 00005887 EB18                <1> 	jmp	short rw0
 18371                              <1> 		; br 1f
 18372                              <1> syswrite: ; < write to file >
 18373                              <1> 	; 13/05/2015
 18374                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 18375                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 18376                              <1> 	;
 18377                              <1> 	; 'syswrite' is given a buffer to write onto an output file
 18378                              <1> 	; and the number of characters to write. If finds the file
 18379                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
 18380                              <1> 	; descriptor is returned from a successful open or create call
 18381                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
 18382                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
 18383                              <1> 	;
 18384                              <1> 	; Calling sequence:
 18385                              <1> 	;	syswrite; buffer; nchars
 18386                              <1> 	; Arguments:
 18387                              <1> 	;	buffer - location of contiguous bytes to be writtten.
 18388                              <1> 	;	nchars - number of characters to be written.
 18389                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 18390                              <1> 	; Outputs: *u.r0 - number of bytes written.	
 18391                              <1> 	; ...............................................................
 18392                              <1> 	;				
 18393                              <1> 	; Retro UNIX 8086 v1 modification: 
 18394                              <1> 	;       'syswrite' system call has three arguments; so,
 18395                              <1> 	;	* 1st argument, file descriptor is in BX register
 18396                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 18397                              <1> 	;	* 3rd argument, number of bytes is in DX register
 18398                              <1> 	;
 18399                              <1> 	;	AX register (will be restored via 'u.r0') will return
 18400                              <1> 	;	to the user with number of bytes written. 
 18401                              <1> 	;
 18402 00005889 E822000000          <1> 	call	rw1
 18403 0000588E 0F8289FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
 18404                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
 18405 00005894 F6C480              <1>         test	ah, 80h
 18406                              <1> 		; tst r1 / positive i-number ?
 18407 00005897 744E                <1>         jz	short rw3 ; 13/05/2015
 18408                              <1> 	;jz	error
 18409                              <1> 		; bge error1 / yes, error 1 
 18410                              <1> 			   ; / negative i-number means write
 18411 00005899 66F7D8              <1>         neg	ax
 18412                              <1> 		; neg r1 / make it positive
 18413 0000589C E8D8110000          <1> 	call	writei
 18414                              <1>         	; jsr r0,writei / write data
 18415                              <1> rw0: ; 1:
 18416 000058A1 A1[80850000]        <1>         mov	eax, [u.nread]
 18417 000058A6 A3[58850000]        <1> 	mov	[u.r0], eax
 18418                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
 18419                              <1> 				  ; / into (u.r0)
 18420 000058AB E98DFCFFFF          <1> 	jmp	sysret
 18421                              <1>         	; br sysret1
 18422                              <1> rw1:	
 18423                              <1> 	; 14/05/2015
 18424                              <1> 	; 13/05/2015
 18425                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 18426                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
 18427                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
 18428                              <1> 	;
 18429                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
 18430                              <1> 				;(in the user's virtual memory space)
 18431                              <1> 	;mov	[u.count], edx 
 18432                              <1> 		; jsr r0,arg; u.base / get buffer pointer
 18433                              <1>         	; jsr r0,arg; u.count / get no. of characters
 18434                              <1> 	;;mov	eax, ebx ; file descriptor
 18435                              <1> 		; mov *u.r0,r1 / put file descriptor 
 18436                              <1> 		             ; / (index to u.fp table) in r1
 18437                              <1> 	; 13/05/2015
 18438 000058B0 C705[58850000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
 18439 000058B8 0000                <1>
 18440                              <1> 	;
 18441                              <1> 	;; call	getf
 18442                              <1>         ; eBX = File descriptor
 18443 000058BA E8E30A0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
 18444                              <1> 		; jsr r0,getf / get i-number of the file in r1
 18445                              <1> 	; AX = I-number of the file ; negative i-number means write
 18446                              <1> 	; 13/05/2015
 18447 000058BF 6683F801            <1> 	cmp 	ax, 1
 18448 000058C3 7217                <1> 	jb	short rw2
 18449                              <1> 	;
 18450 000058C5 890D[78850000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
 18451                              <1> 				;(in the user's virtual memory space)
 18452 000058CB 8915[7C850000]      <1> 	mov	[u.count], edx 
 18453                              <1> 	; 14/05/2015
 18454 000058D1 C705[AD850000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
 18455 000058D9 0000                <1>
 18456 000058DB C3                  <1> 	retn
 18457                              <1>         	; rts r0
 18458                              <1> rw2:
 18459                              <1> 	; 13/05/2015
 18460 000058DC C705[AD850000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 18461 000058E4 0000                <1>
 18462 000058E6 C3                  <1> 	retn
 18463                              <1> rw3: 
 18464                              <1> 	; 13/05/2015
 18465 000058E7 C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 18466 000058EF 0000                <1>
 18467 000058F1 F9                  <1> 	stc
 18468 000058F2 C3                  <1> 	retn
 18469                              <1> 
 18470                              <1> sysopen: ;<open file>
 18471                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 18472                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
 18473                              <1> 	;
 18474                              <1> 	; 'sysopen' opens a file in following manner:
 18475                              <1> 	;    1) The second argument in a sysopen says whether to
 18476                              <1> 	;	open the file ro read (0) or write (>0).
 18477                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
 18478                              <1> 	;    3) The file is opened by 'iopen'.
 18479                              <1> 	;    4) Next housekeeping is performed on the fsp table
 18480                              <1> 	;	and the user's open file list - u.fp.
 18481                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
 18482                              <1> 	;	b) An entry for the file is created in the fsp table.
 18483                              <1> 	;	c) The number of this entry is put on u.fp list.
 18484                              <1> 	;	d) The file descriptor index to u.fp list is pointed
 18485                              <1> 	;	   to by u.r0.
 18486                              <1> 	;
 18487                              <1> 	; Calling sequence:
 18488                              <1> 	;	sysopen; name; mode
 18489                              <1> 	; Arguments:
 18490                              <1> 	;	name - file name or path name
 18491                              <1> 	;	mode - 0 to open for reading
 18492                              <1> 	;	       1 to open for writing
 18493                              <1> 	; Inputs: (arguments)
 18494                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
 18495                              <1> 	;		  is put into r0's location on the stack.	
 18496                              <1> 	; ...............................................................
 18497                              <1> 	;				
 18498                              <1> 	; Retro UNIX 8086 v1 modification: 
 18499                              <1> 	;       'sysopen' system call has two arguments; so,
 18500                              <1> 	;	* 1st argument, name is pointed to by BX register
 18501                              <1> 	;	* 2nd argument, mode is in CX register
 18502                              <1> 	;
 18503                              <1> 	;	AX register (will be restored via 'u.r0') will return
 18504                              <1> 	;	to the user with the file descriptor/number 
 18505                              <1> 	;	(index to u.fp list).
 18506                              <1> 	;
 18507                              <1> 	;call	arg2
 18508                              <1> 	; * name - 'u.namep' points to address of file/path name
 18509                              <1> 	;          in the user's program segment ('u.segmnt')
 18510                              <1> 	;          with offset in BX register (as sysopen argument 1).
 18511                              <1> 	; * mode - sysopen argument 2 is in CX register 
 18512                              <1> 	;          which is on top of stack.
 18513                              <1> 	;
 18514                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
 18515                              <1> 	;
 18516                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
 18517                              <1> 
 18518 000058F3 891D[70850000]      <1> 	mov	[u.namep], ebx
 18519 000058F9 6651                <1> 	push	cx
 18520 000058FB E8D90A0000          <1> 	call	namei
 18521                              <1> 		; jsr r0,namei / i-number of file in r1
 18522                              <1>      	;and	ax, ax
 18523                              <1> 	;jz	error ; File not found
 18524 00005900 723B                <1> 	jc	short fnotfound ; 14/05/2015
 18525                              <1> 	;jc	error ; 27/05/2013
 18526                              <1> 		; br  error2 / file not found
 18527 00005902 665A                <1>    	pop	dx ; mode
 18528 00005904 6652                <1> 	push	dx
 18529                              <1> 	;or	dx, dx
 18530 00005906 08D2                <1> 	or	dl, dl
 18531                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
 18532                              <1> 		         ; / 0 means, open for read)
 18533 00005908 7403                <1> 	jz	short sysopen_0
 18534                              <1> 		; beq 1f / yes, leave i-number positive
 18535                              <1> syscreat_0: ; 27/12/2015
 18536 0000590A 66F7D8              <1> 	neg	ax
 18537                              <1>         	; neg r1 / open for writing so make i-number negative
 18538                              <1> sysopen_0: ;1:
 18539 0000590D E86D110000          <1> 	call	iopen
 18540                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
 18541 00005912 665A                <1> 	pop	dx
 18542                              <1> 	;and	dx, dx
 18543 00005914 20D2                <1> 	and	dl, dl
 18544                              <1>         	; tst (sp)+ / pop the stack and test the mode
 18545 00005916 7403                <1> 	jz	short sysopen_2
 18546                              <1>         	; beq op1 / is open for read op1
 18547                              <1> sysopen_1: ;op0:
 18548 00005918 66F7D8              <1> 	neg	ax
 18549                              <1>         	; neg r1 
 18550                              <1> 		     ;/ make i-number positive if open for writing [???]
 18551                              <1> 	;; NOTE: iopen always make i-number positive.
 18552                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
 18553                              <1> sysopen_2: ;op1:
 18554 0000591B 31F6                <1>         xor     esi, esi
 18555                              <1>         	; clr r2 / clear registers
 18556 0000591D 31DB                <1>         xor     ebx, ebx
 18557                              <1> 		; clr r3
 18558                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
 18559 0000591F 389E[5E850000]      <1>         cmp     [esi+u.fp], bl ; 0
 18560                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
 18561 00005925 7625                <1>         jna      short sysopen_4
 18562                              <1> 		; beq 1f / if byte in list is 0 branch
 18563 00005927 46                  <1>         inc     esi
 18564                              <1> 		; inc r2 / bump r2 so next byte can be checked
 18565 00005928 6683FE0A            <1>         cmp     si, 10
 18566                              <1> 		; cmp r2,$10. / reached end of list?
 18567 0000592C 72F1                <1> 	jb	short sysopen_3
 18568                              <1> 		; blt 1b / no, go back
 18569                              <1> toomanyf:
 18570                              <1> 	; 14/05/2015
 18571 0000592E C705[AD850000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
 18572 00005936 0000                <1>
 18573 00005938 E9E0FBFFFF          <1> 	jmp	error
 18574                              <1>         	; br error2 / yes, error (no files open)
 18575                              <1> fnotfound: 
 18576                              <1> 	; 14/05/2015
 18577 0000593D C705[AD850000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
 18578 00005945 0000                <1>
 18579 00005947 E9D1FBFFFF          <1> 	jmp	error
 18580                              <1> 
 18581                              <1> sysopen_4: ; 1:
 18582 0000594C 6683BB[2C830000]00  <1>         cmp     word [ebx+fsp], 0
 18583                              <1> 		; tst fsp(r3) / scan fsp entries
 18584 00005954 7610                <1>         jna     short sysopen_5
 18585                              <1> 		; beq 1f / if 0 branch
 18586                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
 18587 00005956 6683C30A            <1>         add     bx, 10 ; fsp structure size = 10 bytes/entry
 18588                              <1> 		; add $8.,r3 / add 8 to r3 
 18589                              <1> 			; / to bump it to next entry mfsp table
 18590 0000595A 6681FBF401          <1>         cmp     bx, nfiles*10
 18591                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
 18592 0000595F 72EB                <1> 	jb	short sysopen_4
 18593                              <1>        		; blt 1b / no, back
 18594 00005961 E9B7FBFFFF          <1> 	jmp	error
 18595                              <1>         	; br error2 / yes, error
 18596                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
 18597 00005966 668983[2C830000]    <1>         mov     [ebx+fsp], ax
 18598                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
 18599                              <1> 			; / into next available entry in fsp table,
 18600 0000596D 668B3D[3C850000]    <1> 	mov	di, [cdev] ; word ? byte ?
 18601 00005974 6689BB[2E830000]    <1>         mov     [ebx+fsp+2], di ; device number
 18602                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
 18603 0000597B 31FF                <1>         xor	edi, edi
 18604 0000597D 89BB[30830000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
 18605                              <1> 		; clr fsp+4(r3)
 18606 00005983 6689BB[34830000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
 18607                              <1>        		; clr fsp+6(r3) / clear the next two words
 18608 0000598A 89D8                <1>   	mov	eax, ebx
 18609 0000598C B30A                <1> 	mov	bl, 10
 18610 0000598E F6F3                <1> 	div	bl 
 18611                              <1> 		; asr r3
 18612                              <1> 		; asr r3 / divide by 8 
 18613                              <1> 		; asr r3 ; / to get number of the fsp entry-1
 18614 00005990 FEC0                <1> 	inc	al
 18615                              <1>         	; inc r3 / add 1 to get fsp entry number
 18616 00005992 8886[5E850000]      <1>         mov     [esi+u.fp], al
 18617                              <1> 		; movb r3,u.fp(r2) / move entry number into 
 18618                              <1> 			; / next available slot in u.fp list
 18619 00005998 8935[58850000]      <1>         mov     [u.r0], esi
 18620                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
 18621                              <1> 			     ; / into r0 loc on stack
 18622 0000599E E99AFBFFFF          <1>         jmp	sysret
 18623                              <1> 		; br sysret2
 18624                              <1> 
 18625                              <1> 	;
 18626                              <1> 	; 'fsp' table (10 bytes/entry)
 18627                              <1> 	; bit 15				   bit 0
 18628                              <1> 	; ---|-------------------------------------------
 18629                              <1> 	; r/w|		i-number of open file
 18630                              <1> 	; ---|-------------------------------------------
 18631                              <1> 	;		   device number
 18632                              <1> 	; -----------------------------------------------
 18633                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 18634                              <1> 	; -----------------------------------------------
 18635                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 18636                              <1> 	; ----------------------|------------------------
 18637                              <1> 	;  flag that says file 	| number of processes
 18638                              <1> 	;   has been deleted	| that have file open 
 18639                              <1> 	; ----------------------|------------------------
 18640                              <1> 	;
 18641                              <1> 
 18642                              <1> syscreat: ; < create file >
 18643                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
 18644                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 18645                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
 18646                              <1> 	;
 18647                              <1> 	; 'syscreat' called with two arguments; name and mode.
 18648                              <1> 	; u.namep points to name of the file and mode is put
 18649                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
 18650                              <1> 	; If the file aready exists, it's mode and owner remain 
 18651                              <1> 	; unchanged, but it is truncated to zero length. If the file
 18652                              <1> 	; did not exist, an i-node is created with the new mode via
 18653                              <1> 	; 'maknod' whether or not the file already existed, it is
 18654                              <1> 	; open for writing. The fsp table is then searched for a free
 18655                              <1> 	; entry. When a free entry is found, proper data is placed
 18656                              <1> 	; in it and the number of this entry is put in the u.fp list.
 18657                              <1> 	; The index to the u.fp (also know as the file descriptor)
 18658                              <1> 	; is put in the user's r0. 			
 18659                              <1> 	;
 18660                              <1> 	; Calling sequence:
 18661                              <1> 	;	syscreate; name; mode
 18662                              <1> 	; Arguments:
 18663                              <1> 	;	name - name of the file to be created
 18664                              <1> 	;	mode - mode of the file to be created
 18665                              <1> 	; Inputs: (arguments)
 18666                              <1> 	; Outputs: *u.r0 - index to u.fp list 
 18667                              <1> 	;		   (the file descriptor of new file)
 18668                              <1> 	; ...............................................................
 18669                              <1> 	;				
 18670                              <1> 	; Retro UNIX 8086 v1 modification: 
 18671                              <1> 	;       'syscreate' system call has two arguments; so,
 18672                              <1> 	;	* 1st argument, name is pointed to by BX register
 18673                              <1> 	;	* 2nd argument, mode is in CX register
 18674                              <1> 	;
 18675                              <1> 	;	AX register (will be restored via 'u.r0') will return
 18676                              <1> 	;	to the user with the file descriptor/number 
 18677                              <1> 	;	(index to u.fp list).
 18678                              <1> 	;
 18679                              <1> 	;call	arg2
 18680                              <1> 	; * name - 'u.namep' points to address of file/path name
 18681                              <1> 	;          in the user's program segment ('u.segmnt')
 18682                              <1> 	;          with offset in BX register (as sysopen argument 1).
 18683                              <1> 	; * mode - sysopen argument 2 is in CX register 
 18684                              <1> 	;          which is on top of stack.
 18685                              <1> 	;
 18686                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
 18687                              <1> 			    ; / on stack
 18688 000059A3 891D[70850000]      <1> 	mov	[u.namep], ebx ; file name address
 18689 000059A9 6651                <1> 	push	cx ; mode
 18690 000059AB E8290A0000          <1> 	call 	namei        	
 18691                              <1> 		; jsr r0,namei / get the i-number
 18692                              <1>         ;and	ax, ax
 18693                              <1> 	;jz	short syscreat_1	       	
 18694 000059B0 721E                <1> 	jc	short syscreat_1
 18695                              <1> 		; br  2f / if file doesn't exist 2f
 18696                              <1> 	; 27/12/2015
 18697 000059B2 6683F829            <1> 	cmp	ax, 41 ; device inode ?
 18698 000059B6 0F824EFFFFFF        <1>         jb      syscreat_0 ; yes
 18699                              <1> 	;
 18700 000059BC 66F7D8              <1> 	neg 	ax
 18701                              <1>         	; neg r1 / if file already exists make i-number 
 18702                              <1> 		       ; / negative (open for writing)
 18703 000059BF E8BB100000          <1> 	call	iopen
 18704                              <1>         	; jsr r0,iopen /
 18705 000059C4 E8B8100000          <1> 	call	itrunc
 18706                              <1>         	; jsr r0,itrunc / truncate to 0 length
 18707 000059C9 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
 18708 000059CB E948FFFFFF          <1>         jmp     sysopen_1
 18709                              <1>         	; br op0
 18710                              <1> syscreat_1: ; 2: / file doesn't exist
 18711 000059D0 6658                <1> 	pop	ax
 18712                              <1>         	; mov (sp)+,r1 / put the mode in r1
 18713 000059D2 30E4                <1> 	xor	ah, ah	
 18714                              <1>         	; bic $!377,r1 / clear upper byte
 18715 000059D4 E8D30C0000          <1> 	call 	maknod
 18716                              <1>         	; jsr r0,maknod / make an i-node for this file
 18717 000059D9 66A1[8A850000]      <1> 	mov	ax, [u.dirbuf]
 18718                              <1>         	; mov u.dirbuf,r1 / put i-number 
 18719                              <1> 			        ; / for this new file in r1
 18720 000059DF E934FFFFFF          <1>         jmp     sysopen_1
 18721                              <1>         	; br op0 / open the file
 18722                              <1> 
 18723                              <1> sysmkdir: ; < make directory >
 18724                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 18725                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18726                              <1> 	;
 18727                              <1> 	; 'sysmkdir' creates an empty directory whose name is
 18728                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
 18729                              <1> 	; The special entries '.' and '..' are not present.
 18730                              <1> 	; Errors are indicated if the directory already exists or		
 18731                              <1> 	; user is not the super user. 
 18732                              <1> 	;
 18733                              <1> 	; Calling sequence:
 18734                              <1> 	;	sysmkdir; name; mode
 18735                              <1> 	; Arguments:
 18736                              <1> 	;	name - points to the name of the directory
 18737                              <1> 	;	mode - mode of the directory
 18738                              <1> 	; Inputs: (arguments)
 18739                              <1> 	; Outputs: -
 18740                              <1> 	;    (sets 'directory' flag to 1; 
 18741                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
 18742                              <1> 	; ...............................................................
 18743                              <1> 	;				
 18744                              <1> 	; Retro UNIX 8086 v1 modification: 
 18745                              <1> 	;       'sysmkdir' system call has two arguments; so,
 18746                              <1> 	;	* 1st argument, name is pointed to by BX register
 18747                              <1> 	;	* 2nd argument, mode is in CX register
 18748                              <1> 	;
 18749                              <1> 		
 18750                              <1> ; / make a directory
 18751                              <1> 
 18752                              <1> 	;call	arg2
 18753                              <1> 	; * name - 'u.namep' points to address of file/path name
 18754                              <1> 	;          in the user's program segment ('u.segmnt')
 18755                              <1> 	;          with offset in BX register (as sysopen argument 1).
 18756                              <1> 	; * mode - sysopen argument 2 is in CX register 
 18757                              <1> 	;          which is on top of stack.
 18758                              <1> 
 18759                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
 18760                              <1> 			    ; / on stack
 18761 000059E4 891D[70850000]      <1> 	mov	[u.namep], ebx
 18762 000059EA 6651                <1> 	push	cx ; mode
 18763 000059EC E8E8090000          <1> 	call	namei
 18764                              <1>         	; jsr r0,namei / get the i-number
 18765                              <1>         	;     br .+4 / if file not found branch around error
 18766                              <1>         ;xor 	ax, ax
 18767                              <1> 	;jnz	error
 18768 000059F1 731C                <1> 	jnc	short dir_exists ; 14/05/2015
 18769                              <1> 	;jnc	error	
 18770                              <1> 		; br  error2 / directory already exists (error)
 18771 000059F3 803D[A4850000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 18772                              <1>         	;tstb u.uid / is user the super user
 18773 000059FA 7622                <1> 	jna	short dir_access_err ; 14/05/2015
 18774                              <1> 	;jna	error
 18775                              <1>         	;bne error2 / no, not allowed
 18776 000059FC 6658                <1> 	pop	ax
 18777                              <1>         	;mov (sp)+,r1 / put the mode in r1
 18778 000059FE 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
 18779                              <1>         	;bic $!317,r1 / all but su and ex
 18780                              <1> 	;or	ax , 4000h ; 1011111111111111b
 18781 00005A02 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
 18782                              <1>         	;bis $40000,r1 / directory flag
 18783 00005A05 E8A20C0000          <1> 	call	maknod
 18784                              <1>         	;jsr r0,maknod / make the i-node for the directory
 18785 00005A0A E92EFBFFFF          <1> 	jmp	sysret
 18786                              <1>         	;br sysret2 /
 18787                              <1> dir_exists:
 18788                              <1> 	; 14/05/2015
 18789 00005A0F C705[AD850000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
 18790 00005A17 0000                <1>
 18791 00005A19 E9FFFAFFFF          <1> 	jmp	error
 18792                              <1> dir_access_err:
 18793                              <1> 	; 14/05/2015
 18794 00005A1E C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 18795 00005A26 0000                <1>
 18796 00005A28 E9F0FAFFFF          <1> 	jmp	error
 18797                              <1> 
 18798                              <1> sysclose: ;<close file>
 18799                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 18800                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
 18801                              <1> 	;
 18802                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
 18803                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
 18804                              <1> 	; is put in r1 and 'fclose' is called.
 18805                              <1> 	;
 18806                              <1> 	; Calling sequence:
 18807                              <1> 	;	sysclose
 18808                              <1> 	; Arguments:
 18809                              <1> 	;	-  
 18810                              <1> 	; Inputs: *u.r0 - file descriptor
 18811                              <1> 	; Outputs: -
 18812                              <1> 	; ...............................................................
 18813                              <1> 	;				
 18814                              <1> 	; Retro UNIX 8086 v1 modification:
 18815                              <1> 	;	 The user/application program puts file descriptor
 18816                              <1> 	;        in BX register as 'sysclose' system call argument.
 18817                              <1> 	; 	 (argument transfer method 1)
 18818                              <1> 
 18819                              <1> 	; / close the file
 18820                              <1> 	
 18821 00005A2D 89D8                <1> 	mov 	eax, ebx
 18822 00005A2F E823090000          <1> 	call 	fclose
 18823                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
 18824                              <1> 		; jsr r0,fclose / close the file
 18825                              <1>                	; br error2 / unknown file descriptor
 18826                              <1> 		; br sysret2
 18827                              <1> 	; 14/05/2015
 18828 00005A34 0F8303FBFFFF        <1> 	jnc	sysret
 18829 00005A3A C705[AD850000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 18830 00005A42 0000                <1>
 18831 00005A44 E9D4FAFFFF          <1> 	jmp	error
 18832                              <1> 
 18833                              <1> sysemt:
 18834                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 18835                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
 18836                              <1> 	;
 18837                              <1> 	; Retro UNIX 8086 v1 modification: 
 18838                              <1> 	;	'Enable Multi Tasking'  system call instead 
 18839                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
 18840                              <1> 	;
 18841                              <1> 	; Retro UNIX 8086 v1 feature only!
 18842                              <1> 	;	Using purpose: Kernel will start without time-out
 18843                              <1> 	;	(internal clock/timer) functionality.
 18844                              <1> 	;	Then etc/init will enable clock/timer for
 18845                              <1> 	;	multi tasking. (Then it will not be disabled again
 18846                              <1> 	;	except hardware reset/restart.)
 18847                              <1> 	;
 18848                              <1> 
 18849 00005A49 803D[A4850000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
 18850                              <1> 	;ja	error
 18851 00005A50 0F8770FBFFFF        <1> 	ja	badsys ; 14/05/2015
 18852                              <1> emt_0:
 18853 00005A56 FA                  <1> 	cli
 18854 00005A57 21DB                <1> 	and	ebx, ebx
 18855 00005A59 7410                <1> 	jz	short emt_2
 18856                              <1> 	; Enable multi tasking -time sharing-
 18857 00005A5B B8[826A0000]        <1> 	mov	eax, clock
 18858                              <1> emt_1:
 18859 00005A60 A3[35080000]        <1> 	mov	[x_timer], eax
 18860 00005A65 FB                  <1> 	sti
 18861 00005A66 E9D2FAFFFF          <1> 	jmp	sysret
 18862                              <1> emt_2:
 18863                              <1> 	; Disable multi tasking -time sharing-
 18864 00005A6B B8[3D080000]        <1> 	mov	eax, u_timer
 18865 00005A70 EBEE                <1> 	jmp	short emt_1
 18866                              <1> 
 18867                              <1> 	; Original UNIX v1 'sysemt' routine
 18868                              <1> ;sysemt:
 18869                              <1>         ;
 18870                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
 18871                              <1> 			 ; / in loc 30
 18872                              <1>         ;cmp    30,$core / was the argument a lower address 
 18873                              <1> 			; / than core
 18874                              <1>         ;blo    1f / yes, rtssym
 18875                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
 18876                              <1> 			; / and less than "ecore"
 18877                              <1>         ;blo    2f / yes, sysret2
 18878                              <1> ;1:
 18879                              <1>         ;mov    $rtssym,30
 18880                              <1> ;2:
 18881                              <1>         ;br     sysret2
 18882                              <1> 
 18883                              <1> sysilgins:
 18884                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 18885                              <1> 	; 03/06/2013
 18886                              <1> 	; Retro UNIX 8086 v1 modification: 
 18887                              <1> 	;	not a valid system call ! (not in use)
 18888                              <1> 	;
 18889 00005A72 E94FFBFFFF          <1> 	jmp	badsys
 18890                              <1> 	;jmp	error
 18891                              <1> 	;;jmp 	sysret
 18892                              <1> 
 18893                              <1> 	; Original UNIX v1 'sysemt' routine
 18894                              <1> ;sysilgins: / calculate proper illegal instruction trap address
 18895                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
 18896                              <1> 			  ;/ put it in loc 8.,
 18897                              <1>         ;cmp    10,$core / making it the illegal instruction 
 18898                              <1> 		       ; / trap address
 18899                              <1>         ;blo    1f / is the address a user core address?  
 18900                              <1> 		; / yes, go to 2f
 18901                              <1>         ;cmp    10,$ecore
 18902                              <1>         ;blo    2f
 18903                              <1> ;1:
 18904                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
 18905                              <1> 		    ; / instruction trap address for the system
 18906                              <1> ;2:
 18907                              <1>         ;br     sysret2 / return to the caller via 'sysret'
 18908                              <1> 
 18909                              <1> sysmdate: ; < change the modification time of a file >
 18910                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 18911                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 18912                              <1> 	;
 18913                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
 18914                              <1> 	; file into core. The user is checked if he is the owner 
 18915                              <1> 	; or super user. If he is neither an error occurs.
 18916                              <1> 	; 'setimod' is then called to set the i-node modification
 18917                              <1> 	; byte and the modification time, but the modification time
 18918                              <1> 	; is overwritten by whatever get put on the stack during
 18919                              <1> 	; a 'systime' system call. This calls are restricted to
 18920                              <1> 	; the super user.		
 18921                              <1> 	;
 18922                              <1> 	; Calling sequence:
 18923                              <1> 	;	sysmdate; name
 18924                              <1> 	; Arguments:
 18925                              <1> 	;	name - points to the name of file
 18926                              <1> 	; Inputs: (arguments)
 18927                              <1> 	; Outputs: -
 18928                              <1> 	; ...............................................................
 18929                              <1> 	;				
 18930                              <1> 	; Retro UNIX 8086 v1 modification: 
 18931                              <1> 	;	 The user/application program puts address 
 18932                              <1> 	;	 of the file name in BX register 
 18933                              <1> 	;	 as 'sysmdate' system call argument.
 18934                              <1> 	;
 18935                              <1> ; / change the modification time of a file
 18936                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
 18937 00005A77 891D[70850000]      <1>         mov	[u.namep], ebx
 18938 00005A7D E857090000          <1> 	call	namei
 18939                              <1> 		; jsr r0,namei / get its i-number
 18940 00005A82 0F82B5FEFFFF        <1>         jc	fnotfound ; file not found !
 18941                              <1> 	;jc	error       
 18942                              <1> 		; br error2 / no, such file
 18943 00005A88 E8E80F0000          <1> 	call	iget
 18944                              <1> 		; jsr r0,iget / get i-node into core
 18945 00005A8D A0[A4850000]        <1> 	mov	al, [u.uid]
 18946 00005A92 3A05[2F820000]      <1> 	cmp	al, [i.uid]
 18947                              <1>         	; cmpb u.uid,i.uid / is user same as owner
 18948 00005A98 7413                <1> 	je	short mdate_1
 18949                              <1>         	; beq 1f / yes
 18950 00005A9A 20C0                <1> 	and	al, al
 18951                              <1> 		; tstb u.uid / no, is user the super user
 18952                              <1> 	;jnz	error
 18953                              <1> 		; bne error2 / no, error
 18954 00005A9C 740F                <1> 	jz	short mdate_1
 18955 00005A9E C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 18956 00005AA6 0000                <1>
 18957 00005AA8 E970FAFFFF          <1> 	jmp	error
 18958                              <1> mdate_1: ;1:
 18959 00005AAD E8D10F0000          <1> 	call	setimod
 18960                              <1>         	; jsr r0,setimod / fill in modification data,
 18961                              <1> 		               ; / time etc.
 18962 00005AB2 BE[12790000]        <1> 	mov	esi, p_time
 18963 00005AB7 BF[46820000]        <1> 	mov	edi, i.mtim
 18964 00005ABC A5                  <1> 	movsd
 18965                              <1> 		; mov 4(sp),i.mtim / move present time to
 18966                              <1>         	; mov 2(sp),i.mtim+2 / modification time
 18967 00005ABD E97BFAFFFF          <1>         jmp	sysret
 18968                              <1> 		; br sysret2
 18969                              <1> 
 18970                              <1> sysstty: ; < set tty status and mode >
 18971                              <1> 	; 17/11/2015
 18972                              <1> 	; 12/11/2015
 18973                              <1> 	; 29/10/2015
 18974                              <1> 	; 17/10/2015
 18975                              <1> 	; 13/10/2015
 18976                              <1> 	; 29/06/2015
 18977                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
 18978                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 18979                              <1> 	;
 18980                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
 18981                              <1> 	; whose file descriptor is in (u.r0).
 18982                              <1> 	;
 18983                              <1> 	; Calling sequence:
 18984                              <1> 	;	sysstty; arg
 18985                              <1> 	; Arguments:
 18986                              <1> 	;	arg - address of 3 consequitive words that contain
 18987                              <1> 	;	      the source of status data	
 18988                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
 18989                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 18990                              <1> 	; ...............................................................
 18991                              <1> 	;	
 18992                              <1> 	; Retro UNIX 8086 v1 modification: 
 18993                              <1> 	;	'sysstty' system call will set the tty
 18994                              <1> 	;	(clear keyboard buffer and set cursor position)
 18995                              <1> 	;	 in following manner:
 18996                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
 18997                              <1> 	;
 18998                              <1> 	; Inputs:
 18999                              <1> 	;	BX = 0 --> means
 19000                              <1> 	;	   If CL = FFh
 19001                              <1> 	;	      set cursor position for console tty, only 
 19002                              <1> 	;	      CH will be ignored (char. will not be written)	
 19003                              <1> 	;	   If CH = 0 (CL < FFh)
 19004                              <1> 	;	      set console tty for (current) process
 19005                              <1> 	;	      CL = tty number (0 to 9)
 19006                              <1> 	;	      (If CH = 0, character will not be written)			
 19007                              <1> 	;          If CH > 0 (CL < FFh)	
 19008                              <1> 	;             CL = tty number (0 to 9)
 19009                              <1> 	;	      CH = character will be written
 19010                              <1> 	;	        at requested cursor position (in DX)	
 19011                              <1> 	;	   DX = cursor position for tty number 0 to 7.	
 19012                              <1>   	;		(only tty number 0 to 7) 
 19013                              <1> 	;          DL = communication parameters (for serial ports) 
 19014                              <1> 	;	        (only for COM1 and COM2 serial ports)
 19015                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
 19016                              <1> 	;			or set cursor position	
 19017                              <1> 	;	   DH = 0FFh -> DL is not valid
 19018                              <1> 	;		do not set serial port parameters 
 19019                              <1> 	;		or do not set cursor position
 19020                              <1> 	;
 19021                              <1> 	;	BX > 0 --> points to name of tty
 19022                              <1> 	;    	   CH > 0 -->
 19023                              <1> 	;		CH = character will be written in current 
 19024                              <1> 	;            	cursor position (for tty number from 0 to 7)
 19025                              <1> 	;	     	or character will be sent to serial port
 19026                              <1> 	;	     	(for tty number 8 or 9)
 19027                              <1> 	;		CL = color of the character if tty number < 8.
 19028                              <1> 	;    	   CH = 0 --> Do not write a character, 
 19029                              <1> 	;		set mode (tty 8 to 9) or 
 19030                              <1> 	;		set current cursor positions (tty 0 to 7) only. 
 19031                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
 19032                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
 19033                              <1> 	;		(DL is not valid)
 19034                              <1> 	;	   DL = communication parameters 
 19035                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
 19036                              <1> 	; Outputs:
 19037                              <1> 	;	cf = 0 -> OK
 19038                              <1> 	;	     AL = tty number (0 to 9)
 19039                              <1> 	;	     AH = line status if tty number is 8 or 9
 19040                              <1> 	;	     AH = process number (of the caller) 	
 19041                              <1> 	;	cf = 1 means error (requested tty is not ready)
 19042                              <1> 	;	     AH = FFh if the tty is locked 
 19043                              <1> 	;		  (owned by another process)
 19044                              <1> 	;	        = process number (of the caller) 
 19045                              <1> 	;		  (if < FFh and tty number < 8)
 19046                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 19047                              <1> 	;	     AH = line status if tty number is 8 or 9
 19048                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
 19049                              <1> 	;
 19050                              <1> 	; 27/06/2015 (32 bit modifications)
 19051                              <1> 	; 14/01/2014
 19052 00005AC2 31C0                <1> 	xor 	eax, eax
 19053 00005AC4 6648                <1> 	dec	ax ; 17/10/2015
 19054 00005AC6 A3[58850000]        <1> 	mov	[u.r0], eax ; 0FFFFh
 19055 00005ACB 21DB                <1> 	and	ebx, ebx
 19056 00005ACD 0F85CB000000        <1>         jnz     sysstty_6
 19057                              <1> ; set console tty
 19058                              <1> 	; 29/10/2015
 19059                              <1> 	; 17/01/2014 
 19060 00005AD3 80F909              <1> 	cmp	cl, 9
 19061 00005AD6 7613                <1> 	jna	short sysstty_0
 19062                              <1> 	; 17/11/2015
 19063 00005AD8 80F9FF              <1> 	cmp	cl, 0FFh
 19064 00005ADB 7202                <1> 	jb	short sysstty_13
 19065 00005ADD 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
 19066                              <1> sysstty_13:
 19067 00005ADF 8A1D[A7850000]      <1> 	mov	bl, [u.uno] ; process number
 19068 00005AE5 8A8B[AB820000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
 19069                              <1> sysstty_0:
 19070                              <1> 	; 29/06/2015
 19071 00005AEB 6652                <1> 	push	dx
 19072 00005AED 6651                <1> 	push	cx
 19073 00005AEF 30D2                <1> 	xor 	dl, dl	; sysstty call sign
 19074 00005AF1 88C8                <1> 	mov	al, cl
 19075 00005AF3 A2[58850000]        <1> 	mov	[u.r0], al ; tyy number (0 to 9)
 19076 00005AF8 E8870F0000          <1> 	call	ottyp
 19077 00005AFD 6659                <1> 	pop	cx
 19078 00005AFF 665A                <1> 	pop	dx
 19079                              <1> 	;
 19080 00005B01 7257                <1> 	jc	short sysstty_pd_err
 19081                              <1> 	;
 19082 00005B03 80F908              <1> 	cmp	cl, 8
 19083 00005B06 7222                <1> 	jb	short sysstty_2
 19084                              <1> 	;
 19085 00005B08 80FEFF              <1> 	cmp	dh, 0FFh
 19086 00005B0B 741D                <1> 	je	short sysstty_2
 19087                              <1> 		; set communication parameters for serial ports
 19088                              <1> 	; 29/10/2015
 19089 00005B0D 88D4                <1> 	mov	ah, dl ; communication parameters
 19090                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
 19091                              <1> 		;			 THRE int + RDA int 
 19092                              <1> 		; ah = 23h = 00100011b = 9600 baud,
 19093                              <1> 		;			 THRE int + RDA int 
 19094 00005B0F 28C0                <1> 	sub	al, al ; 0
 19095                              <1> 	; 12/07/2014
 19096 00005B11 80F909              <1> 	cmp	cl, 9
 19097 00005B14 7202                <1> 	jb	short sysstty_1
 19098 00005B16 FEC0                <1> 	inc	al
 19099                              <1> sysstty_1:
 19100 00005B18 6651                <1> 	push	cx
 19101                              <1> 	; 29/06/2015	
 19102 00005B1A E8EF110000          <1> 	call 	sp_setp ; Set serial port communication parameters
 19103 00005B1F 66890D[59850000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
 19104                              <1> 			     ; Modem status (EAX bits 16 to 23)
 19105 00005B26 6659                <1> 	pop	cx
 19106 00005B28 7265                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 19107                              <1> sysstty_2:
 19108                              <1> 	; 17/01/2014
 19109 00005B2A 20ED                <1> 	and	ch, ch 	; set cursor position 
 19110                              <1> 			; or comm. parameters ONLY
 19111 00005B2C 750D                <1> 	jnz	short sysstty_3
 19112 00005B2E 0FB61D[A7850000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 19113 00005B35 888B[AB820000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
 19114                              <1> sysstty_3:
 19115                              <1> 	; 16/01/2014
 19116 00005B3B 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
 19117                              <1> 	; 17/11/2015
 19118 00005B3D B507                <1> 	mov 	ch, 7  ; Default color (light gray)
 19119 00005B3F 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
 19120 00005B41 0F86C5000000        <1>         jna     sysstty_9
 19121                              <1> sysstty_12:
 19122                              <1> 	;; BX = 0, CL = 8 or CL = 9
 19123                              <1> 	; (Set specified serial port as console tty port)
 19124                              <1> 	; CH = character to be written
 19125                              <1> 	; 15/04/2014
 19126                              <1> 	; CH = 0 --> initialization only
 19127                              <1> 	; AL = character
 19128                              <1> 	; 26/06/2014
 19129 00005B47 880D[AC850000]      <1> 	mov	[u.ttyn], cl
 19130                              <1> 	; 12/07/2014
 19131 00005B4D 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
 19132 00005B4F 20C0                <1> 	and	al, al
 19133 00005B51 7416                <1> 	jz	short sysstty_4 ; al = ch = 0
 19134                              <1>  	; 04/07/2014
 19135 00005B53 E82E0F0000          <1> 	call 	sndc
 19136                              <1> 	; 12/07/2014
 19137 00005B58 EB1B                <1> 	jmp	short sysstty_5
 19138                              <1> sysstty_pd_err: ; 29/06/2015
 19139                              <1> 	; 'permission denied !' error
 19140 00005B5A C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
 19141 00005B62 0000                <1>
 19142 00005B64 E9B4F9FFFF          <1> 	jmp	error
 19143                              <1> sysstty_4:
 19144                              <1> 	; 12/07/2014
 19145                              <1> 	;xchg 	ah, al	; al = 0 -> al = ah, ah = 0
 19146 00005B69 88E0                <1> 	mov	al, ah ; 29/06/2015
 19147 00005B6B 2C08                <1> 	sub	al, 8
 19148                              <1> 	; 27/06/2015
 19149 00005B6D E894110000          <1> 	call	sp_status ; get serial port status
 19150                              <1> 	; AL = Line status, AH = Modem status
 19151                              <1> 	; 12/11/2015
 19152 00005B72 3C80                <1> 	cmp	al, 80h
 19153 00005B74 F5                  <1> 	cmc
 19154                              <1> sysstty_5:
 19155 00005B75 66A3[59850000]      <1> 	mov	[u.r0+1], ax ; ah = line status
 19156                              <1> 		     ; EAX bits 16-23 = modem status	
 19157 00005B7B 9C                  <1> 	pushf
 19158 00005B7C 30D2                <1> 	xor	dl, dl ; sysstty call sign
 19159 00005B7E A0[AC850000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
 19160 00005B83 E8FD0E0000          <1> 	call	cttyp
 19161 00005B88 9D                  <1> 	popf
 19162 00005B89 0F83AEF9FFFF        <1> 	jnc	sysret	; time out error 
 19163                              <1> 
 19164                              <1> sysstty_tmout_err:
 19165 00005B8F C705[AD850000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
 19166 00005B97 0000                <1>
 19167 00005B99 E97FF9FFFF          <1> 	jmp	error
 19168                              <1> sysstty_6:
 19169 00005B9E 6652                <1> 	push	dx
 19170 00005BA0 6651                <1> 	push	cx
 19171 00005BA2 891D[70850000]      <1> 	mov	[u.namep], ebx
 19172 00005BA8 E82C080000          <1> 	call	namei
 19173 00005BAD 6659                <1> 	pop	cx
 19174 00005BAF 665A                <1> 	pop	dx
 19175 00005BB1 720E                <1> 	jc	short sysstty_inv_dn
 19176                              <1> 	;
 19177 00005BB3 6683F813            <1> 	cmp	ax, 19  ; inode number of /dev/COM2
 19178 00005BB7 7708                <1> 	ja	short sysstty_inv_dn ; 27/06/2015
 19179                              <1> 	;
 19180 00005BB9 3C0A                <1> 	cmp	al, 10 ; /dev/tty0 .. /dev/tty7
 19181                              <1> 		       ; /dev/COM1, /dev/COM2
 19182 00005BBB 7213                <1> 	jb	short sysstty_7
 19183 00005BBD 2C0A                <1> 	sub	al, 10
 19184 00005BBF EB20                <1> 	jmp	short sysstty_8
 19185                              <1> sysstty_inv_dn: 
 19186                              <1> 	; 27/06/2015
 19187                              <1> 	; Invalid device name (not a tty) ! error
 19188                              <1> 	; (Device is not a tty or device name not found)
 19189 00005BC1 C705[AD850000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 19190 00005BC9 0000                <1>
 19191 00005BCB E94DF9FFFF          <1> 	jmp	error 
 19192                              <1> sysstty_7:
 19193 00005BD0 3C01                <1> 	cmp	al, 1 ; /dev/tty
 19194 00005BD2 75ED                <1> 	jne	short sysstty_inv_dn ; 27/06/2015
 19195 00005BD4 0FB61D[A7850000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 19196 00005BDB 8A83[AB820000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
 19197                              <1> sysstty_8:	
 19198 00005BE1 A2[58850000]        <1> 	mov	[u.r0], al
 19199 00005BE6 6652                <1> 	push	dx
 19200 00005BE8 6650                <1> 	push	ax
 19201 00005BEA 6651                <1> 	push	cx	
 19202 00005BEC E8930E0000          <1> 	call	ottyp
 19203 00005BF1 6659                <1> 	pop	cx
 19204 00005BF3 6658                <1> 	pop	ax
 19205 00005BF5 665A                <1> 	pop	dx
 19206 00005BF7 0F825DFFFFFF        <1>         jc      sysstty_pd_err ; 'permission denied !'
 19207                              <1> 	; 29/10/2015
 19208 00005BFD 86E9                <1> 	xchg 	ch, cl
 19209                              <1> 		; cl = character, ch = color code
 19210 00005BFF 86C1                <1> 	xchg	al, cl
 19211                              <1> 		; al = character, cl = tty number
 19212 00005C01 80F907              <1> 	cmp	cl, 7
 19213 00005C04 0F873DFFFFFF        <1>         ja      sysstty_12
 19214                              <1> 	;
 19215                              <1> 	; 16/01/2014
 19216 00005C0A 30FF                <1> 	xor	bh, bh
 19217                              <1> 	;
 19218                              <1> sysstty_9: 	; tty 0 to tty 7
 19219                              <1> 	; al = character
 19220 00005C0C 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
 19221 00005C0F 740F                <1> 	je	short sysstty_10
 19222 00005C11 6651                <1> 	push	cx
 19223 00005C13 6650                <1> 	push	ax	
 19224                              <1> 	; movzx, ebx, cl
 19225 00005C15 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
 19226 00005C17 E8A1BCFFFF          <1> 	call	_set_cpos
 19227 00005C1C 6658                <1> 	pop	ax
 19228 00005C1E 6659                <1> 	pop	cx
 19229                              <1> sysstty_10: 
 19230                              <1> 	; 29/10/2015
 19231 00005C20 08C0                <1> 	or	al, al ; character
 19232 00005C22 740F                <1> 	jz      short sysstty_11 ; al = 0
 19233                              <1> 	; 17/11/2015
 19234 00005C24 3CFF                <1> 	cmp	al, 0FFh
 19235 00005C26 730B                <1> 	jnb	short sysstty_11
 19236                              <1> 		; ch > 0 and ch < FFh
 19237                              <1> 	; write a character at current cursor position
 19238 00005C28 88EC                <1> 	mov	ah, ch ; color/attribute
 19239                              <1> 	; 12/07/2014
 19240 00005C2A 6651                <1> 	push	cx
 19241 00005C2C E8C7BBFFFF          <1> 	call	_write_c_current
 19242 00005C31 6659                <1> 	pop	cx
 19243                              <1> sysstty_11:
 19244                              <1> 	; 14/01/2014
 19245 00005C33 30D2                <1> 	xor	dl, dl ; sysstty call sign
 19246                              <1> 	; 18/01/2014
 19247                              <1> 	;movzx	eax, cl ; 27/06/2015
 19248 00005C35 88C8                <1> 	mov	al, cl
 19249 00005C37 E8490E0000          <1> 	call	cttyp
 19250 00005C3C E9FCF8FFFF          <1> 	jmp	sysret
 19251                              <1> 
 19252                              <1> ; Original UNIX v1 'sysstty' routine:
 19253                              <1> ; gtty:
 19254                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
 19255                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
 19256                              <1> 	; 		/ r2 has source
 19257                              <1>         ;mov    r2,-(sp)
 19258                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
 19259                              <1> ;1: / flush the clist wait till typewriter is quiescent
 19260                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
 19261                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
 19262                              <1>         ;mov    $240,*$ps / set processor priority to 5
 19263                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
 19264                              <1>         ;       br .+4 / list empty, skip branch
 19265                              <1>         ;br     1b / get another character until list is empty
 19266                              <1>         ;mov    0b,r1 / move cc offset to r1
 19267                              <1>         ;inc    r1 / bump it for output clist
 19268                              <1>         ;tstb   cc(r1) / is it 0
 19269                              <1>         ;beq    1f / yes, no characters to output
 19270                              <1>  	;mov    r1,0f / no, put offset in sleep arg
 19271                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
 19272                              <1>         ;br     1b / try to calm it down again
 19273                              <1> ;1:
 19274                              <1>         ;mov    (sp)+,r1
 19275                              <1>         ;mov    (sp)+,r2 / restore registers
 19276                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
 19277                              <1>         ;beq    1f / if 0, 1f
 19278                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
 19279                              <1>         ;                   / control status register
 19280                              <1> ;1:
 19281                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
 19282                              <1>         ;beq    1f / if 0 1f
 19283                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
 19284                              <1> 	;		    / control status reg
 19285                              <1> ;1:
 19286                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
 19287                              <1>         ;jmp     sysret2 / return to user
 19288                              <1> 
 19289                              <1> sysgtty: ; < get tty status >
 19290                              <1> 	; 23/11/2015
 19291                              <1> 	; 29/10/2015
 19292                              <1> 	; 17/10/2015
 19293                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
 19294                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 19295                              <1> 	;
 19296                              <1> 	; 'sysgtty' gets the status of tty in question. 
 19297                              <1> 	; It stores in the three words addressed by it's argument
 19298                              <1> 	; the status of the typewriter whose file descriptor
 19299                              <1> 	; in (u.r0).
 19300                              <1> 	;
 19301                              <1> 	; Calling sequence:
 19302                              <1> 	;	sysgtty; arg
 19303                              <1> 	; Arguments:
 19304                              <1> 	;	arg - address of 3 words destination of the status
 19305                              <1> 	; Inputs: ((*u.r0 - file descriptor))
 19306                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 19307                              <1> 	; ...............................................................
 19308                              <1> 	;	
 19309                              <1> 	; Retro UNIX 8086 v1 modification: 
 19310                              <1> 	;	'sysgtty' system call will return status of tty
 19311                              <1> 	;	(keyboard, serial port and video page status)
 19312                              <1> 	;	 in following manner:
 19313                              <1> 	;
 19314                              <1> 	; Inputs:
 19315                              <1> 	;	BX = 0 --> means 
 19316                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
 19317                              <1> 	;	                 for (current) process
 19318                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
 19319                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
 19320                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
 19321                              <1> 	;	     CH > 0 -->	tty number + 1
 19322                              <1> 	;
 19323                              <1> 	;	BX > 0 --> points to name of tty
 19324                              <1> 	;	     CL = 0 --> return keyboard status
 19325                              <1> 	;	     CL = 1 --> return video page status
 19326                              <1> 	;	     CH = undefined		 
 19327                              <1> 	;
 19328                              <1> 	; Outputs:
 19329                              <1> 	;	cf = 0 ->
 19330                              <1> 	;
 19331                              <1> 	;	     AL = tty number from 0 to 9
 19332                              <1> 	;		  (0 to 7 is also the video page of the tty)	
 19333                              <1> 	;	     AH = 0 if the tty is free/unused
 19334                              <1> 	;	     AH = the process number of the caller 
 19335                              <1>  	;	     AH = FFh if the tty is locked by another process
 19336                              <1> 	;
 19337                              <1> 	;	  (if calling is for serial port status)
 19338                              <1> 	;	     BX = serial port status if tty number is 8 or 9
 19339                              <1> 	;		  (BH = modem status, BL = Line status)
 19340                              <1> 	;	     CX = 0FFFFh (if data is ready)
 19341                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
 19342                              <1> 	;
 19343                              <1> 	;	  (if calling is for keyboard status)
 19344                              <1> 	;	     BX = current character in tty/keyboard buffer
 19345                              <1> 	;		  (BH = scan code, BL = ascii code)
 19346                              <1> 	;		  (BX=0 if there is not a waiting character)
 19347                              <1> 	;	     CX  is undefined
 19348                              <1> 	;
 19349                              <1> 	;	  (if calling is for video page status)	
 19350                              <1> 	;	     BX = cursor position on the video page
 19351                              <1> 	;		  if tty number < 8
 19352                              <1> 	;		  (BH = row, BL = column)
 19353                              <1> 	;	     CX = current character (in cursor position)
 19354                              <1> 	;		  on the video page of the tty 
 19355                              <1> 	;		  if tty number < 8
 19356                              <1> 	;		  (CH = color, CL = character)
 19357                              <1> 	;	
 19358                              <1> 	;	cf = 1 means error (requested tty is not ready)
 19359                              <1> 	;
 19360                              <1> 	;	     AH = FFh if the caller is not owner of
 19361                              <1> 	;		  specified tty or console tty
 19362                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 19363                              <1> 	;	     BX, CX are undefined if cf = 1
 19364                              <1> 	;
 19365                              <1> 	;	  (If tty number is 8 or 9)
 19366                              <1> 	;	     AL = tty number 
 19367                              <1> 	;	     AH = the process number of the caller 
 19368                              <1> 	;	     BX = serial port status
 19369                              <1> 	;  		 (BH = modem status, BL = Line status)
 19370                              <1> 	;	     CX = 0
 19371                              <1> 	;
 19372                              <1> 		
 19373                              <1> gtty:   ; get (requested) tty number
 19374                              <1> 	; 17/10/2015
 19375                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 19376                              <1> 	; 30/05/2013 - 12/07/2014
 19377                              <1> 	; Retro UNIX 8086 v1 modification ! 
 19378                              <1> 	;
 19379                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
 19380                              <1> 	;
 19381                              <1> 	; 28/06/2015 (32 bit modifications)
 19382                              <1> 	; 16/01/2014
 19383 00005C41 31C0                <1> 	xor 	eax, eax
 19384 00005C43 6648                <1> 	dec	ax ; 17/10/2015
 19385 00005C45 A3[58850000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
 19386 00005C4A 80F901              <1> 	cmp	cl, 1
 19387 00005C4D 760F                <1> 	jna	short sysgtty_0
 19388                              <1> sysgtty_invp:
 19389                              <1> 	; 28/06/2015
 19390 00005C4F C705[AD850000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 19391 00005C57 0000                <1>
 19392 00005C59 E9BFF8FFFF          <1> 	jmp	error
 19393                              <1> sysgtty_0:	
 19394 00005C5E 21DB                <1> 	and	ebx, ebx
 19395 00005C60 7430                <1> 	jz	short sysgtty_1
 19396                              <1> 	;
 19397 00005C62 891D[70850000]      <1> 	mov	[u.namep], ebx
 19398 00005C68 6651                <1> 	push	cx ; 23/11/2015
 19399 00005C6A E86A070000          <1> 	call	namei
 19400 00005C6F 6659                <1> 	pop	cx ; 23/11/2015
 19401 00005C71 7210                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
 19402                              <1> 	;
 19403 00005C73 6683F801            <1> 	cmp	ax, 1
 19404 00005C77 7622                <1> 	jna	short sysgtty_2
 19405 00005C79 6683E80A            <1> 	sub	ax, 10
 19406 00005C7D 6683F809            <1> 	cmp	ax, 9
 19407                              <1> 	;ja	short sysgtty_inv_dn
 19408                              <1> 	;mov	ch, al
 19409                              <1> 	;jmp	short sysgtty_4
 19410                              <1> 	; 23/11/2015
 19411 00005C81 7629                <1> 	jna	short sysgtty_4
 19412                              <1> sysgtty_inv_dn: 
 19413                              <1> 	; 28/06/2015
 19414                              <1> 	; Invalid device name (not a tty) ! error
 19415                              <1> 	; (Device is not a tty or device name not found)
 19416 00005C83 C705[AD850000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 19417 00005C8B 0000                <1>
 19418 00005C8D E98BF8FFFF          <1> 	jmp	error 
 19419                              <1> sysgtty_1:
 19420                              <1> 	; 16/01/2014
 19421 00005C92 80FD0A              <1> 	cmp	ch, 10
 19422 00005C95 77B8                <1> 	ja	short sysgtty_invp ; 28/06/2015
 19423 00005C97 FECD                <1> 	dec	ch ; 0 -> FFh (negative)
 19424 00005C99 790F                <1> 	jns	short sysgtty_3 ; not negative
 19425                              <1> 	;
 19426                              <1> sysgtty_2:
 19427                              <1> 	; get tty number of console tty
 19428 00005C9B 8A25[A7850000]      <1> 	mov	ah, [u.uno]
 19429                              <1>  	; 28/06/2015
 19430 00005CA1 0FB6DC              <1> 	movzx 	ebx, ah
 19431 00005CA4 8AAB[AB820000]      <1> 	mov	ch, [ebx+p.ttyc-1]
 19432                              <1> sysgtty_3:
 19433 00005CAA 88E8                <1> 	mov	al, ch
 19434                              <1> sysgtty_4:
 19435 00005CAC A2[58850000]        <1> 	mov	[u.r0], al
 19436                              <1>  	; 28/06/2015
 19437                              <1> 	;cmp	al, 9
 19438                              <1> 	;ja	short sysgtty_invp
 19439 00005CB1 8B2D[54850000]      <1> 	mov	ebp, [u.usp]
 19440                              <1> 	; 23/11/2015
 19441 00005CB7 20C9                <1> 	and	cl, cl
 19442 00005CB9 7436                <1> 	jz	short sysgtty_6 ; keyboard status
 19443 00005CBB 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
 19444 00005CBD 7232                <1> 	jb	short sysgtty_6 ; video page status
 19445                              <1> 	; serial port status
 19446                              <1> 	; 12/07/2014
 19447                              <1> 	;mov	dx, 0
 19448                              <1> 	;je	short sysgtty_5
 19449                              <1> 	;inc	dl
 19450                              <1> ;sysgtty_5:
 19451                              <1> 	; 28/06/2015
 19452 00005CBF 2C08                <1> 	sub	al, 8
 19453 00005CC1 E840100000          <1> 	call	sp_status ; serial (COM) port (line) status
 19454                              <1> 	; AL = Line status, AH = Modem status
 19455 00005CC6 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
 19456 00005CCA 8A25[A7850000]      <1> 	mov	ah, [u.uno]
 19457 00005CD0 8825[59850000]      <1>         mov     [u.r0+1], ah
 19458 00005CD6 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)	
 19459                              <1> 				; (in ECX)
 19460 00005CDC A880                <1> 	test	al, 80h
 19461 00005CDE 7565                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
 19462 00005CE0 A801                <1> 	test	al, 1
 19463 00005CE2 0F8455F8FFFF        <1> 	jz	sysret
 19464 00005CE8 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)	
 19465 00005CEC E94CF8FFFF          <1> 	jmp	sysret
 19466                              <1> sysgtty_6:
 19467 00005CF1 A2[AC850000]        <1> 	mov	[u.ttyn], al ; tty number
 19468                              <1> 	;movzx	ebx, al
 19469 00005CF6 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
 19470 00005CF8 D0E3                <1> 	shl 	bl, 1  ; aligned to word
 19471                              <1> 	; 22/04/2014 - 29/06/2015
 19472 00005CFA 81C3[16790000]      <1>         add     ebx, ttyl
 19473 00005D00 8A23                <1>  	mov	ah, [ebx]
 19474 00005D02 3A25[A7850000]      <1> 	cmp	ah, [u.uno]
 19475 00005D08 7404                <1> 	je	short sysgtty_7
 19476 00005D0A 20E4                <1> 	and	ah, ah
 19477                              <1> 	;jz	short sysgtty_7
 19478 00005D0C 7506                <1> 	jnz	short sysgtty_8
 19479                              <1> 	;mov	ah, 0FFh
 19480                              <1> sysgtty_7:
 19481 00005D0E 8825[59850000]      <1>         mov     [u.r0+1], ah
 19482                              <1> sysgtty_8:
 19483 00005D14 08C9                <1> 	or	cl, cl
 19484 00005D16 7510                <1> 	jnz	short sysgtty_9
 19485 00005D18 B401                <1> 	mov	ah, 1  ; test a key is available
 19486 00005D1A E83BAFFFFF          <1> 	call	int16h ; 24/01/2016
 19487 00005D1F 66894510            <1> 	mov	[ebp+16], ax ; bx, character
 19488 00005D23 E915F8FFFF          <1> 	jmp	sysret
 19489                              <1> sysgtty_9:
 19490 00005D28 8A1D[AC850000]      <1> 	mov	bl, [u.ttyn]
 19491                              <1> 	; bl = video page number
 19492 00005D2E E8BCB8FFFF          <1> 	call 	get_cpos
 19493                              <1> 	; dx = cursor position
 19494 00005D33 66895510            <1> 	mov	[ebp+16], dx ; bx
 19495                              <1> 	;mov	bl, [u.ttyn]
 19496                              <1> 	; bl = video page number
 19497 00005D37 E872BAFFFF          <1> 	call	_read_ac_current ; 24/01/2016
 19498                              <1> 	; ax = character and attribute/color
 19499 00005D3C 66894518            <1> 	mov	[ebp+24], ax ; cx
 19500 00005D40 E9F8F7FFFF          <1> 	jmp	sysret
 19501                              <1> sysgtty_dnr_err:
 19502                              <1> 	; 'device not responding !' error	
 19503                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
 19504 00005D45 C705[AD850000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ;  25				
 19505 00005D4D 0000                <1>
 19506 00005D4F E9C9F7FFFF          <1> 	jmp	error	
 19507                              <1> 
 19508                              <1> ; Original UNIX v1 'sysgtty' routine:
 19509                              <1> ; sysgtty:
 19510                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
 19511                              <1> 	;	       / r2 has destination
 19512                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
 19513                              <1> 	;                     / in 1st word of dest
 19514                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
 19515                              <1> 	;                     / in 2nd word of dest
 19516                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
 19517                              <1>         ;jmp    sysret2 / return to user
 19518                              <1> 	
 19519                              <1> ; Original UNIX v1 'gtty' routine:
 19520                              <1> ; gtty:
 19521                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
 19522                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
 19523                              <1>         ;jsr    r0,getf / get the i-number of the file
 19524                              <1>         ;tst    r1 / is it open for reading
 19525                              <1>         ;bgt    1f / yes
 19526                              <1>         ;neg    r1 / no, i-number is negative, 
 19527                              <1> 	;          / so make it positive
 19528                              <1> ;1:
 19529                              <1>         ;sub    $14.,r1 / get i-number of tty0
 19530                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
 19531                              <1>         ;bhis   error9 / no, error
 19532                              <1>         ;asl    r1 / 0%2
 19533                              <1>         ;asl    r1 / 0%4 / yes
 19534                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
 19535                              <1> 	;	       ; / tty block
 19536                              <1>         ;mov    u.off,r2 / put argument in r2
 19537                              <1>         ;rts    r0 / return
 19538                              <1> 
 19539                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u2.s
 19540                              <1> ; Last Modification: 03/01/2016
 19541                              <1> 
 19542                              <1> syslink:
 19543                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19544                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 19545                              <1> 	;
 19546                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
 19547                              <1> 	; name 1 is a file that already exists. name 2 is the name
 19548                              <1> 	; given to the entry that will go in the current directory.
 19549                              <1> 	; name2 will then be a link to the name 1 file. The i-number
 19550                              <1> 	; in the name 2 entry of current directory is the same
 19551                              <1> 	; i-number for the name 1 file.
 19552                              <1> 	;
 19553                              <1> 	; Calling sequence:
 19554                              <1> 	;	syslink; name 1; name 2
 19555                              <1> 	; Arguments:
 19556                              <1> 	;	name 1 - file name to which link will be created.
 19557                              <1> 	;	name 2 - name of entry in current directory that
 19558                              <1> 	;		 links to name 1.
 19559                              <1> 	; Inputs: -
 19560                              <1> 	; Outputs: -
 19561                              <1> 	; ...............................................................
 19562                              <1> 	;	
 19563                              <1> 	; Retro UNIX 8086 v1 modification: 
 19564                              <1> 	;       'syslink' system call has two arguments; so,
 19565                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
 19566                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
 19567                              <1> 	;
 19568                              <1> 		; / name1, name2
 19569                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
 19570 00005D54 891D[70850000]      <1> 	mov	[u.namep], ebx
 19571 00005D5A 51                  <1> 	push	ecx
 19572 00005D5B E879060000          <1> 	call	namei
 19573                              <1> 		; jsr r0,namei / find the i-number associated with
 19574                              <1> 			     ; / the 1st path name
 19575                              <1>      	;;and	ax, ax
 19576                              <1> 	;;jz	error ; File not found
 19577                              <1> 	;jc	error 
 19578                              <1> 		; br error9 / cannot be found
 19579 00005D60 730F                <1> 	jnc	short syslink0
 19580                              <1> 	;pop 	ecx
 19581                              <1> 	; 'file not found !' error
 19582 00005D62 C705[AD850000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 19583 00005D6A 0000                <1>
 19584 00005D6C E9ACF7FFFF          <1> 	jmp	error
 19585                              <1> syslink0:
 19586 00005D71 E8FF0C0000          <1> 	call	iget
 19587                              <1> 		; jsr r0,iget / get the i-node into core
 19588 00005D76 8F05[70850000]      <1> 	pop	dword [u.namep] ; ecx
 19589                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
 19590 00005D7C 6650                <1> 	push	ax
 19591                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
 19592                              <1> 			    ; / (a link to this file is to be created)
 19593 00005D7E 66FF35[3C850000]    <1> 	push	word [cdev]
 19594                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
 19595 00005D85 E855000000          <1> 	call	isdir
 19596                              <1> 		; jsr r0,isdir / is it a directory
 19597 00005D8A E84A060000          <1> 	call	namei
 19598                              <1> 		; jsr r0,namei / no, get i-number of name2
 19599                              <1> 	;jnc	error
 19600                              <1> 		; br .+4   / not found 
 19601                              <1> 			 ; / so r1 = i-number of current directory
 19602                              <1> 			 ; / ii = i-number of current directory
 19603                              <1> 		; br error9 / file already exists., error
 19604 00005D8F 720F                <1> 	jc	short syslink1
 19605                              <1> 	; pop ax
 19606                              <1> 	; pop ax
 19607                              <1> 	; 'file exists !' error
 19608 00005D91 C705[AD850000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
 19609 00005D99 0000                <1>
 19610 00005D9B E97DF7FFFF          <1> 	jmp	error
 19611                              <1> syslink1:
 19612 00005DA0 6659                <1> 	pop	cx
 19613                              <1> 	;cmp	cx, [cdev]
 19614 00005DA2 3A0D[3C850000]      <1> 	cmp	cl, [cdev]
 19615                              <1> 	;jne	error
 19616                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
 19617                              <1> 			       ; / end of current directory
 19618                              <1> 	        ; bne error9
 19619 00005DA8 740F                <1> 	je	short syslink2
 19620                              <1> 	; 'not same drive !' error
 19621 00005DAA C705[AD850000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
 19622 00005DB2 0000                <1>
 19623 00005DB4 E964F7FFFF          <1> 	jmp	error
 19624                              <1> syslink2:
 19625 00005DB9 6658                <1> 	pop	ax
 19626 00005DBB 6650                <1> 	push	ax
 19627 00005DBD 66A3[8A850000]      <1> 	mov	[u.dirbuf], ax
 19628                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
 19629 00005DC3 E8A8000000          <1> 	call	mkdir
 19630                              <1> 		; jsr r0,mkdir / make directory entry for name2 
 19631                              <1> 		 	     ; / in current directory
 19632 00005DC8 6658                <1> 	pop	ax
 19633                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
 19634 00005DCA E8A60C0000          <1> 	call	iget
 19635                              <1> 		; jsr r0,iget / get i-node into core
 19636 00005DCF FE05[2E820000]      <1> 	inc	byte [i.nlks]
 19637                              <1> 		; incb i.nlks / add 1 to its number of links
 19638 00005DD5 E8A90C0000          <1> 	call	setimod
 19639                              <1> 		; jsr r0,setimod / set the i-node modified flag
 19640 00005DDA E95EF7FFFF          <1> 	jmp	sysret
 19641                              <1> 
 19642                              <1> isdir:
 19643                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19644                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 19645                              <1> 	;
 19646                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
 19647                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
 19648                              <1> 	;  called by syslink and sysunlink to make sure directories
 19649                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
 19650                              <1> 	; 'isdir' does not bother checking. The current i-node
 19651                              <1> 	;  is not disturbed.			
 19652                              <1> 	;		
 19653                              <1> 	; INPUTS ->
 19654                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
 19655                              <1> 	;    u.uid - user id
 19656                              <1> 	; OUTPUTS ->
 19657                              <1> 	;    r1 - contains current i-number upon exit
 19658                              <1> 	;    	 (current i-node back in core) 
 19659                              <1> 	;	
 19660                              <1> 	; ((AX = R1))
 19661                              <1> 	;
 19662                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 19663                              <1> 	;
 19664                              <1> 
 19665                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
 19666                              <1> 	; / there is an error unless super user made the call
 19667                              <1> 	
 19668 00005DDF 803D[A4850000]00    <1> 	cmp	byte [u.uid], 0 
 19669                              <1> 		; tstb u.uid / super user
 19670 00005DE6 762D                <1> 	jna	short isdir1
 19671                              <1> 		; beq 1f / yes, don't care
 19672 00005DE8 66FF35[38850000]    <1> 	push	word [ii]
 19673                              <1> 		; mov ii,-(sp) / put current i-number on stack
 19674 00005DEF E8810C0000          <1> 	call	iget
 19675                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
 19676 00005DF4 66F705[2C820000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
 19677 00005DFC 40                  <1>
 19678                              <1> 		; bit $40000,i.flgs / is it a directory
 19679                              <1> 	;jnz	error
 19680                              <1> 		; bne error9 / yes, error
 19681 00005DFD 740F                <1> 	jz	short isdir0
 19682 00005DFF C705[AD850000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
 19683 00005E07 0000                <1>
 19684                              <1> 				; 'permission denied !' error
 19685                              <1> 	; pop	ax
 19686 00005E09 E90FF7FFFF          <1> 	jmp	error	
 19687                              <1> isdir0:	
 19688 00005E0E 6658                <1> 	pop	ax
 19689                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
 19690 00005E10 E8600C0000          <1> 	call	iget
 19691                              <1> 		; jsr r0,iget / get it back in
 19692                              <1> isdir1: ; 1:
 19693 00005E15 C3                  <1> 	retn
 19694                              <1> 		; rts r0
 19695                              <1> 
 19696                              <1> sysunlink:
 19697                              <1> 	; 04/12/2015 (14 byte file names)
 19698                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19699                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 19700                              <1> 	;
 19701                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
 19702                              <1> 	; name from its directory. If this entry was the last link
 19703                              <1> 	; to the file, the contents of the file are freed and the
 19704                              <1> 	; file is destroyed. If, however, the file was open in any
 19705                              <1> 	; process, the actual destruction is delayed until it is 
 19706                              <1> 	; closed, even though the directory entry has disappeared.
 19707                              <1> 	; 
 19708                              <1> 	; The error bit (e-bit) is set to indicate that the file	
 19709                              <1> 	; does not exist or that its directory can not be written.
 19710                              <1> 	; Write permission is not required on the file itself.
 19711                              <1> 	; It is also illegal to unlink a directory (except for
 19712                              <1> 	; the superuser).
 19713                              <1> 	;
 19714                              <1> 	; Calling sequence:
 19715                              <1> 	;	sysunlink; name
 19716                              <1> 	; Arguments:
 19717                              <1> 	;	name - name of directory entry to be removed 
 19718                              <1> 	; Inputs: -
 19719                              <1> 	; Outputs: -
 19720                              <1> 	; ...............................................................
 19721                              <1> 	;				
 19722                              <1> 	; Retro UNIX 8086 v1 modification:
 19723                              <1> 	;	 The user/application program puts address of the name
 19724                              <1> 	;        in BX register as 'sysunlink' system call argument.
 19725                              <1> 
 19726                              <1> 	; / name - remove link name
 19727 00005E16 891D[70850000]      <1> 	mov	[u.namep], ebx
 19728                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
 19729 00005E1C E8B8050000          <1> 	call	namei
 19730                              <1> 		; jsr r0,namei / find the i-number associated 
 19731                              <1> 			     ; / with the path name
 19732                              <1> 	;jc	error
 19733                              <1> 		; br error9 / not found
 19734 00005E21 730F                <1> 	jnc	short sysunlink1
 19735                              <1> 	; 'file not found !' error
 19736 00005E23 C705[AD850000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 19737 00005E2B 0000                <1>
 19738 00005E2D E9EBF6FFFF          <1> 	jmp	error
 19739                              <1> sysunlink1:
 19740 00005E32 6650                <1> 	push	ax
 19741                              <1> 		; mov r1,-(sp) / put its i-number on the stack
 19742 00005E34 E8A6FFFFFF          <1> 	call	isdir
 19743                              <1> 		; jsr r0,isdir / is it a directory
 19744 00005E39 6631C0              <1> 	xor 	ax, ax
 19745 00005E3C 66A3[8A850000]      <1> 	mov	[u.dirbuf], ax ; 0
 19746                              <1> 		; clr u.dirbuf / no, clear the location that will
 19747                              <1> 			   ; / get written into the i-number portion
 19748                              <1> 			 ; / of the entry
 19749 00005E42 832D[74850000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
 19750                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
 19751 00005E49 E86E000000          <1> 	call	wdir
 19752                              <1> 		; jsr r0,wdir / free the directory entry
 19753 00005E4E 6658                <1> 	pop	ax
 19754                              <1> 		; mov (sp)+,r1 / get i-number back
 19755 00005E50 E8200C0000          <1> 	call	iget
 19756                              <1> 		; jsr r0,iget / get i-node
 19757 00005E55 E8290C0000          <1> 	call	setimod
 19758                              <1> 		; jsr r0,setimod / set modified flag
 19759 00005E5A FE0D[2E820000]      <1> 	dec	byte [i.nlks]
 19760                              <1> 		; decb i.nlks / decrement the number of links
 19761 00005E60 0F85D7F6FFFF        <1> 	jnz	sysret
 19762                              <1> 		; bgt sysret9 / if this was not the last link
 19763                              <1> 			    ; / to file return
 19764                              <1> 	; AX = r1 = i-number
 19765 00005E66 E893090000          <1> 	call	anyi
 19766                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
 19767                              <1> 			 ; / Then free contents of file and destroy it.
 19768 00005E6B E9CDF6FFFF          <1> 	jmp	sysret
 19769                              <1> 		; br sysret9
 19770                              <1> 
 19771                              <1> mkdir:
 19772                              <1> 	; 04/12/2015 (14 byte directory names)
 19773                              <1> 	; 12/10/2015
 19774                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
 19775                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 19776                              <1> 	;
 19777                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
 19778                              <1> 	; by u.namep into the current directory.
 19779                              <1> 	;
 19780                              <1> 	; INPUTS ->
 19781                              <1> 	;    u.namep - points to a file name 
 19782                              <1> 	;	           that is about to be a directory entry.
 19783                              <1> 	;    ii - current directory's i-number.	
 19784                              <1> 	; OUTPUTS ->
 19785                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
 19786                              <1> 	;    u.off - points to entry to be filled 
 19787                              <1> 	;	     in the current directory		
 19788                              <1> 	;    u.base - points to start of u.dirbuf.
 19789                              <1> 	;    r1 - contains i-number of current directory 
 19790                              <1> 	;	
 19791                              <1> 	; ((AX = R1)) output
 19792                              <1> 	;
 19793                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
 19794                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 19795                              <1> 	;
 19796                              <1> 
 19797                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 19798 00005E70 31C0                <1> 	xor 	eax, eax
 19799 00005E72 BF[8C850000]        <1> 	mov     edi, u.dirbuf+2
 19800 00005E77 89FE                <1> 	mov	esi, edi
 19801 00005E79 AB                  <1> 	stosd
 19802 00005E7A AB                  <1> 	stosd
 19803                              <1> 	; 04/12/2015 (14 byte directory names)
 19804 00005E7B AB                  <1> 	stosd
 19805 00005E7C 66AB                <1> 	stosw
 19806                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
 19807 00005E7E 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
 19808                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 19809                              <1> 	;mov 	ebp, [u.namep]
 19810 00005E80 E899060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 19811                              <1> 		; esi = physical address (page start + offset)
 19812                              <1> 		; ecx = byte count in the page (1 - 4096)
 19813                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 19814                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
 19815                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
 19816                              <1> mkdir_1: ; 1: 
 19817 00005E85 45                  <1> 	inc	ebp ; 12/10/2015
 19818                              <1> 	;
 19819                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
 19820                              <1> 	 ; 01/08/2013
 19821 00005E86 AC                  <1> 	lodsb
 19822                              <1> 		; movb (r2)+,r1 / move character in name to r1
 19823 00005E87 20C0                <1> 	and 	al, al
 19824 00005E89 7427                <1> 	jz 	short mkdir_3 	  
 19825                              <1> 		; beq 1f / if null, done
 19826 00005E8B 3C2F                <1> 	cmp	al, '/'
 19827                              <1> 		; cmp r1,$'/ / is it a "/"?
 19828 00005E8D 7414                <1> 	je	short mkdir_err
 19829                              <1> 	;je	error
 19830                              <1> 		; beq error9 / yes, error
 19831                              <1> 	; 12/10/2015
 19832 00005E8F 6649                <1> 	dec	cx
 19833 00005E91 7505                <1> 	jnz	short mkdir_2
 19834                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 19835 00005E93 E88C060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 19836                              <1> 		; esi = physical address (page start + offset)
 19837                              <1> 		; ecx = byte count in the page
 19838                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 19839                              <1> mkdir_2:
 19840 00005E98 81FF[9A850000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
 19841                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
 19842                              <1> 				     ; / a char?
 19843 00005E9E 74E5                <1> 	je	short mkdir_1
 19844                              <1> 		; beq 1b / yes, go back
 19845 00005EA0 AA                  <1> 	stosb
 19846                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
 19847 00005EA1 EBE2                <1> 	jmp 	short mkdir_1
 19848                              <1> 		; br 1b / get next char
 19849                              <1> mkdir_err:
 19850                              <1> 	; 17/06/2015
 19851 00005EA3 C705[AD850000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 19852 00005EAB 0000                <1>
 19853 00005EAD E96BF6FFFF          <1> 	jmp	error
 19854                              <1> 
 19855                              <1> mkdir_3: ; 1:
 19856 00005EB2 A1[6C850000]        <1> 	mov	eax, [u.dirp]
 19857 00005EB7 A3[74850000]        <1> 	mov	[u.off], eax
 19858                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
 19859                              <1> 				 ; / slot to u.off
 19860                              <1> wdir: ; 29/04/2013
 19861 00005EBC C705[78850000]-     <1>         mov     dword [u.base], u.dirbuf
 19862 00005EC2 [8A850000]          <1>
 19863                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
 19864 00005EC6 C705[7C850000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
 19865 00005ECE 0000                <1>
 19866                              <1> 		; mov $10.,u.count / u.count = 10
 19867 00005ED0 66A1[38850000]      <1> 	mov	ax, [ii] 
 19868                              <1> 		; mov ii,r1 / r1 has i-number of current directory
 19869 00005ED6 B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
 19870 00005ED8 E8AA0B0000          <1> 	call 	access
 19871                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
 19872                              <1> 				 ; / for writing
 19873                              <1> 	; AX = i-number of current directory
 19874                              <1> 	; 01/08/2013
 19875 00005EDD FE05[BF850000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
 19876 00005EE3 E8910B0000          <1> 	call	writei
 19877                              <1> 		; jsr r0,writei / write into directory
 19878 00005EE8 C3                  <1> 	retn	
 19879                              <1> 		; rts r0
 19880                              <1> 
 19881                              <1> sysexec:
 19882                              <1> 	; 23/10/2015
 19883                              <1> 	; 19/10/2015
 19884                              <1> 	; 18/10/2015
 19885                              <1> 	; 10/10/2015
 19886                              <1> 	; 26/08/2015
 19887                              <1> 	; 05/08/2015
 19888                              <1> 	; 29/07/2015
 19889                              <1> 	; 25/07/2015
 19890                              <1> 	; 24/07/2015
 19891                              <1> 	; 21/07/2015
 19892                              <1> 	; 20/07/2015
 19893                              <1> 	; 02/07/2015
 19894                              <1> 	; 01/07/2015
 19895                              <1> 	; 25/06/2015
 19896                              <1> 	; 24/06/2015
 19897                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19898                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 19899                              <1> 	;
 19900                              <1> 	; 'sysexec' initiates execution of a file whose path name if
 19901                              <1> 	; pointed to by 'name' in the sysexec call. 
 19902                              <1> 	; 'sysexec' performs the following operations:
 19903                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
 19904                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
 19905                              <1> 	;    3. sets trap vectors to system routines.
 19906                              <1> 	;    4. loads arguments to be passed to executing file into
 19907                              <1> 	;	highest locations of user's core
 19908                              <1> 	;    5. puts pointers to arguments in locations immediately
 19909                              <1> 	;	following arguments.
 19910                              <1> 	;    6.	saves number of arguments in next location.
 19911                              <1> 	;    7. intializes user's stack area so that all registers
 19912                              <1> 	;	will be zeroed and the PS is cleared and the PC set
 19913                              <1> 	;	to core when 'sysret' restores registers 
 19914                              <1> 	;	and does an rti.
 19915                              <1> 	;    8. inializes u.r0 and u.sp
 19916                              <1> 	;    9. zeros user's core down to u.r0
 19917                              <1> 	;   10.	reads executable file from storage device into core
 19918                              <1> 	;	starting at location 'core'.
 19919                              <1> 	;   11.	sets u.break to point to end of user's code with
 19920                              <1> 	;	data area appended.
 19921                              <1> 	;   12.	calls 'sysret' which returns control at location
 19922                              <1> 	;	'core' via 'rti' instruction. 		  		
 19923                              <1> 	;
 19924                              <1> 	; Calling sequence:
 19925                              <1> 	;	sysexec; namep; argp
 19926                              <1> 	; Arguments:
 19927                              <1> 	;	namep - points to pathname of file to be executed
 19928                              <1> 	;	argp  - address of table of argument pointers
 19929                              <1> 	;	argp1... argpn - table of argument pointers
 19930                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
 19931                              <1> 	; Inputs: (arguments)
 19932                              <1> 	; Outputs: -	
 19933                              <1> 	; ...............................................................
 19934                              <1> 	;
 19935                              <1> 	; Retro UNIX 386 v1 modification: 
 19936                              <1> 	;	User application runs in it's own virtual space 
 19937                              <1> 	;	which is izolated from kernel memory (and other
 19938                              <1> 	;	memory pages) via 80386	paging in ring 3 
 19939                              <1> 	;	privilige mode. Virtual start address is always 0.
 19940                              <1> 	;	User's core memory starts at linear address 400000h
 19941                              <1> 	;	(the end of the 1st 4MB).
 19942                              <1> 	;
 19943                              <1> 	; Retro UNIX 8086 v1 modification: 
 19944                              <1> 	;	user/application segment and system/kernel segment
 19945                              <1> 	;	are different and sysenter/sysret/sysrele routines
 19946                              <1> 	;	are different (user's registers are saved to 
 19947                              <1> 	;	and then restored from system's stack.)
 19948                              <1> 	;
 19949                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 19950                              <1> 	;	      arguments which were in these registers;
 19951                              <1> 	;	      but, it returns by putting the 1st argument
 19952                              <1> 	;	      in 'u.namep' and the 2nd argument
 19953                              <1> 	;	      on top of stack. (1st argument is offset of the
 19954                              <1> 	;	      file/path name in the user's program segment.)		 	
 19955                              <1> 	
 19956                              <1> 	;call	arg2
 19957                              <1> 	; * name - 'u.namep' points to address of file/path name
 19958                              <1> 	;          in the user's program segment ('u.segmnt')
 19959                              <1> 	;          with offset in BX register (as sysopen argument 1).
 19960                              <1> 	; * argp - sysexec argument 2 is in CX register 
 19961                              <1> 	;          which is on top of stack.
 19962                              <1> 	;
 19963                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
 19964                              <1> 
 19965                              <1> 	; 23/06/2015 (32 bit modifications)
 19966                              <1> 
 19967 00005EE9 891D[70850000]      <1> 	mov	[u.namep], ebx ; argument 1
 19968                              <1>         ; 18/10/2015
 19969 00005EEF 890D[D8850000]      <1> 	mov     [argv], ecx  ; * ; argument 2
 19970 00005EF5 E8DF040000          <1> 	call	namei
 19971                              <1> 		; jsr r0,namei / namei returns i-number of file 
 19972                              <1> 			     ; / named in sysexec call in r1
 19973                              <1> 	;jc	error
 19974                              <1> 		; br error9
 19975 00005EFA 731E                <1> 	jnc	short sysexec_0
 19976                              <1> 	;
 19977                              <1> 	; 'file not found !' error
 19978 00005EFC C705[AD850000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
 19979 00005F04 0000                <1>
 19980 00005F06 E912F6FFFF          <1> 	jmp	error 
 19981                              <1> sysexec_not_exf:
 19982                              <1> 	; 'not executable file !' error
 19983 00005F0B C705[AD850000]1600- <1> 	mov	dword [u.error], ERR_NOT_EXECUTABLE
 19984 00005F13 0000                <1>
 19985 00005F15 E903F6FFFF          <1> 	jmp	error 
 19986                              <1> sysexec_0:
 19987 00005F1A E8560B0000          <1> 	call	iget
 19988                              <1> 		; jsr r0,iget / get i-node for file to be executed
 19989 00005F1F 66F705[2C820000]10- <1>         test    word [i.flgs], 10h
 19990 00005F27 00                  <1>
 19991                              <1> 		; bit $20,i.flgs / is file executable
 19992 00005F28 74E1                <1> 	jz	short sysexec_not_exf
 19993                              <1> 	;jz	error
 19994                              <1> 		; beq error9
 19995                              <1> 	;;
 19996 00005F2A E8500B0000          <1> 	call	iopen
 19997                              <1> 		; jsr r0,iopen / gets i-node for file with i-number
 19998                              <1> 			     ; / given in r1 (opens file)
 19999                              <1> 	; AX = i-number of the file
 20000 00005F2F 66F705[2C820000]20- <1> 	test	word [i.flgs], 20h
 20001 00005F37 00                  <1>
 20002                              <1> 		; bit $40,i.flgs / test user id on execution bit
 20003 00005F38 7415                <1> 	jz	short sysexec_1
 20004                              <1> 		; beq 1f
 20005 00005F3A 803D[A4850000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013
 20006                              <1> 		; tstb u.uid / test user id
 20007 00005F41 760C                <1> 	jna	short sysexec_1
 20008                              <1> 		; beq 1f / super user
 20009 00005F43 8A0D[2F820000]      <1> 	mov	cl, [i.uid]
 20010 00005F49 880D[A4850000]      <1> 	mov	[u.uid], cl ; 02/08/2013
 20011                              <1> 		; movb i.uid,u.uid / put user id of owner of file
 20012                              <1> 				 ; / as process user id
 20013                              <1> sysexec_1:
 20014                              <1> 	; 18/10/2215
 20015                              <1> 	; 10/10/2015
 20016                              <1> 	; 24/07/2015
 20017                              <1> 	; 21/07/2015
 20018                              <1> 	; 25/06/2015
 20019                              <1> 	; 24/06/2015
 20020                              <1>         ; Moving arguments to the end of [u.upage]
 20021                              <1> 	; (by regarding page borders in user's memory space)
 20022                              <1> 	;
 20023                              <1> 	; 10/10/2015
 20024                              <1> 	; 21/07/2015
 20025 00005F4F 89E5                <1> 	mov	ebp, esp ; (**)
 20026                              <1> 	; 18/10/2015
 20027 00005F51 89EF                <1> 	mov 	edi, ebp
 20028 00005F53 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
 20029                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
 20030 00005F58 29CF                <1> 	sub	edi, ecx
 20031 00005F5A 89FC                <1> 	mov	esp, edi
 20032 00005F5C 31C0                <1> 	xor	eax, eax
 20033 00005F5E A3[80850000]        <1> 	mov 	[u.nread], eax ; 0
 20034 00005F63 49                  <1> 	dec	ecx ; 256 - 1
 20035 00005F64 890D[7C850000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
 20036                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
 20037                              <1> sysexec_2:
 20038 00005F6A 8B35[D8850000]      <1> 	mov	esi, [argv] ; 18/10/2015 
 20039 00005F70 E873020000          <1> 	call	get_argp
 20040 00005F75 B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
 20041                              <1> sysexec_3:
 20042 00005F7A 21C0                <1> 	and	eax, eax
 20043 00005F7C 7456                <1> 	jz	short sysexec_6
 20044                              <1> 	; 18/10/2015
 20045 00005F7E 010D[D8850000]      <1> 	add	[argv], ecx ; 4
 20046 00005F84 66FF05[D6850000]    <1> 	inc	word [argc]
 20047                              <1> 	;
 20048 00005F8B A3[78850000]        <1> 	mov	[u.base], eax
 20049                              <1>  	; 23/10/2015
 20050 00005F90 66C705[BD850000]00- <1> 	mov	word [u.pcount], 0
 20051 00005F98 00                  <1>
 20052                              <1> sysexec_4:
 20053 00005F99 E8EA0A0000          <1> 	call	cpass ; get a character from user's core memory
 20054 00005F9E 750B                <1>         jnz      short sysexec_5
 20055                              <1> 		; (max. 255 chars + null)
 20056                              <1> 	; 18/10/2015
 20057 00005FA0 28C0                <1> 	sub 	al, al
 20058 00005FA2 AA                  <1> 	stosb
 20059 00005FA3 FF05[80850000]      <1> 	inc	dword [u.nread]
 20060 00005FA9 EB29                <1> 	jmp	short sysexec_6
 20061                              <1> sysexec_5:
 20062 00005FAB AA                  <1> 	stosb
 20063 00005FAC 20C0                <1> 	and 	al, al
 20064 00005FAE 75E9                <1> 	jnz	short sysexec_4
 20065 00005FB0 B904000000          <1> 	mov	ecx, 4
 20066 00005FB5 390D[D4850000]      <1> 	cmp	[ncount], ecx ; 4
 20067 00005FBB 72AD                <1> 	jb	short sysexec_2
 20068 00005FBD 8B35[D0850000]      <1> 	mov	esi, [nbase]
 20069 00005FC3 010D[D0850000]      <1> 	add	[nbase], ecx ; 4	
 20070 00005FC9 66290D[D4850000]    <1> 	sub	[ncount], cx 
 20071 00005FD0 8B06                <1> 	mov	eax, [esi]
 20072 00005FD2 EBA6                <1> 	jmp	short sysexec_3
 20073                              <1> sysexec_6:
 20074                              <1> 	; 18/10/2015
 20075                              <1> 	; argument list transfer from user's core memory to
 20076                              <1> 	; kernel stack frame is OK here.
 20077                              <1> 	; [u.nread] = ; argument list length
 20078                              <1> 	;mov	[argv], esp ; start address of argument list 	
 20079                              <1> 	;
 20080                              <1> 	; 18/10/2015
 20081                              <1> 	; 24/07/2015
 20082                              <1>         ; 21/07/2015
 20083                              <1> 	; 02/07/2015
 20084                              <1> 	; 25/06/2015
 20085                              <1> 	; 24/06/2015
 20086                              <1> 	; 23/06/2015
 20087                              <1> 	;
 20088 00005FD4 8B1D[B5850000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
 20089 00005FDA 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
 20090 00005FDC 740A                <1> 	jz	short sysexec_7
 20091 00005FDE A1[B1850000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
 20092 00005FE3 E8C2D2FFFF          <1> 	call	deallocate_page_dir
 20093                              <1> sysexec_7:
 20094 00005FE8 E8F2D1FFFF          <1> 	call	make_page_dir
 20095                              <1> 	;jc	short sysexec_14
 20096 00005FED 0F8204DDFFFF        <1> 	jc	panic  ; allocation error 
 20097                              <1> 		       ; after a deallocation would be nonsence !?
 20098                              <1> 	; 24/07/2015
 20099                              <1> 	; map kernel pages (1st 4MB) to PDE 0
 20100                              <1> 	;     of the user's page directory
 20101                              <1> 	;     (It is needed for interrupts!)
 20102                              <1> 	; 18/10/2015
 20103 00005FF3 8B15[C8780000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
 20104 00005FF9 8B02                <1> 	mov	eax, [edx] ; physical address of
 20105                              <1> 			   ; kernel's first page table (1st 4 MB)
 20106                              <1> 			   ; (PDE 0 of kernel's page directory)
 20107 00005FFB 8B15[B1850000]      <1> 	mov 	edx, [u.pgdir]
 20108 00006001 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
 20109                              <1> 	;
 20110                              <1> 	; 20/07/2015
 20111 00006003 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
 20112                              <1> 	; 18/10/2015
 20113 00006008 BE[C8850000]        <1> 	mov	esi, pcore ; physical start address
 20114                              <1> sysexec_8:	
 20115 0000600D B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
 20116 00006012 E8E6D1FFFF          <1> 	call	make_page_table
 20117 00006017 0F82DADCFFFF        <1> 	jc	panic
 20118                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
 20119 0000601D E8E9D1FFFF          <1> 	call	make_page ; make new page, clear and set the pte 
 20120 00006022 0F82CFDCFFFF        <1> 	jc	panic
 20121                              <1> 	;
 20122 00006028 8906                <1> 	mov	[esi], eax ; 24/06/2015
 20123                              <1> 	; ebx = virtual address (24/07/2015)
 20124 0000602A E8FFD6FFFF          <1> 	call 	add_to_swap_queue
 20125                              <1> 	; 18/10/2015
 20126 0000602F 81FE[CC850000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
 20127 00006035 740C                <1> 	je	short sysexec_9 ; yes
 20128 00006037 BE[CC850000]        <1> 	mov	esi, ecore  ; physical address of the last page 
 20129                              <1> 	; 20/07/2015
 20130 0000603C BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
 20131                              <1> 	; ebx = virtual end address + segment base address - 4K
 20132 00006041 EBCA                <1>         jmp     short sysexec_8
 20133                              <1> 
 20134                              <1> sysexec_9:
 20135                              <1> 	; 18/10/2015
 20136                              <1> 	; 26/08/2015
 20137                              <1> 	; 25/06/2015
 20138                              <1> 	; move arguments from kernel stack to [ecore]
 20139                              <1> 	; (argument list/line will be copied from kernel stack
 20140                              <1> 	; frame to the last (stack) page of user's core memory)
 20141                              <1> 	; 18/10/2015
 20142 00006043 8B3D[CC850000]      <1> 	mov	edi, [ecore]
 20143 00006049 81C700100000        <1> 	add	edi, PAGE_SIZE
 20144 0000604F 0FB705[D6850000]    <1> 	movzx	eax, word [argc]
 20145 00006056 09C0                <1> 	or	eax, eax
 20146 00006058 7509                <1> 	jnz	short sysexec_10
 20147 0000605A 89FB                <1> 	mov 	ebx, edi
 20148 0000605C 83EB04              <1> 	sub	ebx, 4 
 20149 0000605F 8903                <1> 	mov	[ebx], eax ; 0
 20150 00006061 EB40                <1> 	jmp 	short sysexec_13
 20151                              <1> sysexec_10:
 20152 00006063 8B0D[80850000]      <1> 	mov	ecx, [u.nread]
 20153                              <1> 	;mov 	esi, [argv}
 20154 00006069 89E6                <1> 	mov	esi, esp ; start address of argument list
 20155 0000606B 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
 20156 0000606D 89C2                <1> 	mov	edx, eax
 20157 0000606F FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
 20158 00006071 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
 20159 00006074 89FB                <1> 	mov	ebx, edi
 20160 00006076 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
 20161 00006079 29D3                <1> 	sub 	ebx, edx
 20162 0000607B 89FA                <1> 	mov	edx, edi
 20163 0000607D F3A4                <1> 	rep	movsb
 20164 0000607F 89D6                <1> 	mov 	esi, edx
 20165 00006081 89DF                <1> 	mov 	edi, ebx
 20166 00006083 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
 20167 00006088 2B15[CC850000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
 20168 0000608E AB                  <1> 	stosd	; eax = argument count	
 20169                              <1> sysexec_11:
 20170 0000608F 89F0                <1> 	mov	eax, esi
 20171 00006091 01D0                <1> 	add	eax, edx
 20172 00006093 AB                  <1> 	stosd  ; eax = virtual address
 20173 00006094 FE0D[D6850000]      <1> 	dec	byte [argc]
 20174 0000609A 7407                <1> 	jz	short sysexec_13
 20175                              <1> sysexec_12:
 20176 0000609C AC                  <1> 	lodsb
 20177 0000609D 20C0                <1> 	and	al, al
 20178 0000609F 75FB                <1> 	jnz	short sysexec_12
 20179 000060A1 EBEC                <1> 	jmp	short sysexec_11
 20180                              <1> 	;
 20181                              <1> 	; 1:
 20182                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
 20183                              <1> 			     ; / pointers to arguments to be passed
 20184                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
 20185                              <1> 			      ; / u.quit = 1 take quit
 20186                              <1> 		; mov $1,u.intr / u.intr determines handling of 
 20187                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
 20188                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
 20189                              <1> 			       ; / system routine
 20190                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector 
 20191                              <1> 			       ; / set to take system routine
 20192                              <1> 		; mov $sstack,sp / stack space used during swapping
 20193                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
 20194                              <1> 		; mov $ecore,r5 / r5 has end of core
 20195                              <1> 		; mov $core,r4 / r4 has start of users core
 20196                              <1> 		; mov r4,u.base / u.base has start of users core
 20197                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
 20198                              <1> 	; 1:
 20199                              <1> 		; tst (r2)+ / argument char = "nul"
 20200                              <1> 		; bne 1b
 20201                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of 
 20202                              <1> 			  ; / end of argument pointer list
 20203                              <1> 	; 1:
 20204                              <1> 	     ; / move arguments to bottom of users core
 20205                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 20206                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
 20207                              <1> 			    ; / ptr list
 20208                              <1> 		; blo 1f / branch to 1f when all arguments
 20209                              <1> 		       ; / are moved
 20210                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 20211                              <1> 	; 2:
 20212                              <1> 		; tstb (r3)+
 20213                              <1> 		; bne 2b / scan argument for \0 (nul)
 20214                              <1> 
 20215                              <1> 	; 2:
 20216                              <1> 		; movb -(r3),-(r5) / move argument char 
 20217                              <1> 				 ; / by char starting at "ecore"
 20218                              <1> 		; cmp r3,(r2) / moved all characters in 
 20219                              <1> 			    ; / this argument
 20220                              <1> 		; bhi 2b / branch 2b if not
 20221                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
 20222                              <1> 			     ; / r5 has pointer to nth arg
 20223                              <1> 		; br 1b / string
 20224                              <1> 	; 1:
 20225                              <1> 		; clrb -(r5)
 20226                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
 20227                              <1> 			; / last word of argument strings
 20228                              <1> 		; mov $core,r2
 20229                              <1> 	
 20230                              <1> 	; 1: / move argument pointers into core following 
 20231                              <1> 	      ; / argument strings
 20232                              <1> 		; cmp r2,r4
 20233                              <1> 		; bhis 1f / branch to 1f when all pointers
 20234                              <1> 			; / are moved
 20235                              <1> 		; mov (r2)+,-(r5)
 20236                              <1> 		; br 1b
 20237                              <1> 	; 1:
 20238                              <1> 		; sub $core,r4 / gives number of arguments *2
 20239                              <1> 		; asr r4 / divide r4 by 2 to calculate 
 20240                              <1> 		       ; / the number of args stored
 20241                              <1> 		; mov r4,-(r5) / save number of arguments ahead
 20242                              <1> 			     ; / of the argument pointers
 20243                              <1> sysexec_13:
 20244                              <1> 	; 19/10/2015
 20245                              <1> 	; 18/10/2015
 20246                              <1> 	; 29/07/2015
 20247                              <1> 	; 25/07/2015
 20248                              <1> 	; 24/07/2015
 20249                              <1> 	; 20/07/2015
 20250                              <1> 	; 25/06/2015
 20251                              <1> 	; 24/06/2015
 20252                              <1> 	; 23/06/2015
 20253                              <1> 	;
 20254                              <1> 	; moving arguments to [ecore] is OK here..
 20255                              <1> 	; 18/10/2015
 20256 000060A3 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
 20257                              <1> 	; ebx = beginning addres of argument list pointers
 20258                              <1> 	;	in user's stack
 20259                              <1> 	; 19/10/2015
 20260 000060A5 2B1D[CC850000]      <1> 	sub 	ebx, [ecore]
 20261 000060AB 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
 20262                              <1> 			; end of core - 4096 (last page)
 20263                              <1> 			; (virtual address)
 20264 000060B1 891D[D8850000]      <1> 	mov	[argv], ebx
 20265 000060B7 891D[84850000]      <1> 	mov	[u.break], ebx ; available user memory
 20266                              <1> 	;
 20267 000060BD 29C0                <1> 	sub	eax, eax
 20268 000060BF C705[7C850000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
 20269 000060C7 0000                <1>
 20270                              <1> 		; mov $14,u.count
 20271 000060C9 C705[68850000]-     <1> 	mov	dword [u.fofp], u.off
 20272 000060CF [74850000]          <1>
 20273                              <1> 		; mov $u.off,u.fofp
 20274 000060D3 A3[74850000]        <1> 	mov	[u.off], eax ; 0
 20275                              <1> 		; clr u.off / set offset in file to be read to zero
 20276                              <1> 	; 25/07/2015
 20277 000060D8 A3[78850000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
 20278                              <1> 	; 25/06/2015 
 20279 000060DD 66A1[38850000]      <1> 	mov	ax, [ii]
 20280                              <1> 	; AX = i-number of the executable file
 20281 000060E3 E892090000          <1> 	call	readi
 20282                              <1> 		; jsr r0,readi / read in first six words of 
 20283                              <1> 			; / user's file, starting at $core
 20284                              <1> 		; mov sp,r5 / put users stack address in r5
 20285                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
 20286                              <1> 				; / from r5 (leaves number of words
 20287                              <1> 				; / less 26 available for
 20288                              <1> 			     	; / program in user core
 20289                              <1> 		; mov r5,u.count /
 20290                              <1> 	; 25/06/2015
 20291 000060E8 8B0D[84850000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
 20292 000060EE 890D[7C850000]      <1> 	mov	[u.count], ecx ; save for overrun check
 20293                              <1> 	;
 20294 000060F4 8B0D[80850000]      <1> 	mov	ecx, [u.nread]
 20295 000060FA 890D[84850000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
 20296 00006100 80F920              <1> 	cmp	cl, 32
 20297 00006103 7540                <1>         jne     short sysexec_15
 20298                              <1> 	;:
 20299                              <1> 	; 25/06/2015
 20300                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
 20301                              <1> 	; 18/10/2015
 20302 00006105 8B35[C8850000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
 20303                              <1> 		             ; (phys. start addr. of the exec. file)
 20304 0000610B AD                  <1> 	lodsd
 20305 0000610C 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
 20306 00006110 7533                <1> 	jne	short sysexec_15
 20307                              <1> 		; cmp core,$405 / br .+14 is first instruction 
 20308                              <1> 			      ; / if file is standard a.out format
 20309                              <1> 		; bne 1f / branch, if not standard format
 20310 00006112 AD                  <1> 	lodsd
 20311 00006113 89C1                <1> 	mov	ecx, eax ; text (code) section size
 20312 00006115 AD                  <1> 	lodsd
 20313 00006116 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
 20314                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
 20315                              <1> 		              ; / number of bytes in program text	
 20316                              <1> 		; sub $14,r5 / subtract 12
 20317 00006118 89CB                <1> 	mov	ebx, ecx
 20318                              <1> 	;
 20319                              <1> 	; 25/06/2015
 20320                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
 20321                              <1> 	;	and SINGLIX operating systems (as code template).
 20322                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
 20323                              <1> 	;	due to RUFS (floppy disk file system) restriction...
 20324                              <1> 	;	Overrun is not possible for current version. 	
 20325                              <1> 	;
 20326 0000611A AD                  <1> 	lodsd	
 20327 0000611B 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
 20328 0000611D 3B1D[7C850000]      <1> 	cmp	ebx, [u.count]
 20329 00006123 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
 20330                              <1> 	;
 20331                              <1> 	; 24/07/2015
 20332                              <1> 	; add bss section size to [u.break]
 20333 00006125 0105[84850000]      <1> 	add 	[u.break], eax
 20334                              <1> 	;
 20335 0000612B 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
 20336                              <1> 	;cmp	ecx, [u.count]
 20337                              <1> 	;jnb	short sysexec_16
 20338                              <1> 		; cmp r5,u.count /
 20339                              <1> 		; bgt 1f / branch if r5 greater than u.count
 20340 0000612E 890D[7C850000]      <1> 	mov	[u.count], ecx ; required read count
 20341                              <1> 		; mov r5,u.count
 20342                              <1> 	;
 20343 00006134 EB2A                <1> 	jmp	short sysexec_16
 20344                              <1> 	;
 20345                              <1> sysexec_14:
 20346                              <1> 	; 23/06/2015
 20347                              <1> 	; insufficient (out of) memory
 20348 00006136 C705[AD850000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
 20349 0000613E 0000                <1>
 20350 00006140 E9D8F3FFFF          <1> 	jmp	error
 20351                              <1> 	;
 20352                              <1> sysexec_15:
 20353                              <1> 	; 25/06/2015
 20354 00006145 0FB715[30820000]    <1>         movzx   edx, word [i.size] ; file size
 20355 0000614C 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
 20356 0000614E 7627                <1> 	jna	short sysexec_17 ; no need to next read
 20357 00006150 01D1                <1> 	add	ecx, edx ; [i.size]
 20358 00006152 3B0D[7C850000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
 20359 00006158 77DC                <1> 	ja	short sysexec_14
 20360 0000615A 8915[7C850000]      <1> 	mov	[u.count], edx
 20361                              <1> sysexec_16:
 20362 00006160 66A1[38850000]      <1> 	mov	ax, [ii] ; i-number
 20363 00006166 E80F090000          <1> 	call	readi
 20364                              <1> 		; add core+10,u.nread / add size of user data area 
 20365                              <1> 		                    ; / to u.nread
 20366                              <1> 		; br 2f
 20367                              <1> 	; 1:
 20368                              <1> 		; jsr r0,readi / read in rest of file
 20369                              <1> 	; 2:
 20370 0000616B 8B0D[80850000]      <1> 	mov	ecx, [u.nread]
 20371 00006171 010D[84850000]      <1> 	add	[u.break], ecx
 20372                              <1> 		; mov u.nread,u.break / set users program break to end of 
 20373                              <1> 				    ; / user code
 20374                              <1> 		; add $core+14,u.break / plus data area
 20375                              <1> sysexec_17: ; 20/07/2015
 20376                              <1> 	;mov	ax, [ii] ;rgc i-number
 20377 00006177 E804090000          <1> 	call	iclose
 20378                              <1> 		; jsr r0,iclose / does nothing
 20379 0000617C 31C0                <1>         xor     eax, eax
 20380 0000617E FEC0                <1> 	inc	al
 20381 00006180 66A3[9C850000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
 20382 00006186 66A3[9E850000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
 20383                              <1> 	; 02/07/2015
 20384 0000618C 833D[B5850000]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller sys_init (kernel) ?
 20385 00006193 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
 20386                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
 20387 00006195 8B15[C8780000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
 20388 0000619B 8915[B5850000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here 
 20389                              <1> sysexec_18:
 20390                              <1> 	; 18/10/2015
 20391                              <1> 	; 05/08/2015
 20392                              <1> 	; 29/07/2015
 20393 000061A1 8B2D[D8850000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
 20394                              <1> 			    ; list pointers (argument count)
 20395 000061A7 FA                  <1> 	cli
 20396 000061A8 8B25[64780000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
 20397                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
 20398                              <1> 			    ; for this process	 
 20399                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
 20400                              <1> 	;xor	eax, eax ; 0
 20401 000061AE FEC8                <1> 	dec	al ; eax = 0
 20402 000061B0 66BA2300            <1> 	mov	dx, UDATA
 20403 000061B4 6652                <1> 	push	dx  ; user's stack segment
 20404 000061B6 55                  <1> 	push	ebp ; user's stack pointer
 20405                              <1> 		    ; (points to number of arguments)
 20406 000061B7 FB                  <1> 	sti
 20407 000061B8 9C                  <1> 	pushfd	; EFLAGS
 20408                              <1> 		; Set IF for enabling interrupts in user mode	
 20409                              <1> 	;or	dword [esp], 200h 
 20410                              <1> 	;
 20411                              <1> 	;mov	bx, UCODE
 20412                              <1> 	;push	bx ; user's code segment
 20413 000061B9 6A1B                <1> 	push	UCODE
 20414                              <1> 	;push	0
 20415 000061BB 50                  <1> 	push	eax ; EIP (=0) - start address -	
 20416                              <1> 		; clr -(r5) / popped into ps when rti in 
 20417                              <1> 			  ; / sysrele is executed
 20418                              <1> 		; mov $core,-(r5) / popped into pc when rti 
 20419                              <1> 		                ; / in sysrele is executed
 20420                              <1> 		;mov r5,0f / load second copyz argument
 20421                              <1> 		;tst -(r5) / decrement r5
 20422 000061BC 8925[50850000]      <1> 	mov	[u.sp], esp ; 29/07/2015
 20423                              <1> 	; 05/08/2015
 20424                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
 20425                              <1> 	; ('push dx' would cause to general protection fault, 
 20426                              <1> 	; after 'pop ds' etc.)
 20427                              <1> 	;
 20428                              <1> 	;; push dx ; ds (UDATA)
 20429                              <1> 	;; push dx ; es (UDATA)
 20430                              <1> 	;; push dx ; fs (UDATA)
 20431                              <1> 	;; push dx ; gs (UDATA)
 20432                              <1> 	;
 20433                              <1> 	; This is a trick to prevent general protection fault
 20434                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
 20435 000061C2 8EC2                <1> 	mov 	es, dx ; UDATA
 20436 000061C4 06                  <1> 	push 	es ; ds (UDATA)
 20437 000061C5 06                  <1> 	push 	es ; es (UDATA)
 20438 000061C6 06                  <1> 	push 	es ; fs (UDATA)
 20439 000061C7 06                  <1> 	push	es ; gs (UDATA)
 20440 000061C8 66BA1000            <1> 	mov	dx, KDATA
 20441 000061CC 8EC2                <1> 	mov	es, dx
 20442                              <1> 	;
 20443                              <1> 	;; pushad simulation
 20444 000061CE 89E5                <1> 	mov	ebp, esp ; esp before pushad
 20445 000061D0 50                  <1> 	push	eax ; eax (0)
 20446 000061D1 50                  <1> 	push	eax ; ecx (0)
 20447 000061D2 50                  <1> 	push	eax ; edx (0)
 20448 000061D3 50                  <1> 	push	eax ; ebx (0)
 20449 000061D4 55                  <1> 	push	ebp ; esp before pushad
 20450 000061D5 50                  <1> 	push	eax ; ebp (0)
 20451 000061D6 50                  <1> 	push	eax ; esi (0)		
 20452 000061D7 50                  <1> 	push	eax ; edi (0)	
 20453                              <1> 	;
 20454 000061D8 A3[58850000]        <1> 	mov	[u.r0], eax ; eax = 0
 20455 000061DD 8925[54850000]      <1> 	mov	[u.usp], esp
 20456                              <1> 		; mov r5,u.r0 /
 20457                              <1> 		; sub $16.,r5 / skip 8 words
 20458                              <1> 		; mov r5,u.sp / assign user stack pointer value, 
 20459                              <1> 		;             / effectively zeroes all regs
 20460                              <1> 			    ; / when sysrele is executed
 20461                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
 20462                              <1> 		; clr u.break
 20463                              <1> 		; mov r5,sp / point sp to user's stack
 20464                              <1> 	;
 20465 000061E3 E958F3FFFF          <1> 	jmp	sysret0
 20466                              <1> 	;jmp	sysret
 20467                              <1> 		; br sysret3 / return to core image at $core
 20468                              <1> 
 20469                              <1> get_argp:
 20470                              <1> 	; 18/10/2015 (nbase, ncount)
 20471                              <1> 	; 21/07/2015
 20472                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
 20473                              <1> 	; Get (virtual) address of argument from user's core memory
 20474                              <1> 	;
 20475                              <1> 	; INPUT:
 20476                              <1> 	;	esi = virtual address of argument pointer
 20477                              <1> 	; OUTPUT:
 20478                              <1> 	;	eax = virtual address of argument
 20479                              <1> 	;
 20480                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
 20481                              <1> 	;
 20482 000061E8 833D[B5850000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
 20483                              <1> 				    ; (the caller is kernel)
 20484 000061EF 7667                <1>         jna     short get_argpk 
 20485                              <1> 	;
 20486 000061F1 89F3                <1>      	mov	ebx, esi
 20487 000061F3 E80CD6FFFF          <1> 	call	get_physical_addr ; get physical address
 20488 000061F8 0F8289000000        <1>         jc      get_argp_err
 20489 000061FE A3[D0850000]        <1> 	mov 	[nbase], eax ; physical address	
 20490 00006203 66890D[D4850000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
 20491 0000620A B804000000          <1> 	mov	eax, 4 ; 21/07/2015
 20492 0000620F 6639C1              <1> 	cmp	cx, ax ; 4
 20493 00006212 735D                <1> 	jnb	short get_argp2
 20494 00006214 89F3                <1> 	mov	ebx, esi
 20495 00006216 01CB                <1> 	add	ebx, ecx
 20496 00006218 E8E7D5FFFF          <1> 	call	get_physical_addr ; get physical address
 20497 0000621D 7268                <1> 	jc	short get_argp_err
 20498                              <1> 	;push	esi
 20499 0000621F 89C6                <1> 	mov	esi, eax
 20500 00006221 66870D[D4850000]    <1> 	xchg	cx, [ncount]
 20501 00006228 8735[D0850000]      <1> 	xchg	esi, [nbase]
 20502 0000622E B504                <1> 	mov	ch, 4
 20503 00006230 28CD                <1> 	sub	ch, cl
 20504                              <1> get_argp0:
 20505 00006232 AC                  <1> 	lodsb
 20506 00006233 6650                <1> 	push	ax
 20507 00006235 FEC9                <1> 	dec	cl
 20508 00006237 75F9                <1>         jnz     short get_argp0
 20509 00006239 8B35[D0850000]      <1> 	mov	esi, [nbase]
 20510                              <1> 	; 21/07/2015
 20511 0000623F 0FB6C5              <1> 	movzx	eax, ch
 20512 00006242 0105[D0850000]      <1> 	add	[nbase], eax
 20513 00006248 662905[D4850000]    <1> 	sub	[ncount], ax
 20514                              <1> get_argp1:
 20515 0000624F AC                  <1> 	lodsb
 20516 00006250 FECD                <1> 	dec	ch
 20517 00006252 743D                <1>         jz      short get_argp3
 20518 00006254 6650                <1>         push	ax
 20519 00006256 EBF7                <1> 	jmp     short get_argp1
 20520                              <1> get_argpk:
 20521                              <1> 	; Argument is in kernel's memory space
 20522 00006258 66C705[D4850000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
 20523 00006260 10                  <1>
 20524 00006261 8935[D0850000]      <1> 	mov	[nbase], esi
 20525 00006267 8305[D0850000]04    <1> 	add	dword [nbase], 4
 20526 0000626E 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
 20527 00006270 C3                  <1> 	retn
 20528                              <1> get_argp2:
 20529                              <1> 	; 21/07/2015
 20530                              <1> 	;mov	eax, 4
 20531 00006271 8B15[D0850000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
 20532 00006277 0105[D0850000]      <1> 	add	[nbase], eax
 20533 0000627D 662905[D4850000]    <1> 	sub	[ncount], ax
 20534                              <1> 	;
 20535 00006284 8B02                <1> 	mov	eax, [edx]
 20536 00006286 C3                  <1> 	retn
 20537                              <1> get_argp_err:
 20538 00006287 A3[AD850000]        <1> 	mov	[u.error], eax
 20539 0000628C E98CF2FFFF          <1> 	jmp	error
 20540                              <1> get_argp3:
 20541 00006291 B103                <1> 	mov	cl, 3
 20542                              <1> get_argp4:
 20543 00006293 C1E008              <1> 	shl	eax, 8
 20544 00006296 665A                <1> 	pop	dx
 20545 00006298 88D0                <1> 	mov 	al, dl
 20546 0000629A E2F7                <1>         loop    get_argp4
 20547                              <1> 	;pop	esi
 20548 0000629C C3                  <1> 	retn	
 20549                              <1> 
 20550                              <1> sysfstat: 
 20551                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20552                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 20553                              <1> 	;
 20554                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
 20555                              <1> 	; on open files instead of files given by name. It puts the
 20556                              <1> 	; buffer address on the stack, gets the i-number and
 20557                              <1> 	; checks to see if the file is open for reading or writing.
 20558                              <1> 	; If the file is open for writing (i-number is negative)
 20559                              <1> 	; the i-number is set positive and a branch into 'sysstat'
 20560                              <1> 	; is made.	
 20561                              <1> 	;
 20562                              <1> 	; Calling sequence:
 20563                              <1> 	;	sysfstat; buf
 20564                              <1> 	; Arguments:
 20565                              <1> 	;	buf - buffer address
 20566                              <1> 	;
 20567                              <1> 	; Inputs: *u.r0 - file descriptor
 20568                              <1> 	; Outputs: buffer is loaded with file information
 20569                              <1> 	; ...............................................................
 20570                              <1> 	;				
 20571                              <1> 	; Retro UNIX 8086 v1 modification:
 20572                              <1> 	;       'sysfstat' system call has two arguments; so,
 20573                              <1> 	;	* 1st argument, file descriptor is in BX register
 20574                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 20575                              <1> 
 20576                              <1> 	; / set status of open file
 20577                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
 20578 0000629D 51                  <1> 	push	ecx
 20579                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
 20580                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
 20581                              <1> 		; jsr r0,getf / get the files i-number
 20582                              <1> 	; BX = file descriptor (file number)
 20583 0000629E E8FF000000          <1> 	call	getf1
 20584 000062A3 6621C0              <1> 	and	ax, ax ; i-number of the file
 20585                              <1> 		; tst	r1 / is it 0?
 20586                              <1> 	;jz	error
 20587                              <1> 		; beq error3 / yes, error
 20588 000062A6 750F                <1> 	jnz	short sysfstat1
 20589 000062A8 C705[AD850000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 20590 000062B0 0000                <1>
 20591 000062B2 E966F2FFFF          <1> 	jmp	error
 20592                              <1> sysfstat1:
 20593 000062B7 80FC80              <1> 	cmp	ah, 80h
 20594 000062BA 7223                <1>         jb      short sysstat1
 20595                              <1> 		; bgt 1f / if i-number is negative (open for writing)
 20596 000062BC 66F7D8              <1> 	neg	ax
 20597                              <1> 		; neg r1 / make it positive, then branch
 20598 000062BF EB1E                <1> 	jmp	short sysstat1
 20599                              <1> 		; br 1f / to 1f
 20600                              <1> sysstat:
 20601                              <1> 	; 18/10/2015
 20602                              <1> 	; 07/10/2015
 20603                              <1> 	; 02/09/2015
 20604                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20605                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 20606                              <1> 	;
 20607                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
 20608                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
 20609                              <1> 	; long and information about the file placed in it.	
 20610                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
 20611                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
 20612                              <1> 	; is then loaded and the results are given in the UNIX
 20613                              <1> 	; Programmers Manual sysstat (II).	
 20614                              <1> 	;
 20615                              <1> 	; Calling sequence:
 20616                              <1> 	;	sysstat; name; buf
 20617                              <1> 	; Arguments:
 20618                              <1> 	;	name - points to the name of the file
 20619                              <1> 	;	buf - address of a 34 bytes buffer
 20620                              <1> 	; Inputs: -
 20621                              <1> 	; Outputs: buffer is loaded with file information
 20622                              <1> 	; ...............................................................
 20623                              <1> 	;				
 20624                              <1> 	; Retro UNIX 8086 v1 modification: 
 20625                              <1> 	;       'sysstat' system call has two arguments; so,
 20626                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 20627                              <1> 	;	to get sysstat system call arguments from the user;
 20628                              <1> 	;	* 1st argument, name is pointed to by BX register
 20629                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 20630                              <1> 	;
 20631                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 20632                              <1> 	;	      arguments which were in these registers;
 20633                              <1> 	;	      but, it returns by putting the 1st argument
 20634                              <1> 	;	      in 'u.namep' and the 2nd argument
 20635                              <1> 	;	      on top of stack. (1st argument is offset of the
 20636                              <1> 	;	      file/path name in the user's program segment.)		 	
 20637                              <1> 	
 20638                              <1> 	; / ; name of file; buffer - get files status
 20639                              <1> 		; jsr r0,arg2 / get the 2 arguments
 20640 000062C1 891D[70850000]      <1> 	mov	[u.namep], ebx
 20641 000062C7 51                  <1> 	push	ecx
 20642 000062C8 E80C010000          <1> 	call	namei
 20643                              <1> 		; jsr r0,namei / get the i-number for the file
 20644                              <1> 	;jc	error
 20645                              <1> 		; br error3 / no such file, error
 20646 000062CD 7310                <1> 	jnc	short sysstat1
 20647                              <1> 	; pop 	ecx
 20648                              <1> sysstat_err0:
 20649                              <1> 	; 'file not found !' error
 20650 000062CF C705[AD850000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 20651 000062D7 0000                <1>
 20652 000062D9 E93FF2FFFF          <1> 	jmp	error
 20653                              <1> 
 20654 000062DE 00                  <1> statx: db 0
 20655                              <1> 
 20656                              <1> sysstat1: ; 1:
 20657 000062DF E891070000          <1> 	call	iget
 20658                              <1> 		; jsr r0,iget / get the i-node into core
 20659                              <1> 	; 07/10/2015 (ax = [ii], inode number)
 20660                              <1> 	; 02/09/2015
 20661 000062E4 8F05[78850000]      <1> 	pop	dword [u.base]
 20662                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
 20663 000062EA E858000000          <1> 	call	sysstat_gpa ; get physical address
 20664 000062EF 730A                <1> 	jnc 	short sysstat2
 20665                              <1> sysstat_err1:
 20666 000062F1 A3[AD850000]        <1> 	mov	dword [u.error], eax ; error code
 20667 000062F6 E922F2FFFF          <1> 	jmp	error
 20668                              <1> sysstat2:
 20669 000062FB A0[38850000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
 20670 00006300 AA                  <1> 	stosb
 20671 00006301 FF05[78850000]      <1> 	inc 	dword [u.base]
 20672 00006307 6649                <1> 	dec 	cx
 20673 00006309 7505                <1> 	jnz	short sysstat3
 20674 0000630B E837000000          <1> 	call	sysstat_gpa
 20675                              <1> 	;jc	short sysstat_err1
 20676                              <1> sysstat3:
 20677 00006310 A0[39850000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
 20678 00006315 AA                  <1> 	stosb
 20679                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
 20680 00006316 FF05[78850000]      <1> 	inc 	dword [u.base]
 20681                              <1> 	;dec 	word [u.pcount]
 20682 0000631C 6649                <1> 	dec	cx
 20683 0000631E 7505                <1> 	jnz	short sysstat4
 20684 00006320 E822000000          <1> 	call	sysstat_gpa
 20685                              <1> 	;jc	short sysstat_err1	
 20686                              <1> sysstat4:
 20687 00006325 BE[2C820000]        <1> 	mov	esi, inode
 20688                              <1> 		; mov $inode,r2 / r2 points to i-node
 20689                              <1> sysstat5: ; 1:
 20690 0000632A A4                  <1> 	movsb
 20691                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
 20692 0000632B FF05[78850000]      <1> 	inc 	dword [u.base]
 20693                              <1> 	;dec 	word [u.pcount]
 20694 00006331 6649                <1> 	dec	cx
 20695 00006333 7505                <1> 	jnz	short sysstat6
 20696 00006335 E80D000000          <1> 	call	sysstat_gpa
 20697                              <1> 	;jc	short sysstat_err1
 20698                              <1> sysstat6:		
 20699 0000633A 81FE[4C820000]      <1> 	cmp	esi, inode + 32
 20700                              <1> 		; cmp r2,$inode+32 / done?
 20701 00006340 75E8                <1> 	jne	short sysstat5
 20702                              <1> 		; bne 1b / no, go back
 20703 00006342 E9F6F1FFFF          <1> 	jmp	sysret
 20704                              <1> 		; br sysret3 / return through sysret
 20705                              <1> 	;
 20706                              <1> sysstat_gpa: ; get physical address of file status buffer
 20707                              <1> 	; 02/09/2015
 20708 00006347 8B1D[78850000]      <1> 	mov 	ebx, [u.base]
 20709                              <1> 	; 07/10/2015
 20710 0000634D E8B2D4FFFF          <1> 	call	get_physical_addr ; get physical address
 20711                              <1> 	;jc	short sysstat_gpa1
 20712 00006352 729D                <1> 	jc	short sysstat_err1
 20713                              <1> 	; 18/10/2015
 20714 00006354 89C7                <1> 	mov	edi, eax ; physical address
 20715                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
 20716                              <1> ;sysstat_gpa1:
 20717 00006356 C3                  <1> 	retn
 20718                              <1> 
 20719                              <1> fclose:
 20720                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
 20721                              <1> 	;            (32 bit offset pointer modification)
 20722                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
 20723                              <1> 	;
 20724                              <1> 	; Given the file descriptor (index to the u.fp list)
 20725                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
 20726                              <1> 	; If i-node is active (i-number > 0) the entry in 
 20727                              <1> 	; u.fp list is cleared. If all the processes that opened
 20728                              <1> 	; that file close it, then fsp etry is freed and the file
 20729                              <1> 	; is closed. If not a return is taken. 
 20730                              <1> 	; If the file has been deleted while open, 'anyi' is called
 20731                              <1> 	; to see anyone else has it open, i.e., see if it is appears
 20732                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
 20733                              <1> 	; a check is made to see if the file is special.	
 20734                              <1> 	;
 20735                              <1> 	; INPUTS ->
 20736                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
 20737                              <1> 	;    u.fp - list of entries in the fsp table
 20738                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
 20739                              <1> 	; OUTPUTS ->
 20740                              <1> 	;    r1 - contains the same file descriptor
 20741                              <1> 	;    r2 - contains i-number
 20742                              <1> 	;
 20743                              <1> 	; ((AX = R1))
 20744                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
 20745                              <1> 	;
 20746                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
 20747                              <1> 	;              if i-number of the file is 0. (error)  	
 20748                              <1> 	;
 20749 00006357 0FB7D0              <1> 	movzx	edx, ax ; **
 20750 0000635A 6650                <1> 	push	ax ; ***
 20751                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
 20752                              <1> 			     ; / the index to u.fp list)
 20753 0000635C E83F000000          <1> 	call	getf
 20754                              <1> 		; jsr r0,getf / r1 contains i-number, 
 20755                              <1> 			    ; / cdev has device =, u.fofp 
 20756                              <1> 			    ; / points to 3rd word of fsp entry
 20757 00006361 6683F801            <1> 	cmp	ax, 1 ; r1
 20758                              <1> 		; tst r1 / is i-number 0?
 20759 00006365 7236                <1> 	jb	short fclose_2
 20760                              <1> 		; beq 1f / yes, i-node not active so return
 20761                              <1> 		; tst (r0)+ / no, jump over error return
 20762 00006367 89D3                <1> 	mov	ebx, edx ; **
 20763 00006369 6689C2              <1> 	mov 	dx, ax ; *
 20764                              <1> 		; mov r1,r2 / move i-number to r2 ;*
 20765                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
 20766                              <1> 			    ; / which is index to u.fp ; **
 20767 0000636C C683[5E850000]00    <1> 	mov	byte [ebx+u.fp], 0
 20768                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
 20769 00006373 8B1D[68850000]      <1> 	mov	ebx, [u.fofp]
 20770                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
 20771                              <1> fclose_0:
 20772 00006379 FE4B04              <1> 	dec	byte [ebx+4] ; 18/06/2015
 20773                              <1> 		; decb 2(r1) / decrement the number of processes 
 20774                              <1> 			   ; / that have opened the file
 20775 0000637C 791F                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
 20776                              <1> 		; bge 1f / if all processes haven't closed the file, return
 20777                              <1> 	;
 20778 0000637E 6652                <1> 	push	dx ;*
 20779                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
 20780 00006380 6631C0              <1> 	xor	ax, ax ; 0
 20781 00006383 668943FC            <1> 	mov	[ebx-4], ax ; 0
 20782                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
 20783 00006387 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
 20784                              <1> 		; tstb	3(r1) / has this file been deleted
 20785 0000638A 20C0                <1> 	and	al, al
 20786 0000638C 7408                <1> 	jz	short fclose_1
 20787                              <1> 		; beq 2f / no, branch
 20788 0000638E 6689D0              <1> 	mov	ax, dx ; *
 20789                              <1> 		; mov r2,r1 / yes, put i-number back into r1
 20790                              <1> 	; AX = inode number
 20791 00006391 E868040000          <1> 	call	anyi
 20792                              <1> 		; jsr r0,anyi / free all blocks related to i-number
 20793                              <1> 			    ; / check if file appears in fsp again
 20794                              <1> fclose_1: ; 2:
 20795 00006396 6658                <1> 	pop	ax ; *
 20796                              <1> 		; mov (sp)+,r1 / put i-number back into r1
 20797 00006398 E8E3060000          <1> 	call	iclose ; close if it is special file 
 20798                              <1> 		; jsr r0,iclose / check to see if its a special file
 20799                              <1> fclose_2: ; 1:
 20800 0000639D 6658                <1> 	pop	ax ; ***
 20801                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
 20802 0000639F C3                  <1> 	retn
 20803                              <1> 		; rts r0
 20804                              <1> 
 20805                              <1> getf:	; / get the device number and the i-number of an open file
 20806                              <1> 	; 13/05/2015
 20807                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 20808                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 20809                              <1> 	;
 20810 000063A0 89C3                <1> 	mov	ebx, eax
 20811                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
 20812 000063A2 83FB0A              <1> 	cmp	ebx, 10
 20813                              <1> 		; cmp r1,$10. / user limited to 10 open files
 20814 000063A5 730A                <1>         jnb	short getf2 ; 13/05/2015
 20815                              <1> 	;jnb     error
 20816                              <1> 		; bhis error3 / u.fp is table of users open files, 
 20817                              <1> 			    ; / index in fsp table
 20818 000063A7 8A9B[5E850000]      <1> 	mov	bl, [ebx+u.fp]
 20819                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
 20820                              <1> 		                  ; / in fsp table
 20821 000063AD 08DB                <1> 	or	bl, bl
 20822 000063AF 7503                <1> 	jnz	short getf3
 20823                              <1> 	;jz	short getf4
 20824                              <1> 		; beq 1f / if its zero return
 20825                              <1> getf2:
 20826                              <1> 	; 'File not open !' error (ax=0)
 20827 000063B1 29C0                <1> 	sub	eax, eax
 20828 000063B3 C3                  <1> 	retn
 20829                              <1> getf3:	
 20830                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
 20831                              <1> 	;
 20832                              <1> 	; 'fsp' table (10 bytes/entry)
 20833                              <1> 	; bit 15				   bit 0
 20834                              <1> 	; ---|-------------------------------------------
 20835                              <1> 	; r/w|		i-number of open file
 20836                              <1> 	; ---|-------------------------------------------
 20837                              <1> 	;		   device number
 20838                              <1> 	; -----------------------------------------------
 20839                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 20840                              <1> 	; -----------------------------------------------
 20841                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 20842                              <1> 	; ----------------------|------------------------
 20843                              <1> 	;  flag that says file 	| number of processes
 20844                              <1> 	;   has been deleted	| that have file open 
 20845                              <1> 	; ----------------------|------------------------
 20846                              <1> 	;
 20847 000063B4 B80A000000          <1> 	mov	eax, 10
 20848 000063B9 F6E3                <1> 	mul	bl
 20849 000063BB BB[26830000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
 20850 000063C0 01C3                <1> 	add	ebx, eax
 20851                              <1> 		; asl r1
 20852                              <1> 		; asl r1 / multiply by 8 to get index into 
 20853                              <1> 		       ; / fsp table entry
 20854                              <1> 		; asl r1
 20855                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
 20856                              <1> 			      ; / in the fsp entry
 20857 000063C2 891D[68850000]      <1> 	mov	[u.fofp], ebx
 20858                              <1> 		; mov r1,u.fofp / save address of 3rd word 
 20859                              <1> 			      ; / in fsp entry in u.fofp
 20860 000063C8 4B                  <1> 	dec	ebx
 20861 000063C9 4B                  <1> 	dec	ebx
 20862 000063CA 668B03              <1> 	mov	ax, [ebx]
 20863                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
 20864 000063CD 66A3[3C850000]      <1> 	mov	[cdev], ax ; ;;in fact (!) 
 20865                              <1> 			     ;;dev number is in 1 byte
 20866                              <1> 		; mov -(r1),cdev / remove the device number  cdev
 20867 000063D3 4B                  <1> 	dec	ebx
 20868 000063D4 4B                  <1> 	dec	ebx
 20869 000063D5 668B03              <1> 	mov	ax, [ebx]
 20870                              <1> 		; mov -(r1),r1 / and the i-number  r1
 20871                              <1> getf4:	; 1:
 20872 000063D8 C3                  <1> 	retn
 20873                              <1> 		; rts r0
 20874                              <1> 
 20875                              <1> namei:
 20876                              <1> 	; 04/12/2015 (14 byte file names)
 20877                              <1> 	; 18/10/2015 (nbase, ncount)
 20878                              <1> 	; 12/10/2015
 20879                              <1> 	; 21/08/2015
 20880                              <1> 	; 18/07/2015
 20881                              <1> 	; 02/07/2015
 20882                              <1> 	; 17/06/2015
 20883                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
 20884                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 20885                              <1> 	;
 20886                              <1> 	; 'namei' takes a file path name and returns i-number of
 20887                              <1> 	; the file in the current directory or the root directory
 20888                              <1> 	; (if the first character of the pathname is '/').	
 20889                              <1> 	;
 20890                              <1> 	; INPUTS ->
 20891                              <1> 	;    u.namep - points to a file path name
 20892                              <1> 	;    u.cdir - i-number of users directory
 20893                              <1> 	;    u.cdev - device number on which user directory resides	
 20894                              <1> 	; OUTPUTS ->
 20895                              <1> 	;    r1 - i-number of file
 20896                              <1> 	;    cdev
 20897                              <1> 	;    u.dirbuf - points to directory entry where a match 
 20898                              <1> 	;               occurs in the search for file path name.
 20899                              <1> 	;	        If no match u.dirb points to the end of 
 20900                              <1> 	;               the directory and r1 = i-number of the current
 20901                              <1> 	;	        directory.	
 20902                              <1> 	; ((AX = R1))
 20903                              <1> 	;
 20904                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
 20905                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 20906                              <1> 	;
 20907                              <1> 
 20908 000063D9 66A1[5C850000]      <1> 	mov	ax, [u.cdir]
 20909                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
 20910                              <1> 			      ; / in r1
 20911 000063DF 668B15[A2850000]    <1> 	mov	dx, [u.cdrv]
 20912 000063E6 668915[3C850000]    <1> 	mov	[cdev], dx 	    ; NOTE: Retro UNIX 8086 v1 
 20913                              <1> 				    ; device/drive number is in 1 byte, 
 20914                              <1> 				    ; not in 1 word!
 20915                              <1> 		; mov u.cdev,cdev / device number for users directory 
 20916                              <1> 				; / into cdev
 20917                              <1> 	; 12/10/2015
 20918                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 20919                              <1>       	 ; convert virtual (pathname) addr to physical address
 20920 000063ED E82C010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
 20921                              <1> 		; esi = physical address of [u.namep]
 20922                              <1> 		; ecx = byte count in the page
 20923 000063F2 803E2F              <1> 	cmp	byte [esi], '/'
 20924                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
 20925 000063F5 751E                <1> 	jne	short namei_1
 20926                              <1> 		; bne 1f
 20927 000063F7 FF05[70850000]      <1> 	inc	dword [u.namep]
 20928                              <1> 		; inc u.namep / go to next char
 20929 000063FD 6649                <1> 	dec	cx ; remain byte count in the page
 20930 000063FF 7506                <1> 	jnz	short namei_0
 20931                              <1> 	; 12/10/2015
 20932 00006401 E818010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 20933                              <1> 		; esi = physical address (page start + offset)
 20934                              <1> 		; ecx = byte count in the page
 20935 00006406 4E                  <1> 	dec	esi
 20936                              <1> namei_0:
 20937 00006407 46                  <1> 	inc 	esi  ; go to next char
 20938 00006408 66A1[46850000]      <1> 	mov	ax, [rootdir] ; 09/07/2013
 20939                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
 20940 0000640E C605[3C850000]00    <1> 	mov	byte [cdev], 0
 20941                              <1> 		; clr cdev / clear device number
 20942                              <1> namei_1: ; 1:
 20943 00006415 F606FF              <1> 	test	byte [esi], 0FFh
 20944 00006418 74BE                <1> 	jz	short getf4
 20945                              <1> 	;jz      nig
 20946                              <1> 		; tstb *u.namep / is the character in file name a nul
 20947                              <1> 		; beq nig / yes, end of file name reached; 
 20948                              <1> 			; / branch to "nig"
 20949                              <1> namei_2: ; 1:
 20950                              <1> 	; 18/10/2015
 20951 0000641A 8935[D0850000]      <1> 	mov 	[nbase], esi
 20952 00006420 66890D[D4850000]    <1> 	mov 	[ncount], cx
 20953                              <1> 	;
 20954                              <1> 	;mov	dx, 2
 20955 00006427 B202                <1> 	mov	dl, 2 ; user flag (read, non-owner)
 20956 00006429 E859060000          <1> 	call	access
 20957                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
 20958                              <1> 	; 'access' will not return here if user has not "r" permission !
 20959 0000642E 66F705[2C820000]00- <1> 	test 	word [i.flgs], 4000h
 20960 00006436 40                  <1>
 20961                              <1> 		; bit $40000,i.flgs / directory i-node?
 20962 00006437 746A                <1>         jz      short namei_err
 20963                              <1> 		; beq error3 / no, got an error
 20964                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 20965 00006439 31C0                <1> 	xor	eax, eax
 20966 0000643B A3[74850000]        <1> 	mov	[u.off], eax ; 0
 20967 00006440 66A1[30820000]      <1> 	mov	ax, [i.size]
 20968 00006446 A3[6C850000]        <1> 	mov	[u.dirp], eax
 20969                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
 20970                              <1> 		; clr u.off / u.off is file offset used by user
 20971 0000644B C705[68850000]-     <1> 	mov	dword [u.fofp], u.off
 20972 00006451 [74850000]          <1>
 20973                              <1> 		; mov $u.off,u.fofp / u.fofp is a pointer to 
 20974                              <1> 				  ; / the offset portion of fsp entry
 20975                              <1> namei_3: ; 2:
 20976 00006455 C705[78850000]-     <1> 	mov	dword [u.base], u.dirbuf
 20977 0000645B [8A850000]          <1>
 20978                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
 20979                              <1> 				    ; / copied from a directory
 20980 0000645F C705[7C850000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
 20981 00006467 0000                <1>
 20982                              <1>  		; mov $10.,u.count / u.count is byte count 
 20983                              <1> 				 ; / for reads and writes
 20984 00006469 66A1[38850000]      <1> 	mov 	ax, [ii]
 20985                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
 20986 0000646F FE05[BF850000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
 20987 00006475 E800060000          <1>     	call	readi
 20988                              <1> 		; jsr r0,readi / read 10. bytes of file 
 20989                              <1> 		      ; with i-number (r1); i.e. read a directory entry
 20990 0000647A 8B0D[80850000]      <1> 	mov 	ecx, [u.nread]
 20991 00006480 09C9                <1> 	or 	ecx, ecx
 20992                              <1> 		; tst u.nread
 20993 00006482 741B                <1> 	jz	short nib
 20994                              <1> 		; ble nib / gives error return
 20995                              <1> 	;
 20996 00006484 668B1D[8A850000]    <1> 	mov 	bx, [u.dirbuf]
 20997 0000648B 6621DB              <1> 	and 	bx, bx       
 20998                              <1> 		; tst u.dirbuf /
 20999 0000648E 7522                <1> 	jnz	short namei_4
 21000                              <1> 		; bne 3f / branch when active directory entry 
 21001                              <1> 		       ; / (i-node word in entry non zero)
 21002 00006490 A1[74850000]        <1> 	mov	eax, [u.off]
 21003 00006495 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
 21004 00006498 A3[6C850000]        <1> 	mov	[u.dirp], eax
 21005                              <1> 		; mov u.off,u.dirp
 21006                              <1> 		; sub $10.,u.dirp
 21007 0000649D EBB6                <1> 	jmp	short namei_3
 21008                              <1> 		; br 2b
 21009                              <1> 
 21010                              <1> 	; 18/07/2013
 21011                              <1> nib: 
 21012 0000649F 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
 21013 000064A1 F9                  <1> 	stc
 21014                              <1> nig:
 21015 000064A2 C3                  <1> 	retn
 21016                              <1> 
 21017                              <1> namei_err:
 21018                              <1> 	; 16/06/2015
 21019 000064A3 C705[AD850000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
 21020 000064AB 0000                <1>
 21021 000064AD E96BF0FFFF          <1> 	jmp	error
 21022                              <1> 
 21023                              <1> namei_4: ; 3:
 21024                              <1> 	; 18/10/2015
 21025                              <1> 	; 12/10/2015
 21026                              <1> 	; 21/08/2015
 21027                              <1> 	; 18/07/2015
 21028 000064B2 8B2D[70850000]      <1> 	mov	ebp, [u.namep]
 21029                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
 21030 000064B8 BF[8C850000]        <1> 	mov 	edi, u.dirbuf + 2
 21031                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
 21032                              <1> 	; 18/10/2015
 21033 000064BD 8B35[D0850000]      <1> 	mov	esi, [nbase]	
 21034 000064C3 668B0D[D4850000]    <1> 	mov	cx, [ncount]
 21035                              <1> 	;
 21036 000064CA 6621C9              <1> 	and	cx, cx
 21037 000064CD 7505                <1> 	jnz	short namei_5	
 21038                              <1> 	;
 21039 000064CF E850000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 21040                              <1> 		; esi = physical address (page start + offset)
 21041                              <1> 		; ecx = byte count in the page
 21042                              <1> namei_5: ; 3:
 21043 000064D4 45                  <1> 	inc	ebp ; 18/07/2015
 21044 000064D5 AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
 21045                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
 21046 000064D6 08C0                <1> 	or 	al, al
 21047 000064D8 741D                <1> 	jz 	short namei_7
 21048                              <1> 		; beq 3f / if char is nul, then the last char in string
 21049                              <1> 			; / has been moved
 21050 000064DA 3C2F                <1> 	cmp	al, '/'
 21051                              <1> 		; cmp r4,$'/ / is char a </>
 21052 000064DC 7419                <1> 	je 	short namei_7
 21053                              <1> 		; beq 3f	
 21054                              <1> 	; 12/10/2015
 21055 000064DE 6649                <1> 	dec	cx ; remain byte count in the page
 21056 000064E0 7505                <1> 	jnz	short namei_6
 21057 000064E2 E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 21058                              <1> 		; esi = physical address (page start + offset)
 21059                              <1> 		; ecx = byte count in the page
 21060                              <1> namei_6:
 21061 000064E7 81FF[9A850000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 21062                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
 21063                              <1> 				     ; / all 8 bytes of file name
 21064 000064ED 74E5                <1> 	je	short namei_5
 21065                              <1> 		; beq 3b
 21066 000064EF AE                  <1> 	scasb	
 21067                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
 21068                              <1> 			      ; / char read from directory
 21069 000064F0 74E2                <1> 	je 	short namei_5
 21070                              <1> 		; beq 3b / branch if chars match
 21071                              <1> 
 21072 000064F2 E95EFFFFFF          <1>         jmp    namei_3 ; 2b
 21073                              <1> 		; br 2b / file names do not match go to next directory entry
 21074                              <1> namei_7: ; 3:
 21075 000064F7 81FF[9A850000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 21076                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
 21077 000064FD 740A                <1> 	je	short namei_8
 21078                              <1> 		; beq 3f
 21079 000064FF 8A27                <1> 	mov 	ah, [edi]
 21080                              <1> 	;inc 	edi 
 21081 00006501 20E4                <1> 	and 	ah, ah
 21082                              <1> 		; tstb (r3)+ /
 21083 00006503 0F854CFFFFFF        <1>         jnz     namei_3
 21084                              <1> 		; bne 2b
 21085                              <1> namei_8: ; 3
 21086 00006509 892D[70850000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
 21087                              <1> 		; mov r2,u.namep / u.namep points to char 
 21088                              <1> 			       ; / following a / or nul
 21089                              <1> 	;mov	bx, [u.dirbuf]
 21090                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
 21091                              <1> 				; / entry to r1
 21092 0000650F 20C0                <1> 	and 	al, al
 21093                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
 21094                              <1> 		      ;  / if r4 = </> then go to next directory
 21095                              <1> 	; mov	ax, bx
 21096 00006511 66A1[8A850000]      <1> 	mov 	ax, [u.dirbuf] ; 17/06/2015
 21097 00006517 0F85FDFEFFFF        <1>         jnz     namei_2 
 21098                              <1> 		; bne 1b
 21099                              <1> 	; AX = i-number of the file
 21100                              <1> ;;nig:
 21101 0000651D C3                  <1> 	retn
 21102                              <1> 		; tst (r0)+ / gives non-error return
 21103                              <1> ;;nib:
 21104                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
 21105                              <1> 		       ; ax = 0 -> file not found 
 21106                              <1> ;;	stc	; 27/05/2013
 21107                              <1> ;;	retn
 21108                              <1> 		; rts r0
 21109                              <1> 
 21110                              <1> trans_addr_nmbp:
 21111                              <1> 	; 18/10/2015
 21112                              <1> 	; 12/10/2015
 21113 0000651E 8B2D[70850000]      <1> 	mov 	ebp, [u.namep]
 21114                              <1> trans_addr_nm: 
 21115                              <1> 	; Convert virtual (pathname) address to physical address
 21116                              <1> 	; (Retro UNIX 386 v1 feature only !)
 21117                              <1> 	; 18/10/2015
 21118                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
 21119                              <1> 	; 02/07/2015
 21120                              <1> 	; 17/06/2015
 21121                              <1> 	; 16/06/2015
 21122                              <1> 	;
 21123                              <1> 	; INPUTS: 
 21124                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
 21125                              <1> 	;	[u.pgdir] = user's page directory
 21126                              <1> 	; OUTPUT:
 21127                              <1> 	;       esi = physical address of the pathname
 21128                              <1> 	;	ecx = remain byte count in the page
 21129                              <1> 	;
 21130                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI)
 21131                              <1> 	;
 21132 00006524 833D[B5850000]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
 21133 0000652B 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
 21134                              <1> 				     ; it is already physical address
 21135 0000652D 50                  <1>    	push	eax	
 21136 0000652E 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
 21137 00006530 E8CFD2FFFF          <1>        	call	get_physical_addr ; get physical address
 21138 00006535 7204                <1> 	jc	short tr_addr_nm_err
 21139                              <1> 	; 18/10/2015
 21140                              <1> 	; eax = physical address 
 21141                              <1> 	; cx = remain byte count in page (1-4096) 
 21142                              <1> 		; 12/10/2015 (cx = [u.pncount])
 21143 00006537 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
 21144 00006539 58                  <1> 	pop	eax 
 21145 0000653A C3                  <1> 	retn
 21146                              <1> 
 21147                              <1> tr_addr_nm_err:
 21148 0000653B A3[AD850000]        <1> 	mov	[u.error], eax
 21149                              <1> 	;pop 	eax
 21150 00006540 E9D8EFFFFF          <1> 	jmp	error
 21151                              <1> 
 21152                              <1> trans_addr_nmk:
 21153                              <1> 	; 12/10/2015
 21154                              <1> 	; 02/07/2015
 21155 00006545 8B35[70850000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
 21156 0000654B 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
 21157 0000654F C3                  <1> 	retn
 21158                              <1> 
 21159                              <1> syschdir:
 21160                              <1> 	; / makes the directory specified in the argument
 21161                              <1> 	; / the current directory
 21162                              <1> 	;
 21163                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 21164                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 21165                              <1> 	;
 21166                              <1> 	; 'syschdir' makes the directory specified in its argument
 21167                              <1> 	; the current working directory.
 21168                              <1> 	;
 21169                              <1> 	; Calling sequence:
 21170                              <1> 	;	syschdir; name
 21171                              <1> 	; Arguments:
 21172                              <1> 	;	name - address of the path name of a directory
 21173                              <1> 	;	       terminated by nul byte.	
 21174                              <1> 	; Inputs: -
 21175                              <1> 	; Outputs: -
 21176                              <1> 	; ...............................................................
 21177                              <1> 	;				
 21178                              <1> 	; Retro UNIX 8086 v1 modification:
 21179                              <1> 	;	 The user/application program puts address of 
 21180                              <1> 	;	 the path name in BX register as 'syschdir' 
 21181                              <1> 	; 	 system call argument.
 21182                              <1> 
 21183 00006550 891D[70850000]      <1> 	mov	[u.namep], ebx
 21184                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
 21185 00006556 E87EFEFFFF          <1> 	call	namei
 21186                              <1> 		; jsr r0,namei / find its i-number
 21187                              <1> 	;jc	error
 21188                              <1> 		; br error3
 21189 0000655B 730F                <1> 	jnc	short syschdir0
 21190                              <1> 	; 'directory not found !' error
 21191 0000655D C705[AD850000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
 21192 00006565 0000                <1>
 21193 00006567 E9B1EFFFFF          <1> 	jmp	error
 21194                              <1> syschdir0:
 21195 0000656C E816050000          <1> 	call	access
 21196                              <1> 		; jsr r0,access; 2 / get i-node into core
 21197 00006571 66F705[2C820000]00- <1> 	test	word [i.flgs], 4000h
 21198 00006579 40                  <1>
 21199                              <1> 		; bit $40000,i.flgs / is it a directory?
 21200                              <1> 	;jz	error 
 21201                              <1> 		; beq error3 / no error
 21202 0000657A 750F                <1> 	jnz	short syschdir1
 21203 0000657C C705[AD850000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 21204 00006584 0000                <1>
 21205 00006586 E992EFFFFF          <1> 	jmp	error
 21206                              <1> syschdir1:
 21207 0000658B 66A3[5C850000]      <1> 	mov	[u.cdir], ax
 21208                              <1> 		; mov r1,u.cdir / move i-number to users 
 21209                              <1> 			      ; / current directory
 21210 00006591 66A1[3C850000]      <1> 	mov	ax, [cdev]
 21211 00006597 66A3[A2850000]      <1> 	mov	[u.cdrv], ax
 21212                              <1> 		; mov cdev,u.cdev / move its device to users 
 21213                              <1> 			        ; / current device
 21214 0000659D E99BEFFFFF          <1> 	jmp	sysret
 21215                              <1> 		; br sysret3
 21216                              <1> 	
 21217                              <1> syschmod: ; < change mode of file >
 21218                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 21219                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 21220                              <1> 	;
 21221                              <1> 	; 'syschmod' changes mode of the file whose name is given as
 21222                              <1> 	; null terminated string pointed to by 'name' has it's mode 
 21223                              <1> 	; changed to 'mode'.
 21224                              <1> 	;
 21225                              <1> 	; Calling sequence:
 21226                              <1> 	;	syschmod; name; mode
 21227                              <1> 	; Arguments:
 21228                              <1> 	;	name - address of the file name
 21229                              <1> 	;	       terminated by null byte.
 21230                              <1> 	;	mode - (new) mode/flags < attributes >
 21231                              <1> 	;	
 21232                              <1> 	; Inputs: -
 21233                              <1> 	; Outputs: -
 21234                              <1> 	; ...............................................................
 21235                              <1> 	;				
 21236                              <1> 	; Retro UNIX 8086 v1 modification: 
 21237                              <1> 	;       'syschmod' system call has two arguments; so,
 21238                              <1> 	;	* 1st argument, name is pointed to by BX register
 21239                              <1> 	;	* 2nd argument, mode is in CX register
 21240                              <1> 	;
 21241                              <1> 	; Mode bits (Flags):
 21242                              <1> 	;	bit 0 - write permission for non-owner (1)
 21243                              <1> 	;	bit 1 - read permission for non-owner (2)
 21244                              <1> 	;	bit 2 - write permission for owner (4)
 21245                              <1> 	;	bit 3 - read permission for owner (8)
 21246                              <1> 	;	bit 4 - executable flag (16) 	
 21247                              <1> 	;	bit 5 - set user ID on execution flag (32) 
 21248                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
 21249                              <1> 	;	bit 12 - large file flag (4096)
 21250                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
 21251                              <1> 	;	bit 14 - directory flag (16384)
 21252                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
 21253                              <1> 
 21254                              <1> 	; / name; mode
 21255 000065A2 E814000000          <1> 	call	isown
 21256                              <1> 		;jsr r0,isown / get the i-node and check user status
 21257 000065A7 66F705[2C820000]00- <1> 	test	word [i.flgs], 4000h
 21258 000065AF 40                  <1>
 21259                              <1> 		; bit	$40000,i.flgs / directory?
 21260 000065B0 7402                <1> 	jz	short syschmod1
 21261                              <1> 		; beq 2f / no
 21262                              <1> 	; AL = (new) mode
 21263 000065B2 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
 21264                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
 21265                              <1> 			   ; / executable modes
 21266                              <1> syschmod1: ; 2:
 21267 000065B4 A2[2C820000]        <1> 	mov	[i.flgs], al	
 21268                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
 21269 000065B9 EB42                <1> 	jmp	short isown1
 21270                              <1> 		; br 1f
 21271                              <1> 
 21272                              <1> isown:
 21273                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21274                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 21275                              <1> 	;
 21276                              <1> 	; 'isown' is given a file name (the 1st argument).
 21277                              <1> 	;  It find the i-number of that file via 'namei' 
 21278                              <1> 	;  then gets the i-node into core via 'iget'.
 21279                              <1> 	;  It then tests to see if the user is super user. 
 21280                              <1> 	;  If not, it cheks to see if the user is owner of 
 21281                              <1> 	;  the file. If he is not an error occurs.
 21282                              <1> 	;  If user is the owner 'setimod' is called to indicate
 21283                              <1> 	;  the inode has been modificed and the 2nd argument of
 21284                              <1> 	;  the call is put in r2.
 21285                              <1> 	;
 21286                              <1> 	; INPUTS ->
 21287                              <1> 	;    arguments of syschmod and syschown calls
 21288                              <1> 	; OUTPUTS ->
 21289                              <1> 	;    u.uid - id of user
 21290                              <1> 	;    imod - set to a 1
 21291                              <1> 	;    r2 - contains second argument of the system call				 	
 21292                              <1> 	;
 21293                              <1> 	;   ((AX=R2) output as 2nd argument)
 21294                              <1> 	;
 21295                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 21296                              <1> 	;
 21297                              <1> 		; jsr r0,arg2 / u.namep points to file name
 21298                              <1> 	;; ! 2nd argument on top of stack !
 21299                              <1> 	;; 22/06/2015 - 32 bit modifications
 21300                              <1> 	;; 07/07/2013
 21301 000065BB 891D[70850000]      <1> 	mov	[u.namep], ebx ;; 1st argument
 21302 000065C1 51                  <1> 	push 	ecx ;; 2nd argument
 21303                              <1> 	;;
 21304 000065C2 E812FEFFFF          <1> 	call	namei
 21305                              <1> 		; jsr r0,namei / get its i-number
 21306                              <1>        ; Retro UNIX 8086 v1 modification !
 21307                              <1>        ; ax = 0 -> file not found 
 21308                              <1> 	;and	ax, ax
 21309                              <1> 	;jz	error
 21310                              <1> 	;jc	error ; 27/05/2013
 21311                              <1> 		; br error3
 21312 000065C7 730F                <1> 	jnc	short isown0
 21313                              <1> 	; 'file not found !' error
 21314 000065C9 C705[AD850000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 21315 000065D1 0000                <1>
 21316 000065D3 E945EFFFFF          <1> 	jmp	error
 21317                              <1> isown0:
 21318 000065D8 E898040000          <1> 	call	iget
 21319                              <1> 		; jsr r0,iget / get i-node into core
 21320 000065DD A0[A4850000]        <1> 	mov	al, [u.uid] ; 02/08/2013
 21321 000065E2 08C0                <1> 	or	al, al
 21322                              <1> 		; tstb u.uid / super user?
 21323 000065E4 7417                <1> 	jz	short isown1
 21324                              <1> 		; beq 1f / yes, branch
 21325 000065E6 3A05[2F820000]      <1> 	cmp	al, [i.uid]
 21326                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
 21327                              <1> 				 ; / the file
 21328                              <1> 	;jne	error
 21329                              <1> 		; beq 1f / yes
 21330                              <1> 		; jmp error3 / no, error
 21331 000065EC 740F                <1> 	je	short isown1
 21332                              <1> 
 21333 000065EE C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
 21334 000065F6 0000                <1>
 21335                              <1> 			;  'permission denied !' error
 21336 000065F8 E920EFFFFF          <1> 	jmp	error
 21337                              <1> isown1: ; 1:
 21338 000065FD E881040000          <1> 	call	setimod
 21339                              <1> 		; jsr r0,setimod / indicates 
 21340                              <1> 		;	       ; / i-node has been modified
 21341 00006602 58                  <1> 	pop	eax ; 2nd argument
 21342                              <1> 		; mov (sp)+,r2 / mode is put in r2 
 21343                              <1> 		       ; / (u.off put on stack with 2nd arg)
 21344 00006603 C3                  <1> 	retn
 21345                              <1> 		; rts r0
 21346                              <1> 
 21347                              <1> ;;arg:  ; < get system call arguments >
 21348                              <1> 	; 'arg' extracts an argument for a routine whose call is 
 21349                              <1> 	; of form:
 21350                              <1> 	;	sys 'routine' ; arg1
 21351                              <1> 	;		or
 21352                              <1> 	;	sys 'routine' ; arg1 ; arg2
 21353                              <1> 	;		or
 21354                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
 21355                              <1> 	;	
 21356                              <1> 	; INPUTS ->
 21357                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
 21358                              <1> 	;	This pointers's value is actually the value of
 21359                              <1> 	;	update pc at the the trap to sysent (unkni) is
 21360                              <1> 	;	made to process the sys instruction
 21361                              <1> 	;    r0 - contains the return address for the routine
 21362                              <1> 	;	that called arg. The data in the word pointer 
 21363                              <1> 	;	to by the return address is used as address
 21364                              <1> 	;	in which the extracted argument is stored   		
 21365                              <1> 	;    	
 21366                              <1> 	; OUTPUTS ->
 21367                              <1> 	;    'address' - contains the extracted argument 
 21368                              <1> 	;    u.sp+18 - is incremented by 2 
 21369                              <1> 	;    r1 - contains the extracted argument
 21370                              <1> 	;    r0 - points to the next instruction to be
 21371                              <1> 	;	 executed in the calling routine.
 21372                              <1> 	;
 21373                              <1>   
 21374                              <1> 	; mov u.sp,r1
 21375                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
 21376                              <1> 			; / into argument of arg2
 21377                              <1> 	; add $2,18.(r1) / point pc on stack 
 21378                              <1> 			      ; / to next system argument
 21379                              <1> 	; rts r0
 21380                              <1> 
 21381                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
 21382                              <1> 	; 'arg2' takes first argument in system call
 21383                              <1> 	;  (pointer to name of the file) and puts it in location
 21384                              <1> 	;  u.namep; takes second argument and puts it in u.off
 21385                              <1> 	;  and on top of the stack
 21386                              <1> 	;	
 21387                              <1> 	; INPUTS ->
 21388                              <1> 	;    u.sp, r0
 21389                              <1> 	;    	
 21390                              <1> 	; OUTPUTS ->
 21391                              <1> 	;    u.namep
 21392                              <1> 	;    u.off 
 21393                              <1> 	;    u.off pushed on stack
 21394                              <1> 	;    r1
 21395                              <1> 	;
 21396                              <1> 
 21397                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
 21398                              <1> 				; / first arg in sys call
 21399                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
 21400                              <1> 				; / second arg in sys call
 21401                              <1> 	; mov r0,r1 / r0 points to calling routine
 21402                              <1> 	; mov (sp),r0 / put operation code back in r0
 21403                              <1> 	; mov u.off,(sp) / put pointer to second argument 
 21404                              <1> 			; / on stack
 21405                              <1> 	; jmp (r1) / return to calling routine
 21406                              <1> 
 21407                              <1> syschown: ; < change owner of file >
 21408                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 21409                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 21410                              <1> 	;
 21411                              <1> 	; 'syschown' changes the owner of the file whose name is given
 21412                              <1> 	; as null terminated string pointed to by 'name' has it's owner
 21413                              <1> 	; changed to 'owner'
 21414                              <1> 	;
 21415                              <1> 	; Calling sequence:
 21416                              <1> 	;	syschown; name; owner
 21417                              <1> 	; Arguments:
 21418                              <1> 	;	name - address of the file name
 21419                              <1> 	;	       terminated by null byte.
 21420                              <1> 	;	owner - (new) owner (number/ID)
 21421                              <1> 	;	
 21422                              <1> 	; Inputs: -
 21423                              <1> 	; Outputs: -
 21424                              <1> 	; ...............................................................
 21425                              <1> 	;				
 21426                              <1> 	; Retro UNIX 8086 v1 modification: 
 21427                              <1> 	;       'syschown' system call has two arguments; so,
 21428                              <1> 	;	* 1st argument, name is pointed to by BX register
 21429                              <1> 	;	* 2nd argument, owner number is in CX register
 21430                              <1> 	;
 21431                              <1> 	; / name; owner
 21432 00006604 E8B2FFFFFF          <1> 	call	isown
 21433                              <1> 		; jsr r0,isown / get the i-node and check user status
 21434 00006609 803D[A4850000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
 21435                              <1> 		; tstb u.uid / super user
 21436 00006610 7418                <1> 	jz	short syschown1
 21437                              <1> 		; beq 2f / yes, 2f
 21438 00006612 F605[2C820000]20    <1>         test    byte [i.flgs], 20h ; 32
 21439                              <1> 		; bit $40,i.flgs / no, set userid on execution?
 21440                              <1> 	;jnz	error
 21441                              <1> 		; bne 3f / yes error, could create Trojan Horses
 21442 00006619 740F                <1> 	jz	short syschown1
 21443                              <1> 	; 'permission denied !'
 21444 0000661B C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
 21445 00006623 0000                <1>
 21446 00006625 E9F3EEFFFF          <1> 	jmp	error
 21447                              <1> syschown1: ; 2:
 21448                              <1> 	; AL = owner (number/ID)
 21449 0000662A A2[2F820000]        <1> 	mov	[i.uid], al ; 23/06/2015
 21450                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
 21451                              <1> 			       ; / in the i-node
 21452 0000662F E909EFFFFF          <1> 	jmp	sysret
 21453                              <1> 	; 1: 
 21454                              <1> 		; jmp sysret4
 21455                              <1> 	; 3:
 21456                              <1> 		; jmp	error
 21457                              <1> 
 21458                              <1> systime: ; / get time of year
 21459                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 21460                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 21461                              <1> 	;
 21462                              <1> 	; 20/06/2013
 21463                              <1> 	; 'systime' gets the time of the year.
 21464                              <1> 	; The present time is put on the stack.
 21465                              <1> 	;
 21466                              <1> 	; Calling sequence:
 21467                              <1> 	;	systime
 21468                              <1> 	; Arguments: -
 21469                              <1> 	;	
 21470                              <1> 	; Inputs: -
 21471                              <1> 	; Outputs: sp+2, sp+4 - present time
 21472                              <1> 	; ...............................................................
 21473                              <1> 	;	
 21474                              <1> 	; Retro UNIX 8086 v1 modification: 
 21475                              <1> 	;       'systime' system call will return to the user
 21476                              <1> 	;	with unix time (epoch) in DX:AX register pair
 21477                              <1> 	;
 21478                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
 21479                              <1> 	;	system call for PC compatibility !!		 	
 21480                              <1> 
 21481 00006634 E851040000          <1> 	call 	epoch
 21482 00006639 A3[58850000]        <1> 	mov 	[u.r0], eax
 21483                              <1> 		; mov s.time,4(sp)
 21484                              <1> 		; mov s.time+2,2(sp) / put the present time 
 21485                              <1> 				   ; / on the stack
 21486                              <1> 		; br sysret4
 21487 0000663E E9FAEEFFFF          <1> 	jmp	sysret 
 21488                              <1> 
 21489                              <1> sysstime: ; / set time
 21490                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 21491                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 21492                              <1> 	;
 21493                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
 21494                              <1> 	;
 21495                              <1> 	; Calling sequence:
 21496                              <1> 	;	sysstime
 21497                              <1> 	; Arguments: -
 21498                              <1> 	;	
 21499                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
 21500                              <1> 	; Outputs: -
 21501                              <1> 	; ...............................................................
 21502                              <1> 	;	
 21503                              <1> 	; Retro UNIX 8086 v1 modification: 
 21504                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
 21505                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
 21506                              <1> 	; 
 21507                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 21508                              <1> 	;	to get sysstime system call arguments from the user;
 21509                              <1> 	;	* 1st argument, lowword of unix time is in BX register
 21510                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
 21511                              <1> 	;
 21512                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
 21513                              <1> 	;	system call for PC compatibility !!	
 21514                              <1> 
 21515 00006643 803D[A4850000]00    <1> 	cmp	byte [u.uid], 0
 21516                              <1> 		; tstb u.uid / is user the super user
 21517                              <1> 	;ja	error
 21518                              <1> 		; bne error4 / no, error
 21519 0000664A 760F                <1> 	jna	short systime1
 21520                              <1> 	; 'permission denied !'
 21521 0000664C C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
 21522 00006654 0000                <1>
 21523 00006656 E9C2EEFFFF          <1> 	jmp	error
 21524                              <1> systime1:
 21525                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
 21526                              <1> 	; EBX = unix (epoch) time (from user)
 21527 0000665B 89D8                <1> 	mov	eax, ebx
 21528 0000665D E829040000          <1> 	call 	set_date_time
 21529                              <1> 		; mov 4(sp),s.time
 21530                              <1> 		; mov 2(sp),s.time+2 / set the system time
 21531 00006662 E9D6EEFFFF          <1> 	jmp	sysret
 21532                              <1> 		; br sysret4
 21533                              <1> 
 21534                              <1> sysbreak:
 21535                              <1> 	; 18/10/2015
 21536                              <1> 	; 07/10/2015
 21537                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 21538                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
 21539                              <1> 	;
 21540                              <1> 	; 'sysbreak' sets the programs break points. 
 21541                              <1> 	; It checks the current break point (u.break) to see if it is
 21542                              <1> 	; between "core" and the stack (sp). If it is, it is made an
 21543                              <1> 	; even address (if it was odd) and the area between u.break
 21544                              <1> 	; and the stack is cleared. The new breakpoint is then put
 21545                              <1> 	; in u.break and control is passed to 'sysret'.
 21546                              <1> 	;
 21547                              <1> 	; Calling sequence:
 21548                              <1> 	;	sysbreak; addr
 21549                              <1> 	; Arguments: -
 21550                              <1> 	;	
 21551                              <1> 	; Inputs: u.break - current breakpoint
 21552                              <1> 	; Outputs: u.break - new breakpoint 
 21553                              <1> 	;	area between old u.break and the stack (sp) is cleared.
 21554                              <1> 	; ...............................................................
 21555                              <1> 	;	
 21556                              <1> 	; Retro UNIX 8086 v1 modification:
 21557                              <1> 	;	The user/application program puts breakpoint address
 21558                              <1> 	;       in BX register as 'sysbreak' system call argument.
 21559                              <1> 	; 	(argument transfer method 1)
 21560                              <1> 	;
 21561                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
 21562                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
 21563                              <1> 	;  NOTE:
 21564                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
 21565                              <1> 	;	'u.break' address) of user's memory for original unix's
 21566                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
 21567                              <1> 
 21568                              <1> 		; mov u.break,r1 / move users break point to r1
 21569                              <1> 		; cmp r1,$core / is it the same or lower than core?
 21570                              <1> 		; blos 1f / yes, 1f
 21571                              <1> 	; 23/06/2015
 21572 00006667 8B2D[84850000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
 21573                              <1> 	;and	ebp, ebp
 21574                              <1> 	;jz	short sysbreak_3 
 21575                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
 21576                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
 21577 0000666D 8B15[50850000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
 21578 00006673 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
 21579                              <1> 	; 07/10/2015
 21580 00006676 891D[84850000]      <1> 	mov	[u.break], ebx ; virtual address !!!
 21581                              <1> 	;
 21582 0000667C 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
 21583                              <1> 			   ; with top of user's stack (virtual!)
 21584 0000667E 7327                <1> 	jnb	short sysbreak_3
 21585                              <1> 		; cmp r1,sp / is it the same or higher 
 21586                              <1> 			  ; / than the stack?
 21587                              <1> 		; bhis 1f / yes, 1f
 21588 00006680 89DE                <1> 	mov	esi, ebx
 21589 00006682 29EE                <1> 	sub	esi, ebp ; new break point - old break point
 21590 00006684 7621                <1> 	jna	short sysbreak_3 
 21591                              <1> 	;push	ebx
 21592                              <1> sysbreak_1:
 21593 00006686 89EB                <1> 	mov	ebx, ebp  
 21594 00006688 E877D1FFFF          <1> 	call	get_physical_addr ; get physical address
 21595 0000668D 0F82A8FEFFFF        <1> 	jc	tr_addr_nm_err
 21596                              <1> 	; 18/10/2015
 21597 00006693 89C7                <1> 	mov	edi, eax 
 21598 00006695 29C0                <1> 	sub	eax, eax ; 0
 21599                              <1> 		 ; ECX = remain byte count in page (1-4096)
 21600 00006697 39CE                <1> 	cmp	esi, ecx
 21601 00006699 7302                <1> 	jnb	short sysbreak_2
 21602 0000669B 89F1                <1> 	mov	ecx, esi
 21603                              <1> sysbreak_2:
 21604 0000669D 29CE                <1> 	sub	esi, ecx
 21605 0000669F 01CD                <1> 	add	ebp, ecx
 21606 000066A1 F3AA                <1> 	rep 	stosb
 21607 000066A3 09F6                <1> 	or	esi, esi
 21608 000066A5 75DF                <1> 	jnz	short sysbreak_1
 21609                              <1> 	;
 21610                              <1> 		; bit $1,r1 / is it an odd address
 21611                              <1> 		; beq 2f / no, its even
 21612                              <1> 		; clrb (r1)+ / yes, make it even
 21613                              <1> 	; 2: / clear area between the break point and the stack
 21614                              <1> 		; cmp r1,sp / is it higher or same than the stack
 21615                              <1> 		; bhis 1f / yes, quit
 21616                              <1> 		; clr (r1)+ / clear word
 21617                              <1> 		; br 2b / go back
 21618                              <1> 	;pop	ebx
 21619                              <1> sysbreak_3: ; 1:
 21620                              <1> 	;mov	[u.break], ebx ; virtual address !!!
 21621                              <1> 		; jsr r0,arg; u.break / put the "address" 
 21622                              <1> 			; / in u.break (set new break point)
 21623                              <1> 		; br sysret4 / br sysret
 21624 000066A7 E991EEFFFF          <1> 	jmp	sysret
 21625                              <1> 
 21626                              <1> 
 21627                              <1> maknod: 
 21628                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21629                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 21630                              <1> 	;
 21631                              <1> 	; 'maknod' creates an i-node and makes a directory entry
 21632                              <1> 	; for this i-node in the current directory.
 21633                              <1> 	;
 21634                              <1> 	; INPUTS ->
 21635                              <1> 	;    r1 - contains mode
 21636                              <1> 	;    ii - current directory's i-number	
 21637                              <1> 	;    	
 21638                              <1> 	; OUTPUTS ->
 21639                              <1> 	;    u.dirbuf - contains i-number of free i-node 
 21640                              <1> 	;    i.flgs - flags in new i-node 
 21641                              <1> 	;    i.uid - filled with u.uid
 21642                              <1> 	;    i.nlks - 1 is put in the number of links
 21643                              <1> 	;    i.ctim - creation time				
 21644                              <1> 	;    i.ctim+2 - modification time
 21645                              <1> 	;    imod - set via call to setimod
 21646                              <1> 	;	
 21647                              <1> 	; ((AX = R1)) input
 21648                              <1> 	;
 21649                              <1> 	; (Retro UNIX Prototype : 
 21650                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
 21651                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 21652                              <1> 
 21653                              <1> 	; / r1 contains the mode
 21654 000066AC 80CC80              <1> 	or 	ah, 80h  ; 10000000b
 21655                              <1> 		; bis	$100000,r1 / allocate flag set
 21656 000066AF 6650                <1> 	push	ax
 21657                              <1> 		; mov r1,-(sp) / put mode on stack
 21658                              <1> 	; 31/07/2013
 21659 000066B1 66A1[38850000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
 21660                              <1> 		; mov ii,r1 / move current i-number to r1
 21661 000066B7 B201                <1> 	mov	dl, 1 ; owner flag mask
 21662 000066B9 E8C9030000          <1> 	call	access	
 21663                              <1> 		; jsr r0,access; 1 / get its i-node into core
 21664 000066BE 6650                <1> 	push	ax
 21665                              <1> 		; mov r1,-(sp) / put i-number on stack
 21666 000066C0 66B82800            <1> 	mov	ax, 40
 21667                              <1> 		; mov $40.,r1 / r1 = 40
 21668                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
 21669 000066C4 6640                <1> 	inc	ax
 21670                              <1> 		; inc r1 / r1 = r1 + 1
 21671 000066C6 E8C1030000          <1> 	call	imap
 21672                              <1> 		; jsr r0,imap / get byte address and bit position in 
 21673                              <1> 			    ; /	inode map in r2 & m
 21674                              <1>           ; DX (MQ) has a 1 in the calculated bit position
 21675                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
 21676                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
 21677                              <1> 	;	       Inode count must be checked here
 21678                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
 21679 000066CB 8413                <1> 	test	[ebx], dl
 21680                              <1> 		; bitb mq,(r2) / is the i-node active
 21681 000066CD 75F5                <1> 	jnz	short maknod1
 21682                              <1> 		; bne 1b / yes, try the next one
 21683 000066CF 0813                <1> 	or	[ebx], dl
 21684                              <1> 		; bisb mq,(r2) / no, make it active 
 21685                              <1> 			     ; / (put a 1 in the bit map)
 21686 000066D1 E89F030000          <1> 	call	iget
 21687                              <1> 		; jsr r0,iget / get i-node into core
 21688 000066D6 66F705[2C820000]00- <1> 	test	word [i.flgs], 8000h 
 21689 000066DE 80                  <1>
 21690                              <1> 		; tst i.flgs / is i-node already allocated
 21691 000066DF 75E3                <1> 	jnz	short maknod1	
 21692                              <1> 		; blt 1b / yes, look for another one
 21693 000066E1 66A3[8A850000]      <1> 	mov	[u.dirbuf], ax
 21694                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
 21695 000066E7 6658                <1> 	pop	ax
 21696                              <1> 		; mov (sp)+,r1 / get current i-number back
 21697 000066E9 E887030000          <1> 	call	iget
 21698                              <1> 		; jsr r0,iget / get i-node in core
 21699 000066EE E87DF7FFFF          <1> 	call	mkdir
 21700                              <1> 		; jsr r0,mkdir / make a directory entry 
 21701                              <1> 			     ; / in current directory
 21702 000066F3 66A1[8A850000]      <1> 	mov	ax, [u.dirbuf]
 21703                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
 21704 000066F9 E877030000          <1> 	call	iget
 21705                              <1> 		; jsr r0,iget / get it into core
 21706                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
 21707 000066FE B908000000          <1> 	mov	ecx, 8 
 21708 00006703 31C0                <1> 	xor	eax, eax ; 0
 21709 00006705 BF[2C820000]        <1> 	mov	edi, inode 
 21710 0000670A F3AB                <1> 	rep	stosd
 21711                              <1> 	;
 21712 0000670C 668F05[2C820000]    <1> 	pop	word [i.flgs]
 21713                              <1> 		; mov (sp)+,i.flgs / fill flags
 21714 00006713 8A0D[A4850000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
 21715 00006719 880D[2F820000]      <1> 	mov 	[i.uid], cl
 21716                              <1> 		; movb u.uid,i.uid / user id	
 21717 0000671F C605[2E820000]01    <1> 	mov     byte [i.nlks], 1
 21718                              <1> 		; movb $1,i.nlks / 1 link
 21719                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
 21720                              <1> 	;mov	eax, [s.time]
 21721                              <1> 	;mov 	[i.ctim], eax
 21722                              <1> 	 	; mov s.time,i.ctim / time created
 21723                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
 21724                              <1> 	; Retro UNIX 8086 v1 modification !
 21725                              <1> 	; i.ctime=0, i.ctime+2=0 and
 21726                              <1>         ; 'setimod' will set ctime of file via 'epoch'
 21727 00006726 E858030000          <1> 	call setimod
 21728                              <1> 		; jsr r0,setimod / set modified flag
 21729 0000672B C3                  <1> 	retn
 21730                              <1> 		; rts r0 / return
 21731                              <1> 
 21732                              <1> sysseek: ; / moves read write pointer in an fsp entry
 21733                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21734                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 21735                              <1> 	;
 21736                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
 21737                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
 21738                              <1> 	; The file descriptor refers to a file open for reading or
 21739                              <1> 	; writing. The read (or write) pointer is set as follows:
 21740                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
 21741                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
 21742                              <1> 	;	  current location plus offset.
 21743                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
 21744                              <1> 	;	  size of file plus offset.
 21745                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
 21746                              <1> 	;
 21747                              <1> 	; Calling sequence:
 21748                              <1> 	;	sysseek; offset; ptrname
 21749                              <1> 	; Arguments:
 21750                              <1> 	;	offset - number of bytes desired to move 
 21751                              <1> 	;		 the r/w pointer
 21752                              <1> 	;	ptrname - a switch indicated above
 21753                              <1> 	;
 21754                              <1> 	; Inputs: r0 - file descriptor 
 21755                              <1> 	; Outputs: -
 21756                              <1> 	; ...............................................................
 21757                              <1> 	;	
 21758                              <1> 	; Retro UNIX 8086 v1 modification: 
 21759                              <1> 	;       'sysseek' system call has three arguments; so,
 21760                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
 21761                              <1> 	;	* 2nd argument, offset is in CX register
 21762                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
 21763                              <1> 	;	
 21764                              <1> 
 21765 0000672C E823000000          <1> 	call	seektell
 21766                              <1> 	; AX = u.count
 21767                              <1> 	; BX = *u.fofp
 21768                              <1> 		; jsr r0,seektell / get proper value in u.count
 21769                              <1> 		; add u.base,u.count / add u.base to it
 21770 00006731 0305[78850000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
 21771 00006737 8903                <1> 	mov	[ebx], eax
 21772                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
 21773 00006739 E9FFEDFFFF          <1> 	jmp	sysret
 21774                              <1> 		; br sysret4
 21775                              <1> 
 21776                              <1> systell: ; / get the r/w pointer
 21777                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21778                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 21779                              <1> 	;
 21780                              <1> 	; Retro UNIX 8086 v1 modification:
 21781                              <1> 	; ! 'systell' does not work in original UNIX v1,
 21782                              <1> 	; 	    it returns with error !
 21783                              <1> 	; Inputs: r0 - file descriptor 
 21784                              <1> 	; Outputs: r0 - file r/w pointer
 21785                              <1> 
 21786                              <1> 	;xor	ecx, ecx ; 0
 21787 0000673E BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
 21788                              <1> 	;call 	seektell
 21789 00006743 E812000000          <1> 	call 	seektell0 ; 05/08/2013
 21790                              <1> 	;mov	ebx, [u.fofp]
 21791 00006748 8B03                <1> 	mov	eax, [ebx]
 21792 0000674A A3[58850000]        <1> 	mov	[u.r0], eax
 21793 0000674F E9E9EDFFFF          <1> 	jmp	sysret
 21794                              <1> 
 21795                              <1> ; Original unix v1 'systell' system call:
 21796                              <1> 		; jsr r0,seektell
 21797                              <1> 		; br error4
 21798                              <1> 
 21799                              <1> seektell:
 21800                              <1> 	; 03/01/2016
 21801                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21802                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 21803                              <1> 	;
 21804                              <1> 	; 'seektell' puts the arguments from sysseek and systell
 21805                              <1> 	; call in u.base and u.count. It then gets the i-number of
 21806                              <1> 	; the file from the file descriptor in u.r0 and by calling
 21807                              <1> 	; getf. The i-node is brought into core and then u.count
 21808                              <1> 	; is checked to see it is a 0, 1, or 2.
 21809                              <1> 	; If it is 0 - u.count stays the same
 21810                              <1> 	;          1 - u.count = offset (u.fofp)
 21811                              <1> 	;	   2 - u.count = i.size (size of file)
 21812                              <1> 	; 	 		
 21813                              <1> 	; !! Retro UNIX 8086 v1 modification:
 21814                              <1> 	;	Argument 1, file descriptor is in BX;
 21815                              <1> 	;	Argument 2, offset is in CX;
 21816                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
 21817                              <1> 	;
 21818                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
 21819                              <1> 	; call 	arg
 21820                              <1> 	;
 21821                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
 21822                              <1> 	;
 21823 00006754 890D[78850000]      <1> 	mov 	[u.base], ecx ; offset
 21824                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
 21825                              <1> seektell0:
 21826 0000675A 8915[7C850000]      <1> 	mov 	[u.count], edx
 21827                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
 21828                              <1> 	; mov	ax, bx
 21829                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
 21830                              <1> 			     ; / (index in u.fp list)
 21831                              <1> 	; call	getf
 21832                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
 21833                              <1> 	; BX = file descriptor (file number)
 21834 00006760 E83DFCFFFF          <1> 	call	getf1
 21835 00006765 6609C0              <1> 	or	ax, ax ; i-number of the file
 21836                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
 21837                              <1> 		             ; / put it on the stack
 21838                              <1> 	;jz	error
 21839                              <1> 		; beq error4 / if i-number is 0, not active so error
 21840 00006768 750F                <1> 	jnz	short seektell1
 21841 0000676A C705[AD850000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 21842 00006772 0000                <1>
 21843 00006774 E9A4EDFFFF          <1> 	jmp	error
 21844                              <1> seektell1:
 21845                              <1> 	;push	eax
 21846 00006779 80FC80              <1> 	cmp	ah, 80h
 21847 0000677C 7203                <1> 	jb	short seektell2
 21848                              <1> 		; bgt .+4 / if its positive jump
 21849 0000677E 66F7D8              <1> 	neg	ax
 21850                              <1> 		; neg r1 / if not make it positive
 21851                              <1> seektell2:
 21852 00006781 E8EF020000          <1> 	call	iget
 21853                              <1> 		; jsr r0,iget / get its i-node into core
 21854 00006786 8B1D[68850000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
 21855 0000678C 803D[7C850000]01    <1> 	cmp	byte [u.count], 1
 21856                              <1> 		; cmp u.count,$1 / is ptr name =1
 21857 00006793 7705                <1> 	ja	short seektell3
 21858                              <1> 		; blt 2f / no its zero
 21859 00006795 740A                <1> 	je	short seektell_4
 21860                              <1> 		; beq 1f / yes its 1
 21861 00006797 31C0                <1> 	xor	eax, eax
 21862                              <1> 	;jmp	short seektell_5
 21863 00006799 C3                  <1> 	retn
 21864                              <1> seektell3:
 21865                              <1> 	; 03/01/2016
 21866                              <1> 	;movzx	eax, word [i.size]
 21867 0000679A 66A1[30820000]      <1>         mov   	ax, [i.size]
 21868                              <1>                 ; mov i.size,u.count /  put number of bytes 
 21869                              <1>                                    ; / in file in u.count
 21870                              <1> 	;jmp	short seektell_5
 21871                              <1> 		; br 2f
 21872 000067A0 C3                  <1> 	retn
 21873                              <1> seektell_4: ; 1: / ptrname =1
 21874                              <1> 	;mov	ebx, [u.fofp]
 21875 000067A1 8B03                <1> 	mov	eax, [ebx]
 21876                              <1> 		; mov *u.fofp,u.count / put offset in u.count
 21877                              <1> ;seektell_5: ; 2: / ptrname =0
 21878                              <1> 	;mov	[u.count], eax
 21879                              <1> 	;pop	eax 
 21880                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
 21881 000067A3 C3                  <1> 	retn
 21882                              <1> 		; rts r0
 21883                              <1> 
 21884                              <1> sysintr: ; / set interrupt handling
 21885                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21886                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 21887                              <1> 	;
 21888                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
 21889                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
 21890                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
 21891                              <1> 	; If one does the interrupt character in the tty buffer is
 21892                              <1> 	; cleared and 'sysret'is called. If one does not exits
 21893                              <1> 	; 'sysret' is just called.	
 21894                              <1> 	;
 21895                              <1> 	; Calling sequence:
 21896                              <1> 	;	sysintr; arg
 21897                              <1> 	; Argument:
 21898                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
 21899                              <1> 	;	    - if 1, intterupts cause their normal result
 21900                              <1> 	;		 i.e force an exit.
 21901                              <1> 	;	    - if arg is a location within the program,
 21902                              <1> 	;		control is passed to that location when
 21903                              <1> 	;		an interrupt occurs.	
 21904                              <1> 	; Inputs: -
 21905                              <1> 	; Outputs: -
 21906                              <1> 	; ...............................................................
 21907                              <1> 	;	
 21908                              <1> 	; Retro UNIX 8086 v1 modification: 
 21909                              <1> 	;       'sysintr' system call sets u.intr to value of BX
 21910                              <1> 	;	then branches into sysquit.
 21911                              <1> 	;
 21912 000067A4 66891D[9C850000]    <1> 	mov	[u.intr], bx
 21913                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
 21914                              <1> 		; br 1f / go into quit routine
 21915 000067AB E98DEDFFFF          <1> 	jmp	sysret
 21916                              <1> 
 21917                              <1> sysquit:
 21918                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21919                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 21920                              <1> 	;
 21921                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
 21922                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
 21923                              <1> 	; tty exists. If one does the interrupt character in the tty
 21924                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
 21925                              <1> 	; 'sysret' is just called.	
 21926                              <1> 	;
 21927                              <1> 	; Calling sequence:
 21928                              <1> 	;	sysquit; arg
 21929                              <1> 	; Argument:
 21930                              <1> 	;	arg - if 0, this call diables quit signals from the
 21931                              <1> 	;		typewriter (ASCII FS)
 21932                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
 21933                              <1> 	;		cease and a core image to be produced.
 21934                              <1> 	;		 i.e force an exit.
 21935                              <1> 	;	    - if arg is an addres in the program,
 21936                              <1> 	;		a quit causes control to sent to that
 21937                              <1> 	;		location.	
 21938                              <1> 	; Inputs: -
 21939                              <1> 	; Outputs: -
 21940                              <1> 	; ...............................................................
 21941                              <1> 	;	
 21942                              <1> 	; Retro UNIX 8086 v1 modification: 
 21943                              <1> 	;       'sysquit' system call sets u.quit to value of BX
 21944                              <1> 	;	then branches into 'sysret'.
 21945                              <1> 	;
 21946 000067B0 66891D[9E850000]    <1> 	mov	[u.quit], bx
 21947 000067B7 E981EDFFFF          <1> 	jmp	sysret
 21948                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
 21949                              <1> 	;1:
 21950                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
 21951                              <1> 			      ; / to r1
 21952                              <1> 		; beq sysret4 / return to user
 21953                              <1> 		; clrb 6(r1) / clear the interrupt character 
 21954                              <1> 			   ; / in the tty buffer
 21955                              <1> 		; br sysret4 / return to user
 21956                              <1> 
 21957                              <1> syssetuid: ; / set process id
 21958                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21959                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 21960                              <1> 	;
 21961                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
 21962                              <1> 	; to the process id in (u.r0). Both the effective user and 
 21963                              <1> 	; u.uid and the real user u.ruid are set to this. 
 21964                              <1> 	; Only the super user can make this call.	
 21965                              <1> 	;
 21966                              <1> 	; Calling sequence:
 21967                              <1> 	;	syssetuid
 21968                              <1> 	; Arguments: -
 21969                              <1> 	;
 21970                              <1> 	; Inputs: (u.r0) - contains the process id.
 21971                              <1> 	; Outputs: -
 21972                              <1> 	; ...............................................................
 21973                              <1> 	;	
 21974                              <1> 	; Retro UNIX 8086 v1 modification: 
 21975                              <1> 	;       BL contains the (new) user ID of the current process
 21976                              <1> 
 21977                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
 21978 000067BC 3A1D[A5850000]      <1> 	cmp	bl, [u.ruid] 
 21979                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
 21980                              <1> 			       ; / id number
 21981 000067C2 741E                <1> 	je	short setuid1
 21982                              <1> 		; beq 1f / yes
 21983 000067C4 803D[A4850000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 21984                              <1> 		; tstb u.uid / no, is current user the super user?
 21985                              <1> 	;ja	error
 21986                              <1> 		; bne error4 / no, error
 21987 000067CB 760F                <1> 	jna	short setuid0
 21988 000067CD C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
 21989 000067D5 0000                <1>
 21990                              <1> 				;  'permission denied !' error
 21991 000067D7 E941EDFFFF          <1> 	jmp	error
 21992                              <1> setuid0:
 21993 000067DC 881D[A5850000]      <1> 	mov	[u.ruid], bl
 21994                              <1> setuid1: ; 1:
 21995 000067E2 881D[A4850000]      <1> 	mov	[u.uid], bl ; 02/08/2013
 21996                              <1> 		; movb r1,u.uid / put process id in u.uid
 21997                              <1> 		; movb r1,u.ruid / put process id in u.ruid
 21998 000067E8 E950EDFFFF          <1> 	jmp	sysret
 21999                              <1> 		; br sysret4 / system return
 22000                              <1> 
 22001                              <1> sysgetuid: ; < get user id >
 22002                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 22003                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 22004                              <1> 	;
 22005                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
 22006                              <1> 	; The real user ID identifies the person who is logged in,
 22007                              <1> 	; in contradistinction to the effective user ID, which
 22008                              <1> 	; determines his access permission at each moment. It is thus
 22009                              <1> 	; useful to programs which operate using the 'set user ID'
 22010                              <1> 	; mode, to find out who invoked them.	
 22011                              <1> 	;
 22012                              <1> 	; Calling sequence:
 22013                              <1> 	;	syssetuid
 22014                              <1> 	; Arguments: -
 22015                              <1> 	;
 22016                              <1> 	; Inputs: -
 22017                              <1> 	; Outputs: (u.r0) - contains the real user's id.
 22018                              <1> 	; ...............................................................
 22019                              <1> 	;	
 22020                              <1> 	; Retro UNIX 8086 v1 modification: 
 22021                              <1> 	;       AL contains the real user ID at return.
 22022                              <1> 	;
 22023 000067ED 0FB605[A5850000]    <1> 	movzx 	eax, byte [u.ruid]
 22024 000067F4 A3[58850000]        <1> 	mov	[u.r0], eax
 22025                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
 22026 000067F9 E93FEDFFFF          <1> 	jmp	sysret
 22027                              <1> 		; br sysret4 / systerm return, sysret
 22028                              <1> 
 22029                              <1> anyi: 
 22030                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 22031                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
 22032                              <1> 	;
 22033                              <1> 	; 'anyi' is called if a file deleted while open.
 22034                              <1> 	; "anyi" checks to see if someone else has opened this file.
 22035                              <1> 	;
 22036                              <1> 	; INPUTS ->
 22037                              <1> 	;    r1 - contains an i-number
 22038                              <1> 	;    fsp - start of table containing open files
 22039                              <1> 	;
 22040                              <1> 	; OUTPUTS ->
 22041                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
 22042                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
 22043                              <1> 	;    if file not found - bit in i-node map is cleared
 22044                              <1> 	;    			 (i-node is freed)
 22045                              <1> 	;               all blocks related to i-node are freed
 22046                              <1> 	;	        all flags in i-node are cleared
 22047                              <1> 	; ((AX = R1)) input
 22048                              <1> 	;
 22049                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 22050                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 22051                              <1> 	;
 22052                              <1> 		; / r1 contains an i-number
 22053 000067FE BB[2C830000]        <1> 	mov	ebx, fsp
 22054                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
 22055                              <1> anyi_1: ; 1:
 22056 00006803 663B03              <1> 	cmp	ax, [ebx]
 22057                              <1> 		; cmp r1,(r2) / do i-numbers match?
 22058 00006806 7433                <1> 	je	short anyi_3
 22059                              <1> 		; beq 1f / yes, 1f
 22060 00006808 66F7D8              <1> 	neg	ax
 22061                              <1> 		; neg r1 / no complement r1
 22062 0000680B 663B03              <1> 	cmp	ax, [ebx]
 22063                              <1> 		; cmp r1,(r2) / do they match now?
 22064 0000680E 742B                <1> 	je	short anyi_3
 22065                              <1> 		; beq 1f / yes, transfer
 22066                              <1> 		; / i-numbers do not match
 22067 00006810 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
 22068                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
 22069                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
 22070 00006813 81FB[20850000]      <1> 	cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
 22071                              <1> 		; cmp r2,$fsp+[nfiles*8] 
 22072                              <1> 				; / are we at last entry in the table
 22073 00006819 72E8                <1> 	jb	short anyi_1
 22074                              <1> 		; blt 1b / no, check next entries i-number
 22075                              <1> 	;cmp	ax, 32768
 22076 0000681B 80FC80              <1> 	cmp	ah, 80h ; negative number check
 22077                              <1> 		; tst r1 / yes, no match
 22078                              <1> 		; bge .+4
 22079 0000681E 7203                <1> 	jb	short anyi_2
 22080 00006820 66F7D8              <1> 	neg	ax
 22081                              <1> 		; neg r1 / make i-number positive
 22082                              <1> anyi_2:	
 22083 00006823 E864020000          <1> 	call	imap
 22084                              <1> 		; jsr r0,imap / get address of allocation bit 
 22085                              <1> 			    ; / in the i-map in r2
 22086                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
 22087                              <1>         ;; eBX (R2) has address of the byte with allocation bit
 22088                              <1>  	; not	dx
 22089 00006828 F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
 22090                              <1>         ;and	[ebx], dx
 22091 0000682A 2013                <1> 	and 	[ebx], dl 
 22092                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
 22093 0000682C E850020000          <1> 	call	itrunc
 22094                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
 22095 00006831 66C705[2C820000]00- <1>  	mov 	word [i.flgs], 0
 22096 00006839 00                  <1>
 22097                              <1> 		; clr i.flgs / clear all flags in the i-node
 22098 0000683A C3                  <1> 	retn
 22099                              <1> 		;rts	r0 / return
 22100                              <1> anyi_3: ; 1: / i-numbers match
 22101 0000683B FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
 22102                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
 22103                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
 22104 0000683E C3                  <1> 	retn
 22105                              <1> 		; rts r0
 22106                              <1> 
 22107                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u7.s
 22108                              <1> ; Last Modification: 14/11/2015
 22109                              <1> 
 22110                              <1> sysmount: ; / mount file system; args special; name
 22111                              <1> 	; 14/11/2015
 22112                              <1> 	; 24/10/2015
 22113                              <1> 	; 13/10/2015
 22114                              <1> 	; 10/07/2015
 22115                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 22116                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 22117                              <1> 	;
 22118                              <1> 	; 'sysmount' anounces to the system that a removable 
 22119                              <1> 	; file system has been mounted on a special file.
 22120                              <1> 	; The device number of the special file is obtained via
 22121                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
 22122                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
 22123                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
 22124                              <1> 	; to read file system into core, i.e. the first block on the
 22125                              <1> 	; mountable file system is read in. This block is super block
 22126                              <1> 	; for the file system. This call is super user restricted.	
 22127                              <1> 	;
 22128                              <1> 	; Calling sequence:
 22129                              <1> 	;	sysmount; special; name
 22130                              <1> 	; Arguments:
 22131                              <1> 	;	special - pointer to name of special file (device)
 22132                              <1> 	;	name -  pointer to name of the root directory of the
 22133                              <1> 	;		newly mounted file system. 'name' should 
 22134                              <1> 	;		always be a directory.
 22135                              <1> 	; Inputs: - 
 22136                              <1> 	; Outputs: -
 22137                              <1> 	; ...............................................................
 22138                              <1> 	;				
 22139                              <1> 	; Retro UNIX 8086 v1 modification: 
 22140                              <1> 	;       'sysmount' system call has two arguments; so,
 22141                              <1> 	;	* 1st argument, special is pointed to by BX register
 22142                              <1> 	;	* 2nd argument, name is in CX register
 22143                              <1> 	;
 22144                              <1> 	;	NOTE: Device numbers, names and related procedures are 
 22145                              <1> 	;	       already modified for IBM PC compatibility and 
 22146                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
 22147                              <1> 	
 22148                              <1> 	;call	arg2
 22149                              <1> 		; jsr r0,arg2 / get arguments special and name
 22150 0000683F 891D[70850000]      <1> 	mov	[u.namep], ebx
 22151 00006845 51                  <1> 	push	ecx ; directory name
 22152 00006846 66833D[42850000]00  <1> 	cmp	word [mnti], 0
 22153                              <1> 		; tst mnti / is the i-number of the cross device file
 22154                              <1> 			 ; / zero?
 22155                              <1> 	;ja	error
 22156                              <1>         	; bne errora / no, error
 22157 0000684E 0F87E9000000        <1> 	ja	sysmnt_err0
 22158                              <1> 	;
 22159 00006854 E8CC000000          <1> 	call	getspl
 22160                              <1> 		; jsr r0,getspl / get special files device number in r1
 22161                              <1> 	; 13/10/2015
 22162 00006859 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
 22163 0000685C F683[FA750000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
 22164 00006863 750F                <1> 	jnz	short sysmnt_1
 22165                              <1> sysmnt_err1:
 22166 00006865 C705[AD850000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
 22167 0000686D 0000                <1>
 22168 0000686F E9A9ECFFFF          <1> 	jmp	error
 22169                              <1> sysmnt_1:
 22170 00006874 8F05[70850000]      <1> 	pop	dword [u.namep]
 22171                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
 22172                              <1> 				  ; / on the device
 22173                              <1> 	; 14/11/2015
 22174 0000687A 53                  <1> 	push	ebx ; 13/10/2015
 22175                              <1> 		; mov r1,-(sp) / save the device number
 22176                              <1>         ;
 22177 0000687B E859FBFFFF          <1> 	call	namei
 22178                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 22179                              <1> 		       ; ax = 0 -> file not found 	
 22180                              <1> 	;jz	error
 22181                              <1> 	;jc	error
 22182                              <1> 		; jsr r0,namei / get the i-number of the file
 22183                              <1>                	; br errora
 22184 00006880 730F                <1> 	jnc	short sysmnt_2
 22185                              <1> sysmnt_err2:
 22186 00006882 C705[AD850000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
 22187 0000688A 0000                <1>
 22188 0000688C E98CECFFFF          <1> 	jmp	error
 22189                              <1> sysmnt_2:	
 22190 00006891 66A3[42850000]      <1> 	mov	[mnti], ax
 22191                              <1>         	; mov r1,mnti / put it in mnti
 22192                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
 22193                              <1> sysmnt_3: ;1:
 22194                              <1>         ;cmp	byte [ebx+1], 0
 22195                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
 22196                              <1> 			   ; / dismountable device set?
 22197                              <1>         ;jna	short sysmnt_4		
 22198                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
 22199                              <1> 	;call	idle 	; (wait for hardware interrupt)
 22200                              <1> 	;jmp	short sysmnt_3
 22201                              <1> sysmnt_4:   
 22202 00006897 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
 22203 00006898 A2[3F850000]        <1> 	mov	[mdev], al
 22204                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
 22205 0000689D 8803                <1> 	mov	[ebx], al
 22206                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
 22207                              <1> 			      ; / of the I/O queue entry
 22208                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
 22209                              <1>         	; mov (sp)+,cdev / put device number in cdev
 22210 0000689F 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
 22211                              <1> 		; bis $2000,sb1 / set the read bit
 22212                              <1> 	; Retro UNIX 386 v1 modification : 
 22213                              <1> 	;	32 bit block number at buffer header offset 4
 22214 000068A4 C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
 22215 000068AB E8DD010000          <1> 	call 	diskio
 22216 000068B0 731C                <1> 	jnc	short sysmnt_5
 22217 000068B2 31C0                <1> 	xor 	eax, eax
 22218 000068B4 66A3[42850000]      <1> 	mov	[mnti], ax ; 0
 22219 000068BA A2[3F850000]        <1> 	mov	[mdev], al ; 0
 22220                              <1> 	;mov	[cdev], al ; 0
 22221                              <1> sysmnt_invd:
 22222                              <1> 	; 14/11/2015
 22223 000068BF FEC8                <1> 	dec 	al
 22224 000068C1 8903                <1> 	mov	[ebx], eax ; 000000FFh
 22225 000068C3 FEC0                <1> 	inc	al
 22226 000068C5 48                  <1> 	dec	eax
 22227 000068C6 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
 22228 000068C9 E94FECFFFF          <1> 	jmp	error
 22229                              <1> sysmnt_5:
 22230                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
 22231                              <1> 	; (Following check is needed to prevent mounting an
 22232                              <1> 	; in valid valid file system (in valid super block).
 22233                              <1> 	; 
 22234 000068CE 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
 22235 000068D1 C0E002              <1> 	shl	al, 2 ; 4*index
 22236 000068D4 8B88[DE750000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
 22237 000068DA C1E103              <1> 	shl 	ecx, 3
 22238 000068DD 0FB715[09900000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
 22239 000068E4 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
 22240                              <1> 			 ; (in sectors), if they are not equal
 22241                              <1> 			 ; the disk to be mounted is an...	
 22242 000068E6 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
 22243                              <1> 			 ; (which has not got a valid super block)
 22244                              <1> 	;
 22245 000068E8 C6430100            <1> 	mov	byte [ebx+1], 0
 22246                              <1> 	       	; jsr r0,ppoke / read in entire file system
 22247                              <1> ;sysmnt_6: ;1:
 22248                              <1> 	;;cmp	byte [sb1+1], 0
 22249                              <1> 		; tstb   sb1+1 / done reading?
 22250                              <1>    	;;jna	sysret
 22251                              <1> 	;;call	idle ; (wait for hardware interrupt)
 22252                              <1> 	;;jmp	short sysmnt_6
 22253                              <1> 		;bne 1b / no, wait
 22254                              <1>         	;br sysreta / yes
 22255 000068EC E94CECFFFF          <1> 	jmp	sysret
 22256                              <1> 
 22257                              <1> sysumount: ; / special dismount file system
 22258                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 22259                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 22260                              <1> 	;
 22261                              <1> 	; 04/11/2013
 22262                              <1> 	; 09/07/2013
 22263                              <1> 	; 'sysumount' anounces to the system that the special file, 
 22264                              <1> 	; indicated as an argument is no longer contain a removable
 22265                              <1> 	; file system. 'getspl' gets the device number of the special
 22266                              <1> 	; file. If no file system was mounted on that device an error
 22267                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
 22268                              <1> 	; to 'sysret'.
 22269                              <1> 	;
 22270                              <1> 	; Calling sequence:
 22271                              <1> 	;	sysmount; special
 22272                              <1> 	; Arguments:
 22273                              <1> 	;	special - special file to dismount (device)
 22274                              <1> 	;
 22275                              <1> 	; Inputs: - 
 22276                              <1> 	; Outputs: -
 22277                              <1> 	; ...............................................................
 22278                              <1> 	;				
 22279                              <1> 	; Retro UNIX 8086 v1 modification: 
 22280                              <1> 	;       'sysumount' system call has one argument; so,
 22281                              <1> 	;	* Single argument, special is pointed to by BX register
 22282                              <1> 	;
 22283                              <1> 	
 22284                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
 22285                              <1> 	;call	arg
 22286                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
 22287 000068F1 891D[70850000]      <1>         mov	[u.namep], ebx
 22288 000068F7 E829000000          <1> 	call	getspl
 22289                              <1> 		; jsr r0,getspl / get the device number in r1
 22290 000068FC 3A05[3F850000]      <1> 	cmp	al, [mdev]
 22291                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
 22292 00006902 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
 22293                              <1> 	;jne	error
 22294                              <1>         	; bne errora / no error
 22295 00006904 30C0                <1> 	xor	al, al ; ah = 0
 22296                              <1> sysumnt_0: ;1:
 22297 00006906 3805[06900000]      <1>      	cmp 	[sb1+1], al ; 0
 22298                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
 22299                              <1> 			   ; / (inhibit bit set)?
 22300 0000690C 7607                <1> 	jna	short sysumnt_1		
 22301                              <1> 		; bne 1b / yes, wait
 22302 0000690E E87B010000          <1> 	call	idle ; (wait for hardware interrupt)
 22303 00006913 EBF1                <1> 	jmp	short sysumnt_0
 22304                              <1> sysumnt_1:        
 22305 00006915 A2[3F850000]        <1> 	mov	[mdev], al
 22306                              <1> 	     	; clr mntd / no, clear these
 22307 0000691A 66A3[42850000]      <1>    	mov	[mnti], ax
 22308                              <1>         	; clr mnti
 22309 00006920 E918ECFFFF          <1>         jmp	sysret
 22310                              <1> 		; br sysreta / return
 22311                              <1> 
 22312                              <1> getspl: ; / get device number from a special file name
 22313 00006925 E8AFFAFFFF          <1> 	call	namei
 22314                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 22315                              <1> 		       ; ax = 0 -> file not found 	
 22316 0000692A 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
 22317                              <1> 	;jz	error
 22318                              <1> 	;jc	error
 22319                              <1> 		; jsr r0,namei / get the i-number of the special file
 22320                              <1>                 ; br errora / no such file
 22321 00006930 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
 22322                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
 22323                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
 22324 00006934 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
 22325                              <1> 	;jc	error
 22326                              <1> 		; ble errora / less than 0?  yes, error
 22327 00006936 6683F805            <1>         cmp	ax, 5 ;
 22328                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
 22329 0000693A 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
 22330                              <1> 	;ja	error
 22331                              <1>         	; bgt errora / yes, error
 22332                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
 22333                              <1> iopen_retn:
 22334 0000693C C3                  <1> 	retn
 22335                              <1> 		; rts    r0 / return with device number in r1
 22336                              <1> sysmnt_err0:
 22337 0000693D C705[AD850000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 22338 00006945 0000                <1>
 22339 00006947 E9D1EBFFFF          <1> 	jmp	error
 22340                              <1> 
 22341                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
 22342                              <1> ; Last Modification: 09/12/2015
 22343                              <1> 
 22344                              <1> syssleep:
 22345                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
 22346                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
 22347                              <1> 	;
 22348                              <1> 	; Retro UNIX 8086 v1 feature only
 22349                              <1> 	; (INPUT -> none)
 22350                              <1> 	;
 22351 0000694C 0FB61D[A7850000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 22352 00006953 8AA3[AB820000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 22353 00006959 E831010000          <1> 	call	sleep
 22354 0000695E E9DAEBFFFF          <1> 	jmp	sysret
 22355                              <1> 
 22356                              <1> vp_clr:
 22357                              <1> 	; Reset/Clear Video Page
 22358                              <1> 	;
 22359                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
 22360                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
 22361                              <1> 	;
 22362                              <1> 	; Retro UNIX 8086 v1 feature only !
 22363                              <1> 	;
 22364                              <1> 	; INPUTS -> 
 22365                              <1> 	;   BL = video page number	 
 22366                              <1> 	;
 22367                              <1> 	; OUTPUT ->
 22368                              <1> 	;   none
 22369                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
 22370                              <1> 	;
 22371                              <1> 	; 04/12/2013
 22372 00006963 28C0                <1> 	sub	al, al
 22373                              <1> 	; al = 0 (clear video page)
 22374                              <1> 	; bl = video page
 22375 00006965 B407                <1> 	mov	ah, 07h
 22376                              <1> 	; ah = 7 (attribute/color)
 22377 00006967 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
 22378 0000696A 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
 22379 0000696E E80CADFFFF          <1> 	call	_scroll_up
 22380                              <1> 	; bl = video page
 22381 00006973 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
 22382 00006976 E942AFFFFF          <1> 	jmp 	_set_cpos
 22383                              <1> 
 22384                              <1> sysmsg:
 22385                              <1> 	; 11/11/2015
 22386                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
 22387                              <1> 	; Print user-application message on user's console tty
 22388                              <1> 	;
 22389                              <1> 	; Input -> EBX = Message address
 22390                              <1> 	;	   ECX = Message length (max. 255)
 22391                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
 22392                              <1> 	;
 22393 0000697B 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
 22394 00006981 0F87B6EBFFFF        <1> 	ja	sysret ; nothing to do with big message size
 22395 00006987 08C9                <1> 	or	cl, cl
 22396 00006989 0F84AEEBFFFF        <1> 	jz	sysret
 22397 0000698F 20D2                <1> 	and	dl, dl
 22398 00006991 7502                <1> 	jnz	short sysmsg0
 22399 00006993 B207                <1> 	mov	dl, 07h ; default color
 22400                              <1> 		; (black background, light gray character) 
 22401                              <1> sysmsg0:
 22402 00006995 891D[78850000]      <1> 	mov	[u.base], ebx
 22403 0000699B 8815[F9780000]      <1> 	mov	[ccolor], dl ; color attributes
 22404 000069A1 89E5                <1> 	mov	ebp, esp
 22405 000069A3 31DB                <1> 	xor	ebx, ebx ; 0
 22406 000069A5 891D[80850000]      <1> 	mov	[u.nread], ebx ; 0
 22407                              <1> 	;
 22408 000069AB 381D[BF850000]      <1> 	cmp	[u.kcall], bl ; 0
 22409 000069B1 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
 22410                              <1> 	;
 22411 000069B3 890D[7C850000]      <1> 	mov	[u.count], ecx
 22412 000069B9 41                  <1> 	inc	ecx ; + 00h ; ASCIZZ
 22413 000069BA 29CC                <1> 	sub	esp, ecx
 22414 000069BC 89E7                <1> 	mov	edi, esp
 22415 000069BE 89E6                <1> 	mov	esi, esp
 22416 000069C0 66891D[BD850000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
 22417                              <1> 	; 11/11/2015
 22418 000069C7 8A25[88850000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
 22419                              <1> 	; 0 = none
 22420 000069CD FECC                <1> 	dec	ah
 22421 000069CF 790C                <1> 	jns	short sysmsg1 
 22422 000069D1 8A1D[A7850000]      <1> 	mov	bl, [u.uno] ; process number	
 22423 000069D7 8AA3[AB820000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
 22424                              <1> sysmsg1:
 22425 000069DD 8825[AC850000]      <1> 	mov	[u.ttyn], ah
 22426                              <1> sysmsg2:
 22427 000069E3 E8A0000000          <1> 	call	cpass
 22428 000069E8 7416                <1> 	jz	short sysmsg5
 22429 000069EA AA                  <1> 	stosb
 22430 000069EB 20C0                <1> 	and	al, al
 22431 000069ED 75F4                <1> 	jnz	short sysmsg2
 22432                              <1> sysmsg3:
 22433 000069EF 80FC07              <1> 	cmp	ah, 7 ; tty number
 22434 000069F2 7711                <1> 	ja	short sysmsg6 ; serial port
 22435 000069F4 E83E000000          <1> 	call	print_cmsg
 22436                              <1> sysmsg4:
 22437 000069F9 89EC                <1> 	mov	esp, ebp	
 22438 000069FB E93DEBFFFF          <1> 	jmp	sysret
 22439                              <1> sysmsg5:
 22440 00006A00 C60700              <1> 	mov	byte [edi], 0
 22441 00006A03 EBEA                <1> 	jmp	short sysmsg3
 22442                              <1> sysmsg6:
 22443 00006A05 8A06                <1> 	mov	al, [esi]
 22444 00006A07 E87A000000          <1> 	call	sndc
 22445 00006A0C 72EB                <1> 	jc	short sysmsg4
 22446 00006A0E 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
 22447 00006A11 76E6                <1> 	jna	short sysmsg4
 22448 00006A13 46                  <1> 	inc 	esi
 22449 00006A14 8A25[AC850000]      <1> 	mov	ah, [u.ttyn]
 22450 00006A1A EBE9                <1> 	jmp	short sysmsg6
 22451                              <1> 
 22452                              <1> sysmsgk: ; Temporary (01/07/2015)
 22453                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
 22454                              <1> 	; (ECX -character count- will not be considered)
 22455 00006A1C 8B35[78850000]      <1> 	mov	esi, [u.base]
 22456 00006A22 8A25[F8780000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
 22457 00006A28 8825[AC850000]      <1> 	mov	[u.ttyn], ah
 22458 00006A2E C605[BF850000]00    <1> 	mov	byte [u.kcall], 0
 22459 00006A35 EBB8                <1> 	jmp	short sysmsg3
 22460                              <1> 	
 22461                              <1> 
 22462                              <1> print_cmsg: 
 22463                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
 22464                              <1> 	;
 22465                              <1> 	; print message (on user's console tty) 
 22466                              <1> 	;	with requested color
 22467                              <1> 	;
 22468                              <1> 	; INPUTS:
 22469                              <1> 	;	esi = message address
 22470                              <1> 	;	[u.ttyn] = tty number (0 to 7)
 22471                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
 22472                              <1> 	;
 22473 00006A37 AC                  <1> 	lodsb
 22474                              <1> pcmsg1:
 22475 00006A38 56                  <1> 	push 	esi
 22476 00006A39 0FB61D[AC850000]    <1>         movzx   ebx, byte [u.ttyn]
 22477 00006A40 8A25[F9780000]      <1> 	mov	ah, [ccolor]
 22478 00006A46 E8DEADFFFF          <1> 	call 	WRITE_TTY
 22479 00006A4B 5E                  <1> 	pop	esi
 22480 00006A4C AC                  <1> 	lodsb
 22481 00006A4D 20C0                <1> 	and 	al, al  ; 0
 22482 00006A4F 75E7                <1> 	jnz 	short pcmsg1
 22483 00006A51 C3                  <1> 	retn
 22484                              <1> 
 22485                              <1> sysgeterr:
 22486                              <1> 	; 09/12/2015
 22487                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
 22488                              <1> 	; Get last error number or page fault count
 22489                              <1> 	; (for debugging)
 22490                              <1> 	;
 22491                              <1> 	; Input -> EBX = return type
 22492                              <1> 	;	   0 = last error code (which is in 'u.error')	
 22493                              <1> 	;	   FFFFFFFFh = page fault count for running process
 22494                              <1> 	;	   FFFFFFFEh = total page fault count
 22495                              <1> 	;	   1 .. FFFFFFFDh = undefined 
 22496                              <1> 	;
 22497                              <1> 	; Output -> EAX = last error number or page fault count
 22498                              <1> 	;	   (depending on EBX input)
 22499                              <1> 	; 	
 22500 00006A52 21DB                <1> 	and 	ebx, ebx
 22501 00006A54 750B                <1> 	jnz	short glerr_2
 22502                              <1> glerr_0:
 22503 00006A56 A1[AD850000]        <1> 	mov	eax, [u.error]
 22504                              <1> glerr_1:
 22505 00006A5B A3[58850000]        <1> 	mov	[u.r0], eax
 22506 00006A60 C3                  <1>  	retn
 22507                              <1> glerr_2:
 22508 00006A61 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
 22509 00006A62 74FD                <1> 	jz	short glerr_2 ; page fault count for process
 22510 00006A64 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
 22511 00006A65 75EF                <1> 	jnz	short glerr_0
 22512 00006A67 A1[2C920000]        <1> 	mov	eax, [PF_Count] ; total page fault count
 22513 00006A6C EBED                <1>         jmp     short glerr_1
 22514                              <1> glerr_3:
 22515 00006A6E A1[C1850000]        <1> 	mov 	eax, [u.pfcount]
 22516 00006A73 EBE6                <1> 	jmp	short glerr_1
 22517                              <1> 
 22518                              <1> ; temporary - 24/01/2016
 22519                              <1> 
 22520                              <1> iget:
 22521 00006A75 C3                  <1> 	retn
 22522                              <1> poke:
 22523 00006A76 C3                  <1> 	retn
 22524                              <1> tswap:
 22525 00006A77 C3                  <1> 	retn
 22526                              <1> isintr:
 22527 00006A78 C3                  <1> 	retn
 22528                              <1> writei:
 22529 00006A79 C3                  <1> 	retn
 22530                              <1> readi:
 22531 00006A7A C3                  <1> 	retn
 22532                              <1> putlu:
 22533 00006A7B C3                  <1> 	retn
 22534                              <1> swap:
 22535 00006A7C C3                  <1> 	retn
 22536                              <1> wswap:
 22537 00006A7D C3                  <1> 	retn
 22538                              <1> rswap:
 22539 00006A7E C3                  <1> 	retn
 22540                              <1> iopen:
 22541 00006A7F C3                  <1> 	retn
 22542                              <1> iclose:
 22543 00006A80 C3                  <1> 	retn
 22544                              <1> itrunc:
 22545 00006A81 C3                  <1> 	retn
 22546                              <1> clock:
 22547 00006A82 C3                  <1> 	retn
 22548                              <1> setimod:
 22549 00006A83 C3                  <1> 	retn
 22550                              <1> ottyp:
 22551 00006A84 C3                  <1> 	retn
 22552                              <1> cttyp:
 22553 00006A85 C3                  <1> 	retn
 22554                              <1> sndc:
 22555 00006A86 C3                  <1> 	retn
 22556                              <1> access:
 22557 00006A87 C3                  <1> 	retn
 22558                              <1> cpass:
 22559 00006A88 C3                  <1> 	retn
 22560                              <1> passc:
 22561 00006A89 C3                  <1> 	retn
 22562                              <1> epoch:
 22563 00006A8A C3                  <1> 	retn
 22564                              <1> set_date_time:
 22565 00006A8B C3                  <1> 	retn
 22566                              <1> imap:
 22567 00006A8C C3                  <1> 	retn
 22568                              <1> diskio:
 22569 00006A8D C3                  <1> 	retn
 22570                              <1> idle:
 22571 00006A8E C3                  <1> 	retn
 22572                              <1> sleep:
 22573 00006A8F C3                  <1> 	retn
 22574                              <1> 
 22575                              <1> 
 22576                              <1> 
 22577                                  %include 'trdosk7.s' ; 24/01/2016
 22578                              <1> ; ****************************************************************************
 22579                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - DISK READ&WRITE : trdosk7.s
 22580                              <1> ; ----------------------------------------------------------------------------
 22581                              <1> ; Last Update: 31/01/2016
 22582                              <1> ; ----------------------------------------------------------------------------
 22583                              <1> ; Beginning: 24/01/2016
 22584                              <1> ; ----------------------------------------------------------------------------
 22585                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 22586                              <1> ; ----------------------------------------------------------------------------
 22587                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 22588                              <1> ; DISK_IO.ASM (20/07/2011)
 22589                              <1> ; ****************************************************************************
 22590                              <1> ; DISK_IO.ASM (c) 2009-2011 Erdogan TAN [ 04/07/2009 ] Last Update: 20/07/2011
 22591                              <1> 
 22592                              <1> disk_read:
 22593                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
 22594                              <1> 	; 17/10/2010
 22595                              <1> 	; 18/04/2010
 22596                              <1> 	;
 22597                              <1> 	; INPUT -> EAX = Logical Block Address
 22598                              <1> 	;	   ESI = Logical Dos Disk Table Offset (DRV)	
 22599                              <1> 	;	   ECX = Sector Count	
 22600                              <1> 	; 	   EBX = Destination Buffer
 22601                              <1> 	; OUTPUT -> 
 22602                              <1> 	;	   cf = 0 or cf = 1
 22603                              <1> 	; (Modified registers: EAX, EBX, ECX)
 22604                              <1> 
 22605 00006A90 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
 22606 00006A94 7761                <1> 	ja	short lba_read
 22607                              <1> 
 22608                              <1> chs_read:
 22609                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
 22610                              <1> 	; 20/07/2011
 22611                              <1> 	; 04/07/2009
 22612                              <1> 	;
 22613                              <1> 	; INPUT -> EAX = Logical Block Address
 22614                              <1> 	;	   ECX = Number of sectors to read
 22615                              <1> 	; 	   ESI = Logical Dos Disk Table Offset (DRV)
 22616                              <1> 	; 	   EBX = Destination Buffer
 22617                              <1> 	; OUTPUT -> 
 22618                              <1> 	;	   cf = 0 or cf = 1
 22619                              <1> 	; (Modified registers: EAX; EBX, ECX, EDX)
 22620                              <1> 
 22621                              <1> chs_read_next_sector:
 22622 00006A96 C605[25820000]04    <1> 	mov	byte [retry_count], 4
 22623                              <1>               
 22624                              <1> chs_read_retry:
 22625 00006A9D 50                  <1> 	push	eax			; Linear sector #
 22626 00006A9E 51                  <1> 	push	ecx			; # of FAT/FILE/DIR sectors
 22627                              <1>                 
 22628 00006A9F 0FB74E1E            <1> 	movzx	ecx, word [esi+LD_BPB+SecPerTrack]
 22629 00006AA3 29D2                <1> 	sub	edx, edx
 22630 00006AA5 F7F1                <1> 	div	ecx
 22631                              <1> 	; eax = track, dx (dl ) = sector (on track)
 22632 00006AA7 6689D1              <1> 	mov	cx, dx			; Sector (zero based)
 22633 00006AAA 6641                <1> 	inc	cx			; To make it 1 based
 22634 00006AAC 6651                <1> 	push	cx
 22635 00006AAE 668B4E20            <1> 	mov	cx, word [esi+LD_BPB+Heads]
 22636 00006AB2 6629D2              <1> 	sub	dx, dx
 22637 00006AB5 F7F1                <1> 	div	ecx			; Convert track to head & cyl
 22638                              <1> 	; eax (ax) = cylinder, dx (dl) = head (max. FFh)
 22639 00006AB7 88D6                <1> 	mov	dh, dl
 22640 00006AB9 6659                <1> 	pop	cx			; AX=Cyl, DH=Head, CX=Sector
 22641 00006ABB 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
 22642                              <1> 
 22643 00006ABE 88C5                <1> 	mov	ch, al			; NOTE: max. 1023 cylinders !                   
 22644 00006AC0 C0CC02              <1> 	ror	ah, 2			; Rotate 2 bits right
 22645 00006AC3 08E1                <1> 	or	cl, ah                   
 22646 00006AC5 66B80102            <1> 	mov	ax, 0201h
 22647 00006AC9 E86FBEFFFF          <1> 	call	int13h			; BIOS Service func ( ah ) = 2
 22648                              <1>                                         ; Read disk sectors
 22649                              <1>                                         ; AL-sec num CH-track CL-sec
 22650                              <1>                                         ; DH-head DL-drive ES:BX-buffer
 22651                              <1>                                         ; CF-flag AH-stat AL-sec read
 22652                              <1> 	                                ; If CF = 1 then (If AH > 0)
 22653 00006ACE 8825[26820000]      <1> 	mov	[disk_rw_err], ah
 22654                              <1> 	
 22655 00006AD4 59                  <1> 	pop	ecx
 22656 00006AD5 58                  <1> 	pop	eax
 22657 00006AD6 7314                <1> 	jnc	short chs_read_ok
 22658                              <1> 
 22659 00006AD8 803D[26820000]09    <1> 	cmp	byte [disk_rw_err], 09h ; DMA crossed 64K segment boundary
 22660 00006ADF 7408                <1> 	je	short chs_read_error_retn
 22661                              <1>              
 22662 00006AE1 FE0D[25820000]      <1> 	dec	byte [retry_count]
 22663 00006AE7 75B4                <1> 	jnz	short chs_read_retry
 22664                              <1> 
 22665                              <1> chs_read_error_retn:
 22666 00006AE9 F9                  <1> 	stc
 22667                              <1> 	;retn
 22668 00006AEA EB51                <1> 	jmp	short update_drv_error_byte
 22669                              <1> 
 22670                              <1> chs_read_ok:
 22671 00006AEC 40                  <1> 	inc	eax
 22672 00006AED 81C300020000        <1> 	add	ebx, 512
 22673 00006AF3 E2A1                <1> 	loop	chs_read_next_sector
 22674                              <1> 	;retn
 22675 00006AF5 EB46                <1> 	jmp 	short update_drv_error_byte
 22676                              <1> 
 22677                              <1> lba_read:
 22678                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
 22679                              <1> 	; 10/07/2015 (Retro UNIX 386 v1)
 22680                              <1> 	;
 22681                              <1> 	; INPUT -> EAX = Logical Block Address
 22682                              <1> 	;	   ESI = Logical Dos Disk Table Offset (DRV)	
 22683                              <1> 	;	   ECX = Sector Count	
 22684                              <1> 	; 	   EBX = Destination Buffer
 22685                              <1> 	; OUTPUT -> 
 22686                              <1> 	;	   cf = 0 or cf = 1
 22687                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
 22688                              <1> 
 22689                              <1> 	; LBA read/write (with private LBA function) 
 22690                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 22691                              <1> 
 22692 00006AF7 57                  <1> 	push	edi
 22693                              <1> 
 22694 00006AF8 890D[27820000]      <1> 	mov	[sector_count], ecx ; total sector (read) count
 22695                              <1> 
 22696 00006AFE 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
 22697                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
 22698                              <1> 
 22699                              <1> lba_read_next:
 22700 00006B01 81F9FF000000        <1> 	cmp	ecx, 255
 22701 00006B07 7604                <1> 	jna	short lba_read_rsc
 22702                              <1> 	;mov	ecx, 255
 22703 00006B09 31C9                <1> 	xor	ecx, ecx
 22704 00006B0B FEC9                <1> 	dec	cl
 22705                              <1> lba_read_rsc:
 22706 00006B0D 290D[27820000]      <1> 	sub	[sector_count], ecx ; remain sectors
 22707 00006B13 89CF                <1> 	mov	edi, ecx 
 22708                              <1> 
 22709 00006B15 91                  <1> 	xchg	eax, ecx
 22710                              <1> 
 22711 00006B16 C605[25820000]04    <1> 	mov	byte [retry_count], 4
 22712                              <1> 
 22713                              <1> 	; ecx = sector number
 22714                              <1> 	; al = sector count (1 - 255)
 22715                              <1> 	; dl = drive number
 22716                              <1> lba_read_retry:
 22717                              <1> 	; Function 1Bh = LBA read, 1Ch = LBA write
 22718 00006B1D B41B                <1> 	mov	ah, 1Bh ; LBA read
 22719 00006B1F E819BEFFFF          <1> 	call	int13h
 22720 00006B24 8825[26820000]      <1> 	mov	[disk_rw_err], ah
 22721 00006B2A 7334                <1> 	jnc	short lba_read_ok
 22722 00006B2C 80FC80              <1> 	cmp	ah, 80h ; time out?
 22723 00006B2F 740A                <1>         je      short lba_read_stc_retn
 22724 00006B31 FE0D[25820000]      <1> 	dec	byte [retry_count]
 22725 00006B37 7FE4                <1> 	jg	short lba_read_retry
 22726 00006B39 743A                <1> 	jz	short lba_read_reset
 22727                              <1> 	; sf =  1
 22728                              <1> 
 22729                              <1> lba_read_stc_retn:
 22730 00006B3B F9                  <1> 	stc
 22731                              <1> lba_read_retn:
 22732 00006B3C 5F                  <1> 	pop	edi
 22733                              <1> 
 22734                              <1> update_drv_error_byte:
 22735 00006B3D 9C                  <1> 	pushf
 22736 00006B3E 53                  <1> 	push	ebx
 22737 00006B3F 6651                <1> 	push	cx
 22738                              <1> 	;or	ecx, ecx
 22739                              <1> 	;jz	short udrv_errb0
 22740 00006B41 8A0D[26820000]      <1> 	mov	cl, [disk_rw_err]
 22741                              <1> udrv_errb0:
 22742 00006B47 0FB65E02            <1> 	movzx	ebx, byte [esi+LD_PhyDrvNo]
 22743 00006B4B 80FB02              <1> 	cmp	bl, 2
 22744 00006B4E 7203                <1>         jb      short udrv_errb1
 22745 00006B50 80EB7E              <1> 	sub	bl, 7Eh
 22746                              <1> 	;cmp	bl, 5
 22747                              <1> 	;ja	short udrv_errb2	
 22748                              <1> udrv_errb1:
 22749 00006B53 031D[01760000]      <1>         add     ebx, [drv.error]
 22750 00006B59 880B                <1> 	mov	[ebx], cl ; error code
 22751                              <1> udrv_errb2:
 22752 00006B5B 6659                <1> 	pop	cx
 22753 00006B5D 5B                  <1> 	pop	ebx
 22754 00006B5E 9D                  <1> 	popf
 22755 00006B5F C3                  <1> 	retn
 22756                              <1> 
 22757                              <1> lba_read_ok:
 22758 00006B60 89C8                <1> 	mov	eax, ecx ; sector number
 22759 00006B62 01F8                <1> 	add	eax, edi ; sector number (next)
 22760 00006B64 C1E709              <1> 	shl	edi, 9 ; sector count * 512
 22761 00006B67 01FB                <1> 	add	ebx, edi ; next buffer offset
 22762                              <1> 
 22763 00006B69 8B0D[27820000]      <1> 	mov	ecx, [sector_count] ; remaining sectors
 22764 00006B6F 09C9                <1> 	or	ecx, ecx
 22765 00006B71 758E                <1> 	jnz	short lba_read_next
 22766 00006B73 EBC7                <1> 	jmp	short lba_read_retn
 22767                              <1> 
 22768                              <1> lba_read_reset:
 22769 00006B75 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 22770 00006B77 E8C1BDFFFF          <1>         call	int13h
 22771 00006B7C 739F                <1> 	jnc	short  lba_read_retry
 22772 00006B7E EBBC                <1> 	jmp	short lba_read_retn
 22773                                  %include 'trdosk8.s' ; 24/01/2016
 22774                              <1> ; ****************************************************************************
 22775                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk8.s
 22776                              <1> ; ----------------------------------------------------------------------------
 22777                              <1> ; Last Update: 24/01/2016
 22778                              <1> ; ----------------------------------------------------------------------------
 22779                              <1> ; Beginning: 24/01/2016
 22780                              <1> ; ----------------------------------------------------------------------------
 22781                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 22782                              <1> ; ----------------------------------------------------------------------------
 22783                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 22784                              <1> ; XXXXXXXX.ASM (XX/XX/2011)
 22785                              <1> ;
 22786                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 22787                              <1> ; u0.s (20/11/2015)
 22788                              <1> ; ****************************************************************************
 22789                              <1> 
 22790                              <1> INT4Ah:
 22791                              <1> 	; 24/01/2016
 22792                              <1> 	; this procedure will be called by 'RTC_INT' (in 'timer.s')
 22793 00006B80 C3                  <1> 	retn
 22794                              <1> 
 22795                              <1> ; u0.s
 22796                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
 22797                              <1> ; Last Modification: 20/11/2015
 22798                              <1> 
 22799                              <1> com2_int:
 22800                              <1> 	; 07/11/2015 
 22801                              <1> 	; 24/10/2015
 22802                              <1> 	; 23/10/2015
 22803                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 22804                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 22805                              <1> 	; < serial port 2 interrupt handler >
 22806                              <1> 	;
 22807 00006B81 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 22808                              <1> 	;push	eax
 22809 00006B84 66B80900            <1> 	mov	ax, 9
 22810 00006B88 EB07                <1> 	jmp	short comm_int
 22811                              <1> com1_int:
 22812                              <1> 	; 07/11/2015
 22813                              <1> 	; 24/10/2015
 22814 00006B8A 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 22815                              <1> 	; 23/10/2015
 22816                              <1> 	;push	eax
 22817 00006B8D 66B80800            <1> 	mov	ax, 8
 22818                              <1> comm_int:
 22819                              <1> 	; 20/11/2015
 22820                              <1> 	; 18/11/2015
 22821                              <1> 	; 17/11/2015
 22822                              <1> 	; 16/11/2015
 22823                              <1> 	; 09/11/2015
 22824                              <1> 	; 08/11/2015
 22825                              <1> 	; 07/11/2015
 22826                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
 22827                              <1> 	; 01/11/2015
 22828                              <1> 	; 26/10/2015
 22829                              <1> 	; 23/10/2015
 22830 00006B91 53                  <1> 	push	ebx
 22831 00006B92 56                  <1> 	push	esi
 22832 00006B93 57                  <1> 	push	edi
 22833 00006B94 1E                  <1> 	push 	ds
 22834 00006B95 06                  <1> 	push 	es
 22835                              <1> 	; 18/11/2015
 22836 00006B96 0F20DB              <1> 	mov	ebx, cr3
 22837 00006B99 53                  <1> 	push	ebx ; ****
 22838                              <1> 	;
 22839 00006B9A 51                  <1> 	push	ecx ; ***
 22840 00006B9B 52                  <1> 	push	edx ; **
 22841                              <1> 	;
 22842 00006B9C BB10000000          <1> 	mov	ebx, KDATA
 22843 00006BA1 8EDB                <1> 	mov	ds, bx
 22844 00006BA3 8EC3                <1> 	mov	es, bx
 22845                              <1> 	;
 22846 00006BA5 8B0D[C8780000]      <1> 	mov	ecx, [k_page_dir]
 22847 00006BAB 0F22D9              <1> 	mov	cr3, ecx
 22848                              <1> 	; 20/11/2015
 22849                              <1> 	; Interrupt identification register
 22850 00006BAE 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
 22851                              <1> 	;
 22852 00006BB2 3C08                <1> 	cmp 	al, 8 
 22853 00006BB4 7702                <1> 	ja 	short com_i0
 22854                              <1> 	;
 22855                              <1> 	; 20/11/2015
 22856                              <1> 	; 17/11/2015
 22857                              <1> 	; 16/11/2015
 22858                              <1> 	; 15/11/2015
 22859                              <1> 	; 24/10/2015
 22860                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 22861                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 22862                              <1> 	; < serial port 1 interrupt handler >
 22863                              <1> 	;
 22864 00006BB6 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
 22865                              <1> com_i0:
 22866                              <1> 	;push	eax ; *
 22867                              <1> 	; 07/11/2015
 22868 00006BB8 A2[38790000]        <1> 	mov 	byte [ccomport], al
 22869                              <1> 	; 09/11/2015
 22870 00006BBD 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
 22871                              <1> 	; 17/11/2015
 22872                              <1>  	; reset request for response status
 22873 00006BC0 88A3[2E790000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
 22874                              <1> 	;
 22875                              <1> 	; 20/11/2015
 22876 00006BC6 EC                  <1> 	in	al, dx		; read interrupt id. register
 22877 00006BC7 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 22878 00006BC9 2404                <1> 	and	al, 4		; received data available?	
 22879 00006BCB 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
 22880                              <1> 	;
 22881                              <1> 	; 20/11/2015
 22882 00006BCD 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
 22883 00006BD0 EC                  <1> 	in	al, dx     	; read character
 22884                              <1> 	;JMP	$+2	   	; I/O DELAY
 22885                              <1> 	; 08/11/2015
 22886                              <1> 	; 07/11/2015
 22887 00006BD1 89DE                <1> 	mov	esi, ebx 
 22888 00006BD3 89DF                <1> 	mov	edi, ebx
 22889 00006BD5 81C6[32790000]      <1> 	add 	esi, rchar - 8 ; points to last received char
 22890 00006BDB 81C7[34790000]      <1> 	add	edi, schar - 8 ; points to last sent char
 22891 00006BE1 8806                <1> 	mov	[esi], al ; received char (current char)
 22892                              <1> 	; query
 22893 00006BE3 20C0                <1> 	and	al, al
 22894 00006BE5 7527                <1> 	jnz	short com_i2
 22895                              <1>    	; response
 22896                              <1> 	; 17/11/2015
 22897                              <1> 	; set request for response status
 22898 00006BE7 FE83[2E790000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
 22899                              <1> 	;
 22900 00006BED 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
 22901 00006BF1 EC                  <1> 	in	al, dx	   	; read line status register 
 22902 00006BF2 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 22903 00006BF4 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
 22904 00006BF6 7445                <1> 	jz	short com_eoi 	; no
 22905 00006BF8 B0FF                <1> 	mov 	al, 0FFh   	; response			
 22906 00006BFA 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
 22907 00006BFE EE                  <1> 	out	dx, al	   	; send on serial port
 22908                              <1> 	; 17/11/2015
 22909 00006BFF 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
 22910 00006C02 7502                <1> 	jne 	short com_i1    ; no
 22911 00006C04 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
 22912                              <1> com_i1:
 22913                              <1> 	; 17/11/2015
 22914                              <1> 	; reset request for response status (again)
 22915 00006C06 FE8B[2E790000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
 22916 00006C0C EB2F                <1> 	jmp	short com_eoi
 22917                              <1> com_i2:	
 22918                              <1> 	; 08/11/2015
 22919 00006C0E 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
 22920 00006C10 7417                <1> 	je	short com_i3	; (check for response signal)
 22921                              <1> 	; 07/11/2015
 22922 00006C12 3C04                <1> 	cmp	al, 04h	; EOT
 22923 00006C14 751C                <1> 	jne	short com_i4	
 22924                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
 22925                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
 22926                              <1> 	; 08/11/2015
 22927                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
 22928 00006C16 861D[F8780000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
 22929 00006C1C E8FBD0FFFF          <1> 	call 	ctrlbrk
 22930 00006C21 861D[F8780000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
 22931                              <1> 	;mov	al, 04h ; EOT
 22932                              <1> 	; 08/11/2015
 22933 00006C27 EB09                <1> 	jmp	short com_i4	
 22934                              <1> com_i3:
 22935                              <1> 	; 08/11/2015
 22936                              <1> 	; If 0FFh has been received just after a query
 22937                              <1> 	; (schar, ZERO), it is a response signal.
 22938                              <1> 	; 17/11/2015
 22939 00006C29 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
 22940 00006C2C 7704                <1> 	ja	short com_i4 ; no
 22941                              <1> 	; reset query status (schar)
 22942 00006C2E 8807                <1> 	mov	[edi], al ; 0FFh
 22943 00006C30 FEC0                <1> 	inc	al ; 0
 22944                              <1> com_i4:
 22945                              <1> 	; 27/07/2014
 22946                              <1> 	; 09/07/2014
 22947 00006C32 D0E3                <1> 	shl	bl, 1	
 22948 00006C34 81C3[FA780000]      <1> 	add	ebx, ttychr
 22949                              <1> 	; 23/07/2014 (always overwrite)
 22950                              <1> 	;;cmp	word [ebx], 0
 22951                              <1> 	;;ja	short com_eoi
 22952                              <1> 	;
 22953 00006C3A 668903              <1> 	mov	[ebx], ax   ; Save ascii code
 22954                              <1> 			    ; scan code = 0
 22955                              <1> com_eoi:
 22956                              <1> 	;mov	al, 20h
 22957                              <1> 	;out	20h, al	   ; end of interrupt
 22958                              <1> 	;
 22959                              <1> 	; 07/11/2015
 22960                              <1>       	;pop	eax ; *
 22961 00006C3D A0[38790000]        <1> 	mov	al, byte [ccomport] ; current COM port
 22962                              <1> 	 ; al = tty number (8 or 9)
 22963 00006C42 E85E010000          <1>         call	wakeup
 22964                              <1> com_iret:
 22965                              <1> 	; 23/10/2015
 22966 00006C47 5A                  <1> 	pop	edx ; **
 22967 00006C48 59                  <1> 	pop	ecx ; ***
 22968                              <1> 	; 18/11/2015
 22969                              <1> 	;pop	eax ; ****
 22970                              <1> 	;mov	cr3, eax
 22971                              <1> 	;jmp	iiret
 22972 00006C49 E9809EFFFF          <1> 	jmp	iiretp
 22973                              <1> 
 22974                              <1> ;iiretp: ; 01/09/2015
 22975                              <1> ;	; 28/08/2015
 22976                              <1> ;	pop	eax ; (*) page directory
 22977                              <1> ;	mov	cr3, eax
 22978                              <1> ;iiret:
 22979                              <1> ;	; 22/08/2014
 22980                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
 22981                              <1> ;	out	20h, al	; 8259 PORT
 22982                              <1> ;	;
 22983                              <1> ;	pop	es
 22984                              <1> ;	pop	ds
 22985                              <1> ;	pop	edi
 22986                              <1> ;	pop	esi
 22987                              <1> ;	pop	ebx ; 29/08/2014
 22988                              <1> ;	pop 	eax
 22989                              <1> ;	iretd
 22990                              <1> 
 22991                              <1> sp_init:
 22992                              <1> 	; 07/11/2015
 22993                              <1> 	; 29/10/2015
 22994                              <1> 	; 26/10/2015
 22995                              <1> 	; 23/10/2015
 22996                              <1> 	; 29/06/2015
 22997                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
 22998                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
 22999                              <1> 	; Initialization of Serial Port Communication Parameters
 23000                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 23001                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 23002                              <1> 	;
 23003                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 23004                              <1> 	;
 23005                              <1> 	; INPUT:  (29/06/2015)
 23006                              <1> 	;	AL = 0 for COM1
 23007                              <1> 	;	     1 for COM2
 23008                              <1> 	;	AH = Communication parameters	
 23009                              <1> 	;
 23010                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 23011                              <1> 	;	Bit	4	3	2	1	0
 23012                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 23013                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 23014                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 23015                              <1> 	;		11 = even
 23016                              <1> 	;  Baud rate setting bits: (29/06/2015)
 23017                              <1> 	;		Retro UNIX 386 v1 feature only !
 23018                              <1> 	;	Bit	7    6    5  | Baud rate
 23019                              <1> 	;		------------------------
 23020                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 23021                              <1> 	;		0    0    1  | 9600 (12)
 23022                              <1> 	;		0    1    0  | 19200 (6) 
 23023                              <1> 	;		0    1	  1  | 38400 (3) 
 23024                              <1> 	;		1    0	  0  | 14400 (8)
 23025                              <1> 	;		1    0	  1  | 28800 (4)
 23026                              <1> 	;		1    1    0  | 57600 (2)
 23027                              <1> 	;		1    1    1  | 115200 (1) 	
 23028                              <1> 	
 23029                              <1> 	; References:	
 23030                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
 23031                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
 23032                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
 23033                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
 23034                              <1> 	;
 23035                              <1> 	; Set communication parameters for COM1 (= 03h)	
 23036                              <1> 	;
 23037 00006C4E BB[34790000]        <1> 	mov	ebx, com1p		; COM1 parameters  
 23038 00006C53 66BAF803            <1> 	mov	dx, 3F8h		; COM1
 23039                              <1> 	 ; 29/10/2015
 23040 00006C57 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 23041 00006C5B E86F000000          <1> 	call	sp_i3	; call A4	
 23042 00006C60 A880                <1> 	test	al, 80h
 23043 00006C62 7410                <1> 	jz	short sp_i0 ; OK..
 23044                              <1> 		; Error !
 23045                              <1> 	;mov	dx, 3F8h
 23046 00006C64 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
 23047 00006C67 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 23048 00006C6B E85F000000          <1> 	call	sp_i3	; call A4	
 23049 00006C70 A880                <1> 	test	al, 80h
 23050 00006C72 7508                <1> 	jnz	short sp_i1
 23051                              <1> sp_i0:
 23052                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
 23053                              <1>         ; (INT 14h initialization code disables interrupts.)
 23054                              <1> 	;
 23055 00006C74 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 23056 00006C77 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
 23057                              <1> sp_i1:
 23058 00006C7C 43                  <1> 	inc	ebx
 23059 00006C7D 66BAF802            <1> 	mov	dx, 2F8h		; COM2
 23060                              <1> 	 ; 29/10/2015
 23061 00006C81 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 23062 00006C85 E845000000          <1> 	call	sp_i3	; call A4	
 23063 00006C8A A880                <1> 	test	al, 80h
 23064 00006C8C 7410                <1> 	jz	short sp_i2 ; OK..
 23065                              <1> 		; Error !
 23066                              <1> 	;mov	dx, 2F8h
 23067 00006C8E 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
 23068 00006C91 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 23069 00006C95 E835000000          <1> 	call	sp_i3	; call A4	
 23070 00006C9A A880                <1> 	test	al, 80h
 23071 00006C9C 7530                <1> 	jnz	short sp_i7
 23072                              <1> sp_i2:
 23073 00006C9E C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 23074                              <1> sp_i6:
 23075                              <1> 	;; COM2 - enabling IRQ 3
 23076                              <1> 	; 07/11/2015
 23077                              <1> 	; 26/10/2015
 23078 00006CA1 9C                  <1> 	pushf
 23079 00006CA2 FA                  <1> 	cli
 23080                              <1> 	;
 23081 00006CA3 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
 23082 00006CA7 EC                  <1> 	in	al, dx 	   		; read register
 23083 00006CA8 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 23084 00006CAA 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 23085 00006CAC EE                  <1> 	out	dx, al     		; write back to register
 23086 00006CAD EB00                <1> 	JMP	$+2	   		; I/O DELAY
 23087 00006CAF 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
 23088 00006CB3 EC                  <1> 	in	al, dx     		; read register
 23089 00006CB4 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 23090                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 23091 00006CB6 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 23092 00006CB8 EE                  <1> 	out	dx, al 	   		; write back to register
 23093 00006CB9 EB00                <1> 	JMP	$+2        		; I/O DELAY
 23094 00006CBB E421                <1> 	in	al, 21h    		; read interrupt mask register
 23095 00006CBD EB00                <1> 	JMP	$+2	   		; I/O DELAY
 23096 00006CBF 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
 23097 00006CC1 E621                <1> 	out	21h, al    		; write back to register
 23098                              <1> 	;
 23099                              <1> 	; 23/10/2015
 23100 00006CC3 B8[816B0000]        <1> 	mov 	eax, com2_int
 23101 00006CC8 A3[A06D0000]        <1> 	mov	[com2_irq3], eax
 23102                              <1> 	; 26/10/2015
 23103 00006CCD 9D                  <1> 	popf	
 23104                              <1> sp_i7:
 23105 00006CCE C3                  <1> 	retn
 23106                              <1> 
 23107                              <1> sp_i3:
 23108                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
 23109                              <1> 	; 28/10/2015
 23110 00006CCF FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
 23111 00006CD1 B000                <1> 	mov	al, 0
 23112 00006CD3 EE                  <1> 	out	dx, al			; disable serial port interrupt
 23113 00006CD4 EB00                <1> 	JMP	$+2			; I/O DELAY
 23114 00006CD6 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
 23115 00006CD9 B080                <1> 	mov	al, 80h			
 23116 00006CDB EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
 23117                              <1> 	;-----	SET BAUD RATE DIVISOR
 23118                              <1> 	; 26/10/2015
 23119 00006CDC 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
 23120                              <1> 					; of the divisor value
 23121 00006CDF 88C8                <1> 	mov	al, cl	; 1
 23122 00006CE1 EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
 23123                              <1> 					; 2 = 57600 baud
 23124                              <1> 					; 3 = 38400 baud
 23125                              <1> 					; 6 = 19200 baud
 23126                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
 23127 00006CE2 EB00                <1> 	JMP	$+2			; I/O DELAY
 23128 00006CE4 28C0                <1> 	sub	al, al
 23129 00006CE6 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
 23130                              <1> 					; of the divisor value
 23131 00006CE8 EE                  <1> 	out	dx, al ; 0
 23132 00006CE9 EB00                <1> 	JMP	$+2			; I/O DELAY
 23133                              <1> 	;	
 23134 00006CEB 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
 23135                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
 23136 00006CED 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
 23137 00006CF0 EE                  <1> 	out	dx, al			
 23138 00006CF1 EB00                <1> 	JMP	$+2			; I/O DELAY
 23139                              <1> 	; 29/10/2015
 23140 00006CF3 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
 23141 00006CF5 30C0                <1> 	xor	al, al			; 0
 23142 00006CF7 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
 23143 00006CF8 EB00                <1> 	JMP	$+2	
 23144                              <1> sp_i4:
 23145                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
 23146                              <1> 	; 29/06/2015 (line status after modem status)
 23147 00006CFA 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
 23148                              <1> sp_i4s:
 23149 00006CFD EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
 23150 00006CFE EB00                <1> 	JMP	$+2			; I/O DELAY
 23151 00006D00 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
 23152 00006D02 FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
 23153                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
 23154 00006D04 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
 23155                              <1> 	; AL = Line status, AH = Modem status
 23156 00006D05 C3                  <1> 	retn
 23157                              <1> 
 23158                              <1> sp_status:
 23159                              <1> 	; 29/06/2015
 23160                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
 23161                              <1> 	; Get serial port status
 23162 00006D06 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
 23163 00006D0A 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
 23164                              <1> 					; dx = 2FEh for COM2
 23165 00006D0C EBEF                <1> 	jmp	short sp_i4s
 23166                              <1> 
 23167                              <1> sp_setp: ; Set serial port communication parameters
 23168                              <1> 	; 07/11/2015
 23169                              <1> 	; 29/10/2015
 23170                              <1> 	; 29/06/2015
 23171                              <1> 	; Retro UNIX 386 v1 feature only !	
 23172                              <1> 	;
 23173                              <1> 	; INPUT:
 23174                              <1> 	;	AL = 0 for COM1
 23175                              <1> 	;	     1 for COM2
 23176                              <1> 	;	AH = Communication parameters (*)
 23177                              <1> 	; OUTPUT:
 23178                              <1> 	;	CL = Line status
 23179                              <1> 	;	CH = Modem status
 23180                              <1> 	;   If cf = 1 -> Error code in [u.error]
 23181                              <1> 	;		 'invalid parameter !' 
 23182                              <1> 	;		 	 or
 23183                              <1> 	;		 'device not ready !' error
 23184                              <1> 	;	
 23185                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 23186                              <1> 	;	Bit	4	3	2	1	0
 23187                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 23188                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 23189                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 23190                              <1> 	;		11 = even
 23191                              <1> 	;  Baud rate setting bits: (29/06/2015)
 23192                              <1> 	;		Retro UNIX 386 v1 feature only !
 23193                              <1> 	;	Bit	7    6    5  | Baud rate
 23194                              <1> 	;		------------------------
 23195                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 23196                              <1> 	;		0    0    1  | 9600 (12)
 23197                              <1> 	;		0    1    0  | 19200 (6) 
 23198                              <1> 	;		0    1	  1  | 38400 (3) 
 23199                              <1> 	;		1    0	  0  | 14400 (8)
 23200                              <1> 	;		1    0	  1  | 28800 (4)
 23201                              <1> 	;		1    1    0  | 57600 (2)
 23202                              <1> 	;		1    1    1  | 115200 (1) 
 23203                              <1> 	;
 23204                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 23205                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 23206                              <1> 	;
 23207                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 23208                              <1> 	;
 23209 00006D0E 66BAF803            <1> 	mov	dx, 3F8h
 23210 00006D12 BB[34790000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
 23211 00006D17 3C01                <1> 	cmp	al, 1
 23212 00006D19 776B                <1> 	ja 	short sp_invp_err
 23213 00006D1B 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
 23214 00006D1D FECE                <1> 	dec	dh ; 2F8h
 23215 00006D1F 43                  <1> 	inc	ebx ; COM2 control byte offset
 23216                              <1> sp_setp1:
 23217                              <1> 	; 29/10/2015
 23218 00006D20 8823                <1> 	mov	[ebx], ah
 23219 00006D22 0FB6CC              <1> 	movzx 	ecx, ah
 23220 00006D25 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
 23221 00006D28 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
 23222 00006D2B 8A81[956D0000]      <1> 	mov	al, [ecx+b_div_tbl]
 23223 00006D31 6689C1              <1> 	mov	cx, ax
 23224 00006D34 E896FFFFFF          <1> 	call	sp_i3
 23225 00006D39 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
 23226 00006D3C A880                <1> 	test	al, 80h
 23227 00006D3E 740F                <1> 	jz	short sp_setp2
 23228 00006D40 C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
 23229                              <1> stp_dnr_err:
 23230 00006D43 C705[AD850000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
 23231 00006D4B 0000                <1>
 23232                              <1> 	; CL = Line status, CH = Modem status
 23233 00006D4D F9                  <1> 	stc
 23234 00006D4E C3                  <1> 	retn
 23235                              <1> sp_setp2:
 23236 00006D4F 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
 23237 00006D52 0F8649FFFFFF        <1>         jna     sp_i6 
 23238                              <1> 		      ; COM1 (3F?h)
 23239                              <1> sp_i5: 
 23240                              <1> 	; 07/11/2015
 23241                              <1> 	; 26/10/2015
 23242                              <1> 	; 29/06/2015
 23243                              <1> 	;
 23244                              <1> 	;; COM1 - enabling IRQ 4
 23245 00006D58 9C                  <1> 	pushf
 23246 00006D59 FA                  <1> 	cli
 23247 00006D5A 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
 23248 00006D5E EC                  <1> 	in	al, dx 	   		; read register
 23249 00006D5F EB00                <1> 	JMP	$+2			; I/O DELAY
 23250 00006D61 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 23251 00006D63 EE                  <1> 	out	dx, al     		; write back to register
 23252 00006D64 EB00                <1> 	JMP	$+2			; I/O DELAY
 23253 00006D66 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
 23254 00006D6A EC                  <1> 	in	al, dx     		; read register
 23255 00006D6B EB00                <1> 	JMP	$+2			; I/O DELAY
 23256                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 23257 00006D6D 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 23258 00006D6F EE                  <1> 	out	dx, al 	   		; write back to register
 23259 00006D70 EB00                <1> 	JMP	$+2        		; I/O DELAY
 23260 00006D72 E421                <1> 	in	al, 21h    		; read interrupt mask register
 23261 00006D74 EB00                <1> 	JMP	$+2			; I/O DELAY
 23262 00006D76 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
 23263 00006D78 E621                <1> 	out	21h, al    		; write back to register
 23264                              <1> 	;
 23265                              <1> 	; 23/10/2015
 23266 00006D7A B8[8A6B0000]        <1> 	mov 	eax, com1_int
 23267 00006D7F A3[9C6D0000]        <1> 	mov	[com1_irq4], eax
 23268                              <1> 	; 26/10/2015
 23269 00006D84 9D                  <1> 	popf
 23270 00006D85 C3                  <1> 	retn
 23271                              <1> 
 23272                              <1> sp_invp_err:
 23273 00006D86 C705[AD850000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 23274 00006D8E 0000                <1>
 23275 00006D90 31C9                <1> 	xor	ecx, ecx
 23276 00006D92 49                  <1> 	dec	ecx ; 0FFFFh
 23277 00006D93 F9                  <1> 	stc
 23278 00006D94 C3                  <1> 	retn
 23279                              <1> 
 23280                              <1> ; 29/10/2015
 23281                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
 23282 00006D95 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
 23283                              <1> 
 23284                              <1> 
 23285                              <1> ; 23/10/2015
 23286                              <1> com1_irq4:
 23287 00006D9C [A46D0000]          <1> 	dd dummy_retn
 23288                              <1> com2_irq3:
 23289 00006DA0 [A46D0000]          <1> 	dd dummy_retn
 23290                              <1> 
 23291                              <1> dummy_retn:
 23292 00006DA4 C3                  <1> 	retn
 23293                              <1> 
 23294                              <1> wakeup:
 23295                              <1> 	; 24/01/2016
 23296 00006DA5 C3                  <1> 	retn
 23297                                  %include 'trdosk9.s' ; 04/01/2016
 23298                              <1> ; ****************************************************************************
 23299                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - INITIALIZED DATA : trdosk9.s
 23300                              <1> ; ----------------------------------------------------------------------------
 23301                              <1> ; Last Update: 01/02/2016
 23302                              <1> ; ----------------------------------------------------------------------------
 23303                              <1> ; Beginning: 04/01/2016
 23304                              <1> ; ----------------------------------------------------------------------------
 23305                              <1> ; ----------------------------------------------------------------------------
 23306                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 23307                              <1> ; ----------------------------------------------------------------------------
 23308                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 23309                              <1> ; TRDOS2.ASM (09/11/2011)
 23310                              <1> ; ****************************************************************************
 23311                              <1> ; DRV_INIT.ASM [26/09/2009] Last Update: 07/08/2011
 23312                              <1> ; MAINPROG.ASM [17/01/2004] Last Update: 09/11/2011
 23313                              <1> ; CMD_INTR.ASM [29/01/2005] Last Update: 09/11/2011
 23314                              <1> 
 23315                              <1> Restore_CDIR:	
 23316 00006DA6 FF                  <1> 		db 0FFh ; Initial value -> any number except 0
 23317                              <1> 
 23318                              <1> msg_CRLF_temp:  
 23319 00006DA7 070D0A00            <1> 		db  07h, 0Dh, 0Ah, 0
 23320                              <1> 
 23321                              <1> Magic_Bytes:
 23322 00006DAB 04                  <1> 		db 4
 23323 00006DAC 01                  <1> 		db 1
 23324                              <1> mainprog_Version:
 23325 00006DAD 07                  <1> 		db 7
 23326 00006DAE 5B5452444F535D204D- <1> 		db "[TRDOS] Main Program v2.0.020216"
 23327 00006DB7 61696E2050726F6772- <1>
 23328 00006DC0 616D2076322E302E30- <1>
 23329 00006DC9 3230323136          <1>
 23330 00006DCE 0D0A                <1> 		db 0Dh, 0Ah
 23331 00006DD0 286329204572646F67- <1> 		db "(c) Erdogan Tan 2005-2016"
 23332 00006DD9 616E2054616E203230- <1>
 23333 00006DE2 30352D32303136      <1>
 23334 00006DE9 0D0A00              <1> 		db 0Dh, 0Ah, 0
 23335                              <1> 
 23336                              <1> MainProgCfgFile:
 23337 00006DEC 4D41494E50524F472E- <1> 		db "MAINPROG.CFG", 0
 23338 00006DF5 43464700            <1>
 23339                              <1> 
 23340                              <1> TRDOSPromptLabel:
 23341 00006DF9 5452444F53          <1> 		db "TRDOS"
 23342 00006DFE 00                  <1> 		db 0
 23343 00006DFF 00<rept>            <1>                 times 5 db 0
 23344 00006E04 00                  <1> 		db 0
 23345                              <1> 
 23346                              <1> ; INTERNAL COMMANDS
 23347 00006E05 444952              <1> Cmd_Dir:	db "DIR"
 23348                              <1> ; Cmd_Cd:	db "CD"
 23349                              <1> ; Cmd_Drive:	db "C:" ; D:, E: etc.
 23350 00006E08 564552              <1> Cmd_Ver:	db "VER"
 23351 00006E0B 45584954            <1> Cmd_Exit:	db "EXIT"
 23352 00006E0F 50524F4D5054        <1> Cmd_Prompt:	db "PROMPT"
 23353 00006E15 564F4C554D45        <1> Cmd_Volume:	db "VOLUME"
 23354 00006E1B 4C4F4E474E414D45    <1> Cmd_LongName:	db "LONGNAME"
 23355 00006E23 44415445            <1> Cmd_Date:	db "DATE"
 23356 00006E27 54494D45            <1> Cmd_Time:	db "TIME"
 23357                              <1> ;Cmd_Run:	db "RUN"
 23358 00006E2B 534554              <1> Cmd_Set:	db "SET" 
 23359 00006E2E 434C53              <1> Cmd_Cls:	db "CLS"
 23360 00006E31 53484F57            <1> Cmd_Show:	db "SHOW"
 23361 00006E35 44454C              <1> Cmd_Del:	db "DEL"
 23362 00006E38 415454524942        <1> Cmd_Attrib:	db "ATTRIB"
 23363 00006E3E 52454E414D45        <1> Cmd_Rename:	db "RENAME"
 23364 00006E44 524D444952          <1> Cmd_Rmdir:	db "RMDIR"
 23365 00006E49 4D4B444952          <1> Cmd_Mkdir:	db "MKDIR"
 23366 00006E4E 434F5059            <1> Cmd_Copy:	db "COPY"
 23367 00006E52 4D4F5645            <1> Cmd_Move:	db "MOVE"
 23368 00006E56 5041544800          <1> Cmd_Path:	db "PATH", 0
 23369 00006E5B 46494E44            <1> Cmd_Find:	db "FIND" ; temporary
 23370 00006E5F 4D454D              <1> Cmd_Mem:	db "MEM"  ; MEMORY
 23371 00006E62 5245414446494C45    <1> Cmd_ReadFile:	db 'READFILE' ; temporary
 23372 00006E6A 4543484F            <1> Cmd_Echo:	db "ECHO"
 23373                              <1> ;Cmd_Remark:	db "*" 
 23374 00006E6E 444556494345        <1> Cmd_Device:	db "DEVICE"
 23375 00006E74 4445564C495354      <1> Cmd_DevList:	db "DEVLIST"
 23376                              <1> 
 23377                              <1> Msg_Enter_Date:
 23378 00006E7B 456E746572206E6577- <1>                 db 'Enter new date (dd-mm-yy): '
 23379 00006E84 206461746520286464- <1>
 23380 00006E8D 2D6D6D2D7979293A20  <1>
 23381 00006E96 00                  <1>                 db 0
 23382                              <1> Msg_Show_Date:
 23383 00006E97 43757272656E742064- <1>                 db   'Current date is '
 23384 00006EA0 61746520697320      <1>
 23385 00006EA7 30                  <1> Day:            db   '0'
 23386 00006EA8 30                  <1> 		db   '0'
 23387 00006EA9 2F                  <1>                 db   '/'
 23388 00006EAA 30                  <1> Month:          db   '0'
 23389 00006EAB 30                  <1> 		db   '0'
 23390 00006EAC 2F                  <1>                 db   '/'
 23391 00006EAD 30                  <1> Century:        db   '0'
 23392 00006EAE 30                  <1>                 db   '0'
 23393 00006EAF 30                  <1> Year:           db   '0'
 23394 00006EB0 30                  <1> 		db   '0'
 23395 00006EB1 0D0A00              <1>                 db   0Dh, 0Ah, 0
 23396                              <1> 
 23397                              <1> Msg_Enter_Time:
 23398 00006EB4 456E746572206E6577- <1> 		db 'Enter new time: '
 23399 00006EBD 2074696D653A20      <1>
 23400 00006EC4 00                  <1> 		db 0
 23401                              <1> Msg_Show_Time:
 23402 00006EC5 43757272656E742074- <1> 		db   'Current time is '
 23403 00006ECE 696D6520697320      <1>
 23404 00006ED5 30                  <1> Hour:           db   '0'
 23405 00006ED6 30                  <1> 		db   '0'
 23406 00006ED7 3A                  <1> 		db   ':'
 23407 00006ED8 30                  <1> Minute:         db   '0'
 23408 00006ED9 30                  <1> 		db   '0'
 23409 00006EDA 3A                  <1> 		db   ':'
 23410 00006EDB 30                  <1> Second:         db   '0'
 23411 00006EDC 30                  <1> 		db   '0'
 23412 00006EDD 0D0A00              <1> 		db   0Dh, 0Ah, 0
 23413                              <1> 
 23414                              <1> 
 23415                              <1> ;VolSize_Unit1:   dd 0
 23416                              <1> ;VolSize_Unit2:   dd 0
 23417                              <1> 
 23418                              <1> VolSize_KiloBytes:
 23419 00006EE0 206B696C6F62797465- <1> 		db " kilobytes", 0Dh, 0Ah, 0
 23420 00006EE9 730D0A00            <1>
 23421                              <1> VolSize_Bytes:
 23422 00006EED 2062797465730D0A00  <1> 		db " bytes", 0Dh, 0Ah, 0
 23423                              <1> Volume_in_drive:
 23424 00006EF6 0D0A                <1> 		db 0Dh, 0Ah
 23425                              <1> Vol_FS_Name:
 23426 00006EF8 54522046533120      <1> 		db "TR FS1 "
 23427 00006EFF 566F6C756D6520696E- <1> 		db "Volume in drive "
 23428 00006F08 20647269766520      <1>
 23429 00006F0F 30                  <1> Vol_Drv_Name:   db 30h
 23430 00006F10 3A                  <1> 		db ":"
 23431 00006F11 20697320            <1> 		db " is "
 23432 00006F15 0D0A                <1> 		db 0Dh, 0Ah
 23433                              <1> Vol_Vol_Name:
 23434 00006F17 20<rept>            <1> 		times 64 db 20h
 23435 00006F57 0D0A                <1> 		db 0Dh, 0Ah
 23436                              <1> Vol_Vol_Serial_Header:
 23437 00006F59 0D0A                <1> 		db 0Dh, 0Ah
 23438 00006F5B 566F6C756D65205365- <1> 		db "Volume Serial No: "
 23439 00006F64 7269616C204E6F3A20  <1>
 23440                              <1> Vol_Vol_Serial2:
 23441 00006F6D 30303030            <1> 		db "0000"
 23442 00006F71 2D                  <1> 		db "-"
 23443                              <1> Vol_Vol_Serial1:
 23444 00006F72 30303030            <1> 		db "0000"
 23445 00006F76 0D0A00              <1> 		db 0Dh, 0Ah, 0
 23446                              <1> 
 23447                              <1> ;Vol_Tot_Sec_Str_Start:
 23448                              <1> ;		dd 0
 23449                              <1> Vol_Total_Sector_Header:
 23450 00006F79 0D0A                <1> 		db 0Dh, 0Ah
 23451 00006F7B 566F6C756D65205369- <1> 		db "Volume Size : ", 0
 23452 00006F84 7A65203A2000        <1>
 23453                              <1> ;Vol_Tot_Sec_Str: 
 23454                              <1> ;		db "0000000000"
 23455                              <1> ;Vol_Tot_Sec_Str_End:
 23456                              <1> ;		db 0
 23457                              <1> ;Vol_Free_Sectors_Str_Start:
 23458                              <1> ;		dd 0
 23459                              <1> Vol_Free_Sectors_Header:
 23460 00006F8A 467265652053706163- <1> 		db "Free Space  : ", 0
 23461 00006F93 6520203A2000        <1>
 23462                              <1> ;Vol_Free_Sectors_Str:
 23463                              <1> ;		db "0000000000"
 23464                              <1> ;Vol_Free_Sectors_Str_End:
 23465                              <1> ;		db 0
 23466                              <1> 
 23467                              <1> Msg_Bad_Command:
 23468 00006F99 42616420636F6D6D61- <1>                 db "Bad command or file name!"
 23469 00006FA2 6E64206F722066696C- <1>
 23470 00006FAB 65206E616D6521      <1>
 23471 00006FB2 0D0A00              <1>                 db 0Dh, 0Ah, 0
 23472                              <1> 
 23473                                  
 23474                                  ; 07/03/2015
 23475                                  ; Temporary Code
 23476                                  display_disks:
 23477 00006FB5 803D[AE750000]00        	cmp 	byte [fd0_type], 0
 23478 00006FBC 7605                    	jna 	short ddsks1
 23479 00006FBE E87D000000              	call	pdskm
 23480                                  ddsks1:
 23481 00006FC3 803D[AF750000]00        	cmp	byte [fd1_type], 0
 23482 00006FCA 760C                    	jna	short ddsks2
 23483 00006FCC C605[19750000]31        	mov	byte [dskx], '1'
 23484 00006FD3 E868000000              	call	pdskm
 23485                                  ddsks2:
 23486 00006FD8 803D[B0750000]00        	cmp	byte [hd0_type], 0
 23487 00006FDF 7654                    	jna	short ddsk6
 23488 00006FE1 66C705[17750000]68-     	mov	word [dsktype], 'hd'
 23489 00006FE9 64                 
 23490 00006FEA C605[19750000]30        	mov	byte [dskx], '0'
 23491 00006FF1 E84A000000              	call	pdskm
 23492                                  ddsks3:
 23493 00006FF6 803D[B1750000]00        	cmp	byte [hd1_type], 0
 23494 00006FFD 7636                    	jna	short ddsk6
 23495 00006FFF C605[19750000]31        	mov	byte [dskx], '1'
 23496 00007006 E835000000              	call	pdskm
 23497                                  ddsks4:
 23498 0000700B 803D[B2750000]00        	cmp	byte [hd2_type], 0
 23499 00007012 7621                    	jna	short ddsk6
 23500 00007014 C605[19750000]32        	mov	byte [dskx], '2'
 23501 0000701B E820000000              	call	pdskm
 23502                                  ddsks5:
 23503 00007020 803D[B3750000]00        	cmp	byte [hd3_type], 0
 23504 00007027 760C                    	jna	short ddsk6
 23505 00007029 C605[19750000]33        	mov	byte [dskx], '3'
 23506 00007030 E80B000000              	call	pdskm
 23507                                  ddsk6:
 23508 00007035 BE[28750000]            	mov	esi, nextline
 23509 0000703A E806000000              	call	pdskml
 23510                                  pdskm_ok:
 23511 0000703F C3                      	retn
 23512                                  pdskm:
 23513 00007040 BE[15750000]            	mov	esi, dsk_ready_msg
 23514                                  pdskml:	
 23515 00007045 AC                      	lodsb
 23516 00007046 08C0                    	or	al, al
 23517 00007048 74F5                    	jz	short pdskm_ok
 23518 0000704A 56                      	push	esi
 23519 0000704B 31DB                    	xor	ebx, ebx ; 0
 23520                                  			; Video page 0 (bl=0)
 23521 0000704D B407                    	mov	ah, 07h ; Black background, 
 23522                                  			; light gray forecolor
 23523 0000704F E8D5A7FFFF              	call	WRITE_TTY
 23524 00007054 5E                      	pop	esi
 23525 00007055 EBEE                    	jmp	short pdskml
 23526                                  
 23527 00007057 90<rept>                align 16
 23528                                  
 23529                                  gdt:	; Global Descriptor Table
 23530                                  	; (30/07/2015, conforming cs)
 23531                                  	; (26/03/2015)
 23532                                  	; (24/03/2015, tss)
 23533                                  	; (19/03/2015)
 23534                                  	; (29/12/2013)
 23535                                  	;
 23536 00007060 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
 23537                                  	; 18/08/2014
 23538                                  			; 8h kernel code segment, base = 00000000h		
 23539 00007068 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
 23540                                  			; 10h kernel data segment, base = 00000000h	
 23541 00007070 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
 23542                                  			; 1Bh user code segment, base address = 400000h ; CORE
 23543 00007078 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
 23544                                  			; 23h user data segment, base address = 400000h ; CORE
 23545 00007080 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
 23546                                  			; Task State Segment
 23547 00007088 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
 23548                                  			       ;  no IO permission in ring 3)
 23549                                  gdt_tss0:
 23550 0000708A 0000                    	dw 0  ; TSS base address, bits 0-15 
 23551                                  gdt_tss1:
 23552 0000708C 00                      	db 0  ; TSS base address, bits 16-23 
 23553                                  	      		; 49h	
 23554 0000708D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
 23555 0000708E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
 23556                                  gdt_tss2:
 23557 0000708F 00                      	db 0  ; TSS base address, bits 24-31 
 23558                                  
 23559                                  gdt_end:
 23560                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 23561                                  					;; Type= 1 (code)/C=0/R=1/A=0
 23562                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 23563                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 23564                                  
 23565                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 23566                                  					;; Type= 0 (data)/E=0/W=1/A=0
 23567                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 23568                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 23569                                  		; W= Writeable, A= Accessed
 23570                                  	
 23571                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
 23572                                  					;; Type= 1 (code)/C=0/R=1/A=0
 23573                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 23574                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 23575                                  
 23576                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
 23577                                  					;; Type= 0 (data)/E=0/W=1/A=0
 23578                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 23579                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 23580                                  	
 23581                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
 23582                                  
 23583                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
 23584                                  		;	 = 100000h * 1000h (G=1) = 4GB
 23585                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
 23586                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
 23587                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
 23588                                  		; AVL= Available to programmers	
 23589                                  
 23590                                  gdtd:
 23591 00007090 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
 23592 00007092 [60700000]                      dd gdt			; Address of the GDT
 23593                                  
 23594                                  	; 20/08/2014
 23595                                  idtd:
 23596 00007096 FF01                            dw idt_end - idt - 1    ; Limit (size)
 23597 00007098 [60760000]                      dd idt			; Address of the IDT
 23598                                  
 23599                                  Align 4
 23600                                  
 23601                                  	; 21/08/2014
 23602                                  ilist:
 23603                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
 23604                                  	;
 23605                                  	; Exception list
 23606                                  	; 25/08/2014	
 23607 0000709C [4E090000]              	dd	exc0	; 0h,  Divide-by-zero Error
 23608 000070A0 [55090000]              	dd	exc1	
 23609 000070A4 [5C090000]              	dd 	exc2	
 23610 000070A8 [63090000]              	dd	exc3	
 23611 000070AC [67090000]              	dd	exc4	
 23612 000070B0 [6B090000]              	dd	exc5	
 23613 000070B4 [6F090000]              	dd 	exc6	; 06h,  Invalid Opcode
 23614 000070B8 [73090000]              	dd	exc7	
 23615 000070BC [77090000]              	dd	exc8	
 23616 000070C0 [7B090000]              	dd	exc9	
 23617 000070C4 [7F090000]              	dd 	exc10	
 23618 000070C8 [83090000]              	dd	exc11
 23619 000070CC [87090000]              	dd	exc12
 23620 000070D0 [8B090000]              	dd	exc13	; 0Dh, General Protection Fault
 23621 000070D4 [8F090000]              	dd 	exc14	; 0Eh, Page Fault
 23622 000070D8 [93090000]              	dd	exc15
 23623 000070DC [97090000]              	dd	exc16
 23624 000070E0 [9B090000]              	dd	exc17
 23625 000070E4 [9F090000]              	dd 	exc18
 23626 000070E8 [A3090000]              	dd	exc19
 23627 000070EC [A7090000]              	dd 	exc20
 23628 000070F0 [AB090000]              	dd	exc21
 23629 000070F4 [AF090000]              	dd	exc22
 23630 000070F8 [B3090000]              	dd	exc23
 23631 000070FC [B7090000]              	dd 	exc24
 23632 00007100 [BB090000]              	dd	exc25
 23633 00007104 [BF090000]              	dd	exc26
 23634 00007108 [C3090000]              	dd	exc27
 23635 0000710C [C7090000]              	dd 	exc28
 23636 00007110 [CB090000]              	dd	exc29
 23637 00007114 [CF090000]              	dd 	exc30
 23638 00007118 [D3090000]              	dd	exc31
 23639                                  	; Interrupt list
 23640 0000711C [84070000]              	dd	timer_int	; INT 20h
 23641                                  		;dd	irq0	
 23642 00007120 [200E0000]              	dd	kb_int		; 24/01/2016
 23643                                  		;dd	irq1
 23644 00007124 [A4080000]              	dd	irq2
 23645                                  		; COM2 int
 23646 00007128 [A8080000]              	dd	irq3
 23647                                  		; COM1 int
 23648 0000712C [B3080000]              	dd	irq4
 23649 00007130 [BE080000]              	dd	irq5
 23650                                  ;DISKETTE_INT: ;06/02/2015
 23651 00007134 [E8280000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
 23652                                  		;dd	irq6
 23653                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
 23654                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 23655 00007138 [3A0C0000]              	dd	default_irq7	; 25/02/2015
 23656                                  		;dd	irq7
 23657                                  ; Real Time Clock Interrupt
 23658 0000713C [DD0A0000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
 23659                                  		;dd	irq8	; INT 28h
 23660 00007140 [CE080000]              	dd	irq9
 23661 00007144 [D2080000]              	dd	irq10
 23662 00007148 [D6080000]              	dd	irq11
 23663 0000714C [DA080000]              	dd	irq12
 23664 00007150 [DE080000]              	dd	irq13
 23665                                  ;HDISK_INT1:  ;06/02/2015 	
 23666 00007154 [24310000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
 23667                                  		;dd	irq14
 23668                                  ;HDISK_INT2:  ;06/02/2015
 23669 00007158 [4B310000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
 23670                                  		;dd	irq15	; INT 2Fh
 23671                                  		; 14/08/2015
 23672 0000715C [21540000]              	dd	sysent		; INT 30h (system calls)
 23673                                  	
 23674                                  	;dd	ignore_int
 23675 00007160 00000000                	dd	0
 23676                                  
 23677                                  ;;;
 23678                                  ;;; 11/03/2015
 23679                                  %include 'kybdata.s'	; KEYBOARD (BIOS) DATA
 23680                              <1> ; ****************************************************************************
 23681                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - kybdata.s
 23682                              <1> ; ----------------------------------------------------------------------------
 23683                              <1> ; Last Update: 17/01/2016
 23684                              <1> ; ----------------------------------------------------------------------------
 23685                              <1> ; Beginning: 17/01/2016
 23686                              <1> ; ----------------------------------------------------------------------------
 23687                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 23688                              <1> ; ----------------------------------------------------------------------------
 23689                              <1> ; Turkish Rational DOS
 23690                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
 23691                              <1> ;
 23692                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 23693                              <1> ; kybdata.inc (11/03/2015)
 23694                              <1> ;
 23695                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
 23696                              <1> ; ****************************************************************************
 23697                              <1> 
 23698                              <1> ; Retro UNIX 386 v1 Kernel - KYBDATA.INC
 23699                              <1> ; Last Modification: 11/03/2015
 23700                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
 23701                              <1> ;
 23702                              <1> ; ///////// KEYBOARD DATA ///////////////
 23703                              <1> 
 23704                              <1> ; 05/12/2014
 23705                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
 23706                              <1> ; 03/06/86  KEYBOARD BIOS
 23707                              <1> 
 23708                              <1> ;---------------------------------------------------------------------------------
 23709                              <1> ;	KEY IDENTIFICATION SCAN TABLES
 23710                              <1> ;---------------------------------------------------------------------------------
 23711                              <1> 
 23712                              <1> ;-----	TABLES FOR ALT CASE ------------
 23713                              <1> ;-----	ALT-INPUT-TABLE 
 23714 00007164 524F50514B          <1> K30:	db	82,79,80,81,75
 23715 00007169 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
 23716                              <1> ;-----	SUPER-SHIFT-TABLE 
 23717 0000716E 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
 23718 00007174 161718191E1F        <1> 	db	22,23,24,25,30,31
 23719 0000717A 202122232425        <1> 	db	32,33,34,35,36,37
 23720 00007180 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
 23721 00007186 3132                <1> 	db	49,50
 23722                              <1> 
 23723                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
 23724                              <1> ;-----	KEY_TABLE 
 23725 00007188 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
 23726 00007189 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
 23727 0000718E 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
 23728                              <1> _K6L    equ     $-_K6
 23729                              <1> 
 23730                              <1> ;-----	MASK_TABLE
 23731 00007190 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
 23732 00007191 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
 23733 00007196 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
 23734                              <1> 
 23735                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
 23736 00007198 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
 23737 0000719E 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
 23738 000071A4 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
 23739 000071AA 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
 23740 000071B0 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
 23741 000071B6 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
 23742 000071BC 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
 23743 000071C2 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
 23744 000071C8 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
 23745 000071CE 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
 23746                              <1> 	;				;----- FUNCTIONS ------		
 23747 000071D2 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
 23748 000071D8 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
 23749 000071DE 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
 23750 000071E4 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
 23751 000071EA 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
 23752                              <1> 
 23753                              <1> ;-----	TABLES FOR LOWER CASE ----------
 23754 000071F0 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
 23755 000071F9 39302D3D0809        <1>
 23756 000071FF 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
 23757 00007208 705B5D0DFF61736466- <1>
 23758 00007211 67686A6B6C3B27      <1>
 23759 00007218 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
 23760 00007221 6D2C2E2FFF2AFF20FF  <1>
 23761                              <1> ;-----	LC TABLE SCAN
 23762 0000722A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
 23763 0000722F 4041424344          <1> 	db	64,65,66,67,68
 23764 00007234 FFFF                <1> 	db	-1,-1			; NL, SL
 23765                              <1> 
 23766                              <1> ;-----	KEYPAD TABLE
 23767 00007236 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
 23768 0000723C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
 23769 00007243 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
 23770                              <1> 
 23771                              <1> ;-----	TABLES FOR UPPER CASE ----------
 23772 00007248 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
 23773 00007251 28295F2B0800        <1>
 23774 00007257 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
 23775 00007260 507B7D0DFF41534446- <1>
 23776 00007269 47484A4B4C3A22      <1>
 23777 00007270 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
 23778 00007279 4D3C3E3FFF2AFF20FF  <1>
 23779                              <1> ;-----	UC TABLE SCAN
 23780 00007282 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
 23781 00007287 595A5B5C5D          <1> 	db	89,90,91,92,93
 23782 0000728C FFFF                <1> 	db	-1,-1			; NL, SL
 23783                              <1> 
 23784                              <1> ;-----	NUM STATE TABLE
 23785 0000728E 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
 23786 00007297 3233302E            <1>
 23787                              <1> 	;
 23788 0000729B FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
 23789                              <1> 
 23790                              <1> ; 26/08/2014
 23791                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
 23792                              <1> ; Derived from IBM "pc-at" 
 23793                              <1> ; rombios source code (06/10/1985)
 23794                              <1> ; 'dseg.inc'
 23795                              <1> 
 23796                              <1> ;---------------------------------------;
 23797                              <1> ;	SYSTEM DATA AREA		;
 23798                              <1> ;----------------------------------------
 23799 000072A0 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
 23800                              <1> 
 23801                              <1> ;----------------------------------------
 23802                              <1> ;	KEYBOARD DATA AREAS		;
 23803                              <1> ;----------------------------------------
 23804                              <1> 
 23805 000072A1 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
 23806 000072A2 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
 23807 000072A3 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
 23808 000072A4 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
 23809 000072A5 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
 23810 000072A6 [B6720000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
 23811 000072AA [D6720000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
 23812 000072AE [B6720000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
 23813 000072B2 [B6720000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
 23814                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
 23815 000072B6 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
 23816                              <1> 
 23817                              <1> ; /// End Of KEYBOARD DATA ///
 23818                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
 23819                              <1> ; ****************************************************************************
 23820                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - vidata.s
 23821                              <1> ; ----------------------------------------------------------------------------
 23822                              <1> ; Last Update: 30/01/2016
 23823                              <1> ; ----------------------------------------------------------------------------
 23824                              <1> ; Beginning: 16/01/2016
 23825                              <1> ; ----------------------------------------------------------------------------
 23826                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 23827                              <1> ; ----------------------------------------------------------------------------
 23828                              <1> ; Turkish Rational DOS
 23829                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
 23830                              <1> ;
 23831                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 23832                              <1> ; vidata.inc (11/03/2015)
 23833                              <1> ;
 23834                              <1> ; Derived from 'IBM PC-AT' BIOS source code (1985) 
 23835                              <1> ; ****************************************************************************
 23836                              <1> 
 23837                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.S
 23838                              <1> ; Last Modification: 11/03/2015
 23839                              <1> ;		    (Data section for 'VIDEO.INC')	
 23840                              <1> ;
 23841                              <1> ; ///////// VIDEO DATA ///////////////
 23842                              <1> 
 23843                              <1> ;-----	COLUMNS
 23844                              <1> ;M6:
 23845                              <1> ;	db	40, 40, 80, 80, 40, 40, 80, 80
 23846                              <1> 
 23847                              <1> ;-----	C_REG_TAB
 23848                              <1> ;M7:
 23849                              <1> ;	db	2Ch, 28h, 2Dh, 29h, 2Ah, 2Eh, 1Eh, 29h	; TABLE OF MODE SETS
 23850                              <1> 
 23851                              <1> ;----------------------------------------
 23852                              <1> ;	VIDEO DISPLAY DATA AREA		;
 23853                              <1> ;----------------------------------------
 23854 000072D6 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
 23855 000072D7 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
 23856                              <1> 				; (29h default setting for video mode 3)
 23857                              <1> 				; Mode Select register Bits
 23858                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
 23859                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
 23860                              <1> 				;   BIT 2 - COLOR (0), BW (1)
 23861                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
 23862                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
 23863                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
 23864                              <1> 				;   BIT 6, 7 - Not Used
 23865                              <1> 
 23866                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
 23867                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
 23868                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
 23869                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
 23870                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
 23871                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
 23872                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
 23873                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
 23874                              <1> ; Mode & 37h = Video signal OFF
 23875                              <1> 			
 23876                              <1> video_params:
 23877                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
 23878                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
 23879                              <1> 	; VIDEO MODE 3
 23880 000072D8 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
 23881 000072DF 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
 23882 000072E4 00000000            <1> 	db	0,0,0,0
 23883                              <1> 
 23884                              <1> ; 16/01/2016
 23885                              <1> chr_attrib:  ; Character color/attributes for viode pages (0 to 7)
 23886 000072E8 0707070707070707    <1> 	db	07h, 07h, 07h, 07h, 07h, 07h, 07h, 07h
 23887                              <1> ; 30/01/2016
 23888                              <1> vmode:
 23889 000072F0 0303030303030303    <1> 	db	3,3,3,3,3,3,3,3 ; video modes for pseudo screens 
 23890                              <1> 
 23891                              <1> ; /// End Of VIDEO DATA ///
 23892                                  %include 'diskdata.s'	; DISK (BIOS) DATA (initialized)
 23893                              <1> ; ****************************************************************************
 23894                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskdata.s
 23895                              <1> ; ----------------------------------------------------------------------------
 23896                              <1> ; Last Update: 24/01/2016
 23897                              <1> ; ----------------------------------------------------------------------------
 23898                              <1> ; Beginning: 24/01/2016
 23899                              <1> ; ----------------------------------------------------------------------------
 23900                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 23901                              <1> ; ----------------------------------------------------------------------------
 23902                              <1> ; Turkish Rational DOS
 23903                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
 23904                              <1> ;
 23905                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 23906                              <1> ; diskdata.inc (11/03/2015)
 23907                              <1> ;
 23908                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
 23909                              <1> ; ****************************************************************************
 23910                              <1> 
 23911                              <1> ; Retro UNIX 386 v1 Kernel - DISKDATA.INC
 23912                              <1> ; Last Modification: 11/03/2015
 23913                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
 23914                              <1> ;
 23915                              <1> 
 23916                              <1> ;----------------------------------------
 23917                              <1> ;	80286 INTERRUPT LOCATIONS	:
 23918                              <1> ;	REFERENCED BY POST & BIOS	:
 23919                              <1> ;----------------------------------------
 23920                              <1> 
 23921 000072F8 [5B730000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
 23922                              <1> 
 23923                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
 23924                              <1> ;----------------------------------------------------------------
 23925                              <1> ; DISK_BASE							:
 23926                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
 23927                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
 23928                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
 23929                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
 23930                              <1> ;----------------------------------------------------------------
 23931                              <1> 
 23932                              <1> ;DISK_BASE:	
 23933                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 23934                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 23935                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 23936                              <1> ;	DB	2		; 512 BYTES/SECTOR
 23937                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
 23938                              <1> ;	db	18		; (EOT for 1.44MB diskette)
 23939                              <1> ;	DB	01BH		; GAP LENGTH
 23940                              <1> ;	DB	0FFH		; DTL
 23941                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
 23942                              <1> ;	db	06ch		; (for 1.44MB dsikette)
 23943                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
 23944                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 23945                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
 23946                              <1> 
 23947                              <1> ;----------------------------------------
 23948                              <1> ;	ROM BIOS DATA AREAS		:
 23949                              <1> ;----------------------------------------
 23950                              <1> 
 23951                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 23952                              <1> 
 23953                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
 23954                              <1> 
 23955                              <1> ;----------------------------------------
 23956                              <1> ;	DISKETTE DATA AREAS		:
 23957                              <1> ;----------------------------------------
 23958                              <1> 
 23959                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
 23960                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
 23961                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
 23962                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
 23963                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
 23964                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
 23965                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
 23966                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
 23967                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
 23968                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
 23969                              <1> 
 23970                              <1> ;----------------------------------------
 23971                              <1> ;	POST AND BIOS WORK DATA AREA	:
 23972                              <1> ;----------------------------------------
 23973                              <1> 
 23974                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
 23975                              <1> 
 23976                              <1> ;----------------------------------------
 23977                              <1> ;	TIMER DATA AREA 		:
 23978                              <1> ;----------------------------------------
 23979                              <1> 
 23980                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
 23981                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
 23982                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
 23983                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
 23984                              <1> 
 23985                              <1> ;----------------------------------------
 23986                              <1> ;	ADDITIONAL MEDIA DATA		:
 23987                              <1> ;----------------------------------------
 23988                              <1> 
 23989                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 23990                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 23991                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 23992                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 23993                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 23994                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 23995                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 23996                              <1> 
 23997                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 23998                              <1> 
 23999                              <1> ;--------------------------------------------------------
 24000                              <1> ;	DRIVE TYPE TABLE				:
 24001                              <1> ;--------------------------------------------------------
 24002                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
 24003                              <1> DR_TYPE:
 24004 000072FC 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
 24005                              <1>                 ;DW      MD_TBL1
 24006 000072FD [1A730000]          <1> 		dd	MD_TBL1
 24007 00007301 82                  <1> 		DB	02+BIT7ON
 24008                              <1> 		;DW      MD_TBL2
 24009 00007302 [27730000]          <1>                 dd      MD_TBL2
 24010 00007306 02                  <1> DR_DEFAULT:	DB	02
 24011                              <1>                 ;DW      MD_TBL3
 24012 00007307 [34730000]          <1> 		dd      MD_TBL3
 24013 0000730B 03                  <1> 		DB	03
 24014                              <1>                 ;DW      MD_TBL4
 24015 0000730C [41730000]          <1> 		dd      MD_TBL4
 24016 00007310 84                  <1> 		DB	04+BIT7ON
 24017                              <1>                 ;DW      MD_TBL5
 24018 00007311 [4E730000]          <1> 		dd      MD_TBL5
 24019 00007315 04                  <1> 		DB	04
 24020                              <1>                 ;DW      MD_TBL6
 24021 00007316 [5B730000]          <1> 		dd      MD_TBL6
 24022                              <1> DR_TYPE_E       equ $                   ; END OF TABLE
 24023                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
 24024                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
 24025                              <1> ;--------------------------------------------------------
 24026                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
 24027                              <1> ;--------------------------------------------------------
 24028                              <1> ;--------------------------------------------------------
 24029                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
 24030                              <1> ;--------------------------------------------------------
 24031                              <1> MD_TBL1:        
 24032 0000731A DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24033 0000731B 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24034 0000731C 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24035 0000731D 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24036 0000731E 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24037 0000731F 2A                  <1> 	DB	02AH		; GAP LENGTH
 24038 00007320 FF                  <1> 	DB	0FFH		; DTL
 24039 00007321 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24040 00007322 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24041 00007323 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24042 00007324 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24043 00007325 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 24044 00007326 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24045                              <1> ;--------------------------------------------------------
 24046                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
 24047                              <1> ;--------------------------------------------------------
 24048                              <1> MD_TBL2:        
 24049 00007327 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24050 00007328 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24051 00007329 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24052 0000732A 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24053 0000732B 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24054 0000732C 2A                  <1> 	DB	02AH		; GAP LENGTH
 24055 0000732D FF                  <1> 	DB	0FFH		; DTL
 24056 0000732E 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24057 0000732F F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24058 00007330 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24059 00007331 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24060 00007332 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 24061 00007333 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
 24062                              <1> ;--------------------------------------------------------
 24063                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
 24064                              <1> ;--------------------------------------------------------
 24065                              <1> MD_TBL3:
 24066 00007334 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24067 00007335 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24068 00007336 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24069 00007337 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24070 00007338 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
 24071 00007339 1B                  <1> 	DB	01BH		; GAP LENGTH
 24072 0000733A FF                  <1> 	DB	0FFH		; DTL
 24073 0000733B 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
 24074 0000733C F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24075 0000733D 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24076 0000733E 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24077 0000733F 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24078 00007340 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 24079                              <1> ;--------------------------------------------------------
 24080                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
 24081                              <1> ;--------------------------------------------------------
 24082                              <1> MD_TBL4:
 24083 00007341 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24084 00007342 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24085 00007343 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24086 00007344 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24087 00007345 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24088 00007346 2A                  <1> 	DB	02AH		; GAP LENGTH
 24089 00007347 FF                  <1> 	DB	0FFH		; DTL
 24090 00007348 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24091 00007349 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24092 0000734A 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24093 0000734B 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24094 0000734C 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24095 0000734D 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24096                              <1> ;--------------------------------------------------------
 24097                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
 24098                              <1> ;--------------------------------------------------------
 24099                              <1> MD_TBL5:
 24100 0000734E DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24101 0000734F 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24102 00007350 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24103 00007351 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24104 00007352 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 24105 00007353 2A                  <1> 	DB	02AH		; GAP LENGTH
 24106 00007354 FF                  <1> 	DB	0FFH		; DTL
 24107 00007355 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 24108 00007356 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24109 00007357 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24110 00007358 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24111 00007359 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24112 0000735A 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 24113                              <1> ;--------------------------------------------------------
 24114                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
 24115                              <1> ;--------------------------------------------------------
 24116                              <1> MD_TBL6:
 24117 0000735B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
 24118 0000735C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 24119 0000735D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 24120 0000735E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 24121 0000735F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
 24122 00007360 1B                  <1> 	DB	01BH		; GAP LENGTH
 24123 00007361 FF                  <1> 	DB	0FFH		; DTL
 24124 00007362 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
 24125 00007363 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 24126 00007364 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 24127 00007365 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 24128 00007366 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 24129 00007367 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 24130                              <1> 
 24131                              <1> 
 24132                              <1> ; << diskette.inc >>
 24133                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 24134                              <1> ;
 24135                              <1> ;----------------------------------------
 24136                              <1> ;	ROM BIOS DATA AREAS		:
 24137                              <1> ;----------------------------------------
 24138                              <1> 
 24139                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 24140                              <1> 
 24141                              <1> ;----------------------------------------
 24142                              <1> ;	FIXED DISK DATA AREAS		:
 24143                              <1> ;----------------------------------------
 24144                              <1> 
 24145                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
 24146                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
 24147                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
 24148                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
 24149                              <1> 
 24150                              <1> ;----------------------------------------
 24151                              <1> ;	ADDITIONAL MEDIA DATA		:
 24152                              <1> ;----------------------------------------
 24153                              <1> 
 24154                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 24155                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
 24156                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
 24157                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
 24158                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
 24159                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 24160                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 24161                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 24162                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 24163                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 24164                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 24165                              <1> 
 24166                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 24167                              <1> ;
 24168                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 24169                              <1> 
 24170                              <1> ERR_TBL:
 24171 00007368 E0                  <1> 	db	NO_ERR
 24172 00007369 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
 24173 0000736D 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
 24174                              <1> 
 24175                              <1> ; 17/12/2014 (mov ax, [cfd])
 24176                              <1> ; 11/12/2014
 24177 00007371 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
 24178                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
 24179 00007372 01                  <1> pfd:		db 1			; previous floppy drive (for GET_PARM)
 24180                              <1> 					; (initial value of 'pfd 
 24181                              <1> 					; must be different then 'cfd' value
 24182                              <1> 					; to force updating/initializing
 24183                              <1> 					; current drive parameters) 
 24184 00007373 90                  <1> align 2
 24185                              <1> 
 24186 00007374 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
 24187                              <1> 			      ; (170h)
 24188 00007376 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
 24189                              <1> 
 24190                              <1> ; 05/01/2015 
 24191 00007378 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
 24192                              <1> 
 24193                              <1> ; *****************************************************************************
 24194                                  ;;;
 24195                                  
 24196                                  ; 27/08/2014
 24197                                  scr_row:
 24198 00007379 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
 24199                                  scr_col:
 24200 0000737D 00000000                	dd 0
 24201                                  
 24202 00007381 90                      Align 2
 24203                                  
 24204                                  ; 20/08/2014
 24205                                    ; /* This is the default interrupt "handler" :-) */ 
 24206                                    ; Linux v0.12 (head.s)
 24207                                  int_msg:
 24208 00007382 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
 24209 0000738B 6E7465727275707420-
 24210 00007394 212000             
 24211                                  
 24212 00007397 90                      Align 2  
 24213                                  
 24214                                  ; 21/08/2014
 24215                                  timer_msg:
 24216 00007398 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
 24217 000073A1 542032306829202120-
 24218 000073AA 54696D657220496E74-
 24219 000073B3 657272757074203A20 
 24220                                  tcountstr:
 24221 000073BC 303030303020            	db "00000 "
 24222 000073C2 00                      	db 0
 24223                                  
 24224 000073C3 90                      Align 2
 24225                                  	; 21/08/2014
 24226                                  exc_msg:
 24227 000073C4 435055206578636570-     	db "CPU exception ! "
 24228 000073CD 74696F6E202120     
 24229                                  excnstr: 		; 25/08/2014
 24230 000073D4 3F3F68202045495020-     	db "??h", "  EIP : "
 24231 000073DD 3A20               
 24232                                  EIPstr: ; 29/08/2014
 24233 000073DF 00<rept>                	times 12 db 0
 24234                                  rtc_msg:
 24235 000073EB 5265616C2054696D65-     	db "Real Time Clock - "
 24236 000073F4 20436C6F636B202D20 
 24237                                  datestr:
 24238 000073FD 30302F30302F303030-     	db "00/00/0000"
 24239 00007406 30                 
 24240 00007407 20                      	db " "
 24241                                  daystr:
 24242 00007408 44415920                	db "DAY "
 24243                                  timestr:	
 24244 0000740C 30303A30303A3030                db "00:00:00"
 24245 00007414 20                      	db " "
 24246 00007415 00                      	db 0 
 24247                                  
 24248                                  daytmp:
 24249                                  	; 28/02/2015
 24250 00007416 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
 24251 0000741F 4F4E20545545205745-
 24252 00007428 442054485520465249-
 24253 00007431 2053415420         
 24254                                  
 24255 00007436 FF                      ptime_seconds: db 0FFh
 24256                                  
 24257                                  	; 23/02/2015
 24258                                  	; 25/08/2014
 24259                                  ;scounter:
 24260                                  ;	db 5
 24261                                  ;	db 19
 24262                                  
 24263                                  ; 05/11/2014
 24264                                  msg_out_of_memory:
 24265 00007437 070D0A                  	db 	07h, 0Dh, 0Ah
 24266 0000743A 496E73756666696369-             db      'Insufficient memory ! (Minimum 2 MB memory is needed.)'
 24267 00007443 656E74206D656D6F72-
 24268 0000744C 79202120284D696E69-
 24269 00007455 6D756D2032204D4220-
 24270 0000745E 6D656D6F7279206973-
 24271 00007467 206E65656465642E29 
 24272 00007470 0D0A00                   	db	0Dh, 0Ah, 0
 24273                                  	;
 24274                                  setup_error_msg:
 24275 00007473 0D0A                    	db 0Dh, 0Ah
 24276 00007475 4469736B2053657475-     	db 'Disk Setup Error!' 
 24277 0000747E 70204572726F7221   
 24278 00007486 0D0A00                  	db 0Dh, 0Ah,0
 24279                                  
 24280                                  ; 06/11/2014
 24281                                  ; Memory Information message
 24282                                  ; 14/08/2015
 24283                                  msg_memory_info:
 24284 00007489 07                      	db	07h
 24285 0000748A 0D0A                    	db	0Dh, 0Ah
 24286                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
 24287 0000748C 546F74616C206D656D-     	db	"Total memory : "
 24288 00007495 6F7279203A20       
 24289                                  mem_total_b_str: ; 10 digits
 24290 0000749B 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
 24291 000074A4 302062797465730D0A 
 24292 000074AD 202020202020202020-     	db	"               ", 20h, 20h, 20h
 24293 000074B6 202020202020202020 
 24294                                  mem_total_p_str: ; 7 digits
 24295 000074BF 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
 24296 000074C8 616765730D0A       
 24297 000074CE 0D0A                    	db 	0Dh, 0Ah
 24298 000074D0 46726565206D656D6F-     	db	"Free memory  : "
 24299 000074D9 727920203A20       
 24300                                  free_mem_b_str:  ; 10 digits
 24301 000074DF 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
 24302 000074E8 3F2062797465730D0A 
 24303 000074F1 202020202020202020-     	db	"               ", 20h, 20h, 20h
 24304 000074FA 202020202020202020 
 24305                                  free_mem_p_str:  ; 7 digits
 24306 00007503 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
 24307 0000750C 616765730D0A       
 24308 00007512 0D0A00                  	db	0Dh, 0Ah, 0
 24309                                  
 24310                                  dsk_ready_msg:
 24311 00007515 0D0A                    	db 	0Dh, 0Ah
 24312                                  dsktype:
 24313 00007517 6664                    	db	'fd'
 24314                                  dskx:
 24315 00007519 30                      	db	'0'
 24316 0000751A 20                      	db	20h
 24317 0000751B 697320524541445920-     	db 	'is READY ...'
 24318 00007524 2E2E2E             
 24319 00007527 00                      	db 	0
 24320                                  nextline:
 24321 00007528 0D0A00                  	db 	0Dh, 0Ah, 0
 24322                                  
 24323                                  ; KERNEL - SYSINIT Messages
 24324                                  ; 24/08/2015
 24325                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
 24326                                  ; 14/07/2013
 24327                                  ;kernel_init_err_msg:
 24328                                  ;	db 0Dh, 0Ah
 24329                                  ;	db 07h
 24330                                  ;	db 'Kernel initialization ERROR !'
 24331                                  ;	db 0Dh, 0Ah, 0 
 24332                                  
 24333                                  ;welcome_msg: 
 24334                                  ;	db 0Dh, 0Ah
 24335                                  ;	db 07h
 24336                                  ;	db 'Welcome to TRDOS 386 Operating System !'
 24337                                  ;	db 0Dh, 0Ah
 24338                                  ;	db 'by Erdogan Tan - 02/02/2016 (v2.0.0)'
 24339                                  ;	db 0Dh, 0Ah, 0
 24340                                  
 24341                                  panic_msg:
 24342 0000752B 0D0A07                  	db 0Dh, 0Ah, 07h
 24343 0000752E 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
 24344 00007537 726E656C2050616E69-
 24345 00007540 632021             
 24346 00007543 0D0A00                  	db 0Dh, 0Ah, 0
 24347                                  
 24348                                  ; 10/05/2015
 24349                                  badsys_msg:
 24350 00007546 0D0A                    	db 0Dh, 0Ah
 24351 00007548 07                      	db 07h
 24352 00007549 496E76616C69642053-     	db 'Invalid System Call !'
 24353 00007552 797374656D2043616C-
 24354 0000755B 6C2021             
 24355 0000755E 0D0A                    	db 0Dh, 0Ah
 24356 00007560 4541583A20              	db 'EAX: '
 24357                                  bsys_msg_eax:
 24358 00007565 303030303030303068      	db '00000000h'
 24359 0000756E 0D0A                    	db 0Dh, 0Ah
 24360 00007570 4549503A20              	db 'EIP: '
 24361                                  bsys_msg_eip:
 24362 00007575 303030303030303068      	db '00000000h' 
 24363 0000757E 0D0A00                  	db 0Dh, 0Ah, 0
 24364                                  
 24365                                  BSYS_M_SIZE equ $ - badsys_msg
 24366                                  
 24367                                  
 24368 00007581 90                      align 2
 24369                                  
 24370                                  ; EPOCH Variables
 24371                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
 24372                                  ; 09/04/2013 epoch variables
 24373                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
 24374                                  ;
 24375 00007582 B207                    year: 	dw 1970
 24376 00007584 0100                    month: 	dw 1
 24377 00007586 0100                    day: 	dw 1
 24378 00007588 0000                    hour: 	dw 0
 24379 0000758A 0000                    minute: dw 0
 24380 0000758C 0000                    second: dw 0
 24381                                  
 24382                                  DMonth:
 24383 0000758E 0000                    	dw 0
 24384 00007590 1F00                    	dw 31
 24385 00007592 3B00                    	dw 59
 24386 00007594 5A00                    	dw 90
 24387 00007596 7800                    	dw 120
 24388 00007598 9700                    	dw 151
 24389 0000759A B500                    	dw 181
 24390 0000759C D400                    	dw 212
 24391 0000759E F300                    	dw 243
 24392 000075A0 1101                    	dw 273
 24393 000075A2 3001                    	dw 304
 24394 000075A4 4E01                    	dw 334
 24395                                  
 24396                                  ; 04/11/2014 (Retro UNIX 386 v1)
 24397 000075A6 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
 24398                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
 24399 000075A8 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
 24400                                  		   ;   between 16 MB and 4 GB.
 24401                                  
 24402                                  ; 12/11/2014 (Retro UNIX 386 v1)
 24403 000075AA 00                      boot_drv:    db 0 ; boot drive number (physical)
 24404                                  ; 24/11/2014
 24405 000075AB 00                      drv:	     db 0 
 24406 000075AC 00                      last_drv:    db 0 ; last hdd
 24407 000075AD 00                      hdc:         db 0  ; number of hard disk drives
 24408                                  		     ; (present/detected)
 24409                                  ;
 24410                                  ; 24/11/2014 (Retro UNIX 386 v1)
 24411                                  ; Physical drive type & flags
 24412 000075AE 00                      fd0_type:    db 0  ; floppy drive type
 24413 000075AF 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
 24414                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
 24415                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
 24416                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
 24417                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
 24418 000075B0 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
 24419 000075B1 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
 24420 000075B2 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
 24421 000075B3 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
 24422                                  		     ; bit 0 - Fixed disk access subset supported
 24423                                  		     ; bit 1 - Drive locking and ejecting
 24424                                  		     ; bit 2 - Enhanced disk drive support
 24425                                  		     ; bit 3 = Reserved (64 bit EDD support)
 24426                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
 24427                                  		     ; will interpret it as 'LBA ready'!)		
 24428                                  
 24429                                  ; 11/03/2015 - 10/07/2015
 24430 000075B4 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
 24431 000075BD 0000000000         
 24432 000075C2 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
 24433 000075CB 0000000000         
 24434 000075D0 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
 24435 000075D9 0000000000         
 24436 000075DE 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
 24437 000075E7 000000000000000000-
 24438 000075F0 000000000000000000-
 24439 000075F9 00                 
 24440 000075FA 00000000000000          drv.status:    db 0,0,0,0,0,0,0
 24441 00007601 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
 24442                                  ;
 24443                                  starting_msg:
 24444 00007608 5475726B6973682052-     	db "Turkish Rational DOS v2.0 [02/02/2016] ...", 0
 24445 00007611 6174696F6E616C2044-
 24446 0000761A 4F532076322E30205B-
 24447 00007623 30322F30322F323031-
 24448 0000762C 365D202E2E2E00     
 24449                                  NextLine:
 24450 00007633 0D0A00                  	db 0Dh, 0Ah, 0
 24451                                  
 24452                                  msgl_drv_not_ready: 
 24453 00007636 070D0A                  	db 07h, 0Dh, 0Ah
 24454 00007639 4472697665206E6F74-             db 'Drive not ready or read error !'
 24455 00007642 207265616479206F72-
 24456 0000764B 207265616420657272-
 24457 00007654 6F722021           
 24458 00007658 0D0A00                          db 0Dh, 0Ah, 0
 24459                                  
 24460 0000765B 90<rept>                align 16
 24461                                  
 24462                                  bss_start:
 24463                                  
 24464                                  ABSOLUTE bss_start
 24465                                  
 24466                                  	; 11/03/2015
 24467                                  	; Interrupt Descriptor Table (20/08/2014)
 24468                                  idt:
 24469 00007660 <res 00000200>          	resb	64*8 ; INT 0 to INT 3Fh
 24470                                  idt_end:
 24471                                  
 24472                                  ;alignb 4
 24473                                  
 24474                                  task_state_segment:
 24475                                  	; 24/03/2015
 24476 00007860 <res 00000002>          tss.link:   resw 1
 24477 00007862 <res 00000002>          	    resw 1
 24478                                  ; tss offset 4	
 24479 00007864 <res 00000004>          tss.esp0:   resd 1
 24480 00007868 <res 00000002>          tss.ss0:    resw 1
 24481 0000786A <res 00000002>          	    resw 1	
 24482 0000786C <res 00000004>          tss.esp1:   resd 1
 24483 00007870 <res 00000002>          tss.ss1:    resw 1
 24484 00007872 <res 00000002>          	    resw 1 	
 24485 00007874 <res 00000004>          tss.esp2:   resd 1
 24486 00007878 <res 00000002>          tss.ss2:    resw 1
 24487 0000787A <res 00000002>          	    resw 1
 24488                                  ; tss offset 28
 24489 0000787C <res 00000004>          tss.CR3:    resd 1
 24490 00007880 <res 00000004>          tss.eip:    resd 1
 24491 00007884 <res 00000004>          tss.eflags: resd 1
 24492                                  ; tss offset 40
 24493 00007888 <res 00000004>          tss.eax:    resd 1		 		
 24494 0000788C <res 00000004>          tss.ecx:    resd 1
 24495 00007890 <res 00000004>          tss.edx:    resd 1
 24496 00007894 <res 00000004>          tss.ebx:    resd 1
 24497 00007898 <res 00000004>          tss.esp:    resd 1
 24498 0000789C <res 00000004>          tss.ebp:    resd 1
 24499 000078A0 <res 00000004>          tss.esi:    resd 1
 24500 000078A4 <res 00000004>          tss.edi:    resd 1
 24501                                  ; tss offset 72
 24502 000078A8 <res 00000002>          tss.ES:     resw 1
 24503 000078AA <res 00000002>          	    resw 1	
 24504 000078AC <res 00000002>          tss.CS:	    resw 1
 24505 000078AE <res 00000002>          	    resw 1
 24506 000078B0 <res 00000002>          tss.SS:	    resw 1
 24507 000078B2 <res 00000002>          	    resw 1
 24508 000078B4 <res 00000002>          tss.DS:	    resw 1
 24509 000078B6 <res 00000002>          	    resw 1
 24510 000078B8 <res 00000002>          tss.FS:	    resw 1
 24511 000078BA <res 00000002>          	    resw 1
 24512 000078BC <res 00000002>          tss.GS:	    resw 1
 24513 000078BE <res 00000002>          	    resw 1		
 24514 000078C0 <res 00000002>          tss.LDTR:   resw 1
 24515 000078C2 <res 00000002>          	    resw 1
 24516                                  ; tss offset 100		
 24517 000078C4 <res 00000002>          	    resw 1		
 24518 000078C6 <res 00000002>          tss.IOPB:   resw 1
 24519                                  ; tss offset 104 
 24520                                  tss_end:
 24521                                  
 24522 000078C8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
 24523                                  		    ; (Physical address = Virtual address)	 	
 24524 000078CC <res 00000004>          memory_size: resd 1 ; memory size in pages
 24525 000078D0 <res 00000004>          free_pages:  resd 1 ; number of free pages		
 24526 000078D4 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
 24527                                  		    ; first free page search
 24528 000078D8 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
 24529                                  		    ; next free page search will be
 24530                                  		    ; stopped after it. (end of M.A.T.)
 24531 000078DC <res 00000004>          first_page:  resd 1 ; offset value in M.A.T. which
 24532                                  		    ; first free page search
 24533                                  		    ; will be started on it. (for user)
 24534 000078E0 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
 24535                                  
 24536                                  ; 02/09/2014 (Retro UNIX 386 v1)
 24537                                  ; 04/12/2013 (Retro UNIX 8086 v1)
 24538 000078E4 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
 24539                                  			  ; NOTE: active page only	
 24540 000078E6 <res 00000002>          CURSOR_MODE: resw 1 ; 24/01/2016
 24541 000078E8 <res 00000010>          CURSOR_POSN: resw 8 ; cursor positions for video pages
 24542                                  ACTIVE_PAGE: 
 24543 000078F8 <res 00000001>          ptty: 	     resb 1 ; current tty
 24544                                  ; 01/07/2015 - 29/01/2016
 24545 000078F9 <res 00000001>          ccolor:	     resb 1 ; current color attribute
 24546                                  ; 26/10/2015
 24547                                  ; 07/09/2014
 24548 000078FA <res 00000014>          ttychr:      resw ntty+2 ; Character buffer (multiscreen)
 24549                                  
 24550                                  ; 21/08/2014
 24551 0000790E <res 00000004>          tcount:	     resd 1
 24552                                  
 24553                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
 24554 00007912 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
 24555                                  
 24556                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
 24557                                  ; (open mode locks for pseudo TTYs)
 24558                                  ; [ major tty locks (return error in any conflicts) ]
 24559 00007916 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
 24560                                  
 24561                                  ; 15/04/2015 (Retro UNIX 386 v1)
 24562                                  ; 22/09/2013 (Retro UNIX 8086 v1)
 24563 0000792A <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
 24564                                  ; 15/04/2015 (Retro UNIX 386 v1)
 24565                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
 24566                                  ;; 0 means serial port is not available 
 24567                                  ;;comprm: ; 25/06/2014
 24568 00007934 <res 00000001>          com1p:       resb 1  ;;0E3h
 24569 00007935 <res 00000001>          com2p:       resb 1  ;;0E3h
 24570                                  
 24571                                  ; 17/11/2015
 24572                                  ; request for response (from the terminal)	
 24573 00007936 <res 00000002>          req_resp:    resw 1 			
 24574                                  ; 07/11/2015
 24575 00007938 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
 24576                                  		    ; (0= COM1, 1= COM2)
 24577                                  ; 09/11/2015
 24578 00007939 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
 24579                                  ; 07/11/2015
 24580 0000793A <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
 24581 0000793C <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
 24582                                  
 24583                                  ; 22/08/2014 (RTC)
 24584                                  ; (Packed BCD)
 24585 0000793E <res 00000001>          time_seconds: resb 1
 24586 0000793F <res 00000001>          time_minutes: resb 1
 24587 00007940 <res 00000001>          time_hours:   resb 1
 24588 00007941 <res 00000001>          date_wday:    resb 1
 24589 00007942 <res 00000001>          date_day:     resb 1
 24590 00007943 <res 00000001>          date_month:   resb 1			
 24591 00007944 <res 00000001>          date_year:    resb 1
 24592 00007945 <res 00000001>          date_century: resb 1
 24593                                  
 24594                                  ; 24/01/2016
 24595 00007946 <res 00000004>          RTC_LH:	       resd 1
 24596 0000794A <res 00000001>          RTC_WAIT_FLAG: resb 1
 24597 0000794B <res 00000001>          USER_FLAG:     resb 1
 24598                                  
 24599                                  
 24600                                  %include 'diskbss.s'	; UNINITIALIZED DISK (BIOS) DATA
 24601                              <1> ; ****************************************************************************
 24602                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskbss.s
 24603                              <1> ; ----------------------------------------------------------------------------
 24604                              <1> ; Last Update: 24/01/2016
 24605                              <1> ; ----------------------------------------------------------------------------
 24606                              <1> ; Beginning: 24/01/2016
 24607                              <1> ; ----------------------------------------------------------------------------
 24608                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 24609                              <1> ; ----------------------------------------------------------------------------
 24610                              <1> ; Turkish Rational DOS
 24611                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
 24612                              <1> ;
 24613                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 24614                              <1> ; diskbss.inc (10/07/2015)
 24615                              <1> ;
 24616                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
 24617                              <1> ; ****************************************************************************
 24618                              <1> 
 24619                              <1> ; Retro UNIX 386 v1 Kernel - DISKBSS.INC
 24620                              <1> ; Last Modification: 10/07/2015
 24621                              <1> ;	(Unnitialized Disk Parameters Data section for 'DISKIO.INC') 
 24622                              <1> 
 24623                              <1> alignb 2
 24624                              <1> 
 24625                              <1> ;----------------------------------------
 24626                              <1> ;	TIMER DATA AREA 		:
 24627                              <1> ;----------------------------------------
 24628                              <1> 
 24629                              <1> TIMER_LH:	; 16/02/205
 24630 0000794C <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
 24631 0000794E <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
 24632 00007950 <res 00000001>      <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
 24633                              <1> 
 24634                              <1> ;----------------------------------------
 24635                              <1> ;	DISKETTE DATA AREAS		:
 24636                              <1> ;----------------------------------------
 24637                              <1> 
 24638 00007951 <res 00000001>      <1> SEEK_STATUS:	resb	1
 24639 00007952 <res 00000001>      <1> MOTOR_STATUS:	resb	1
 24640 00007953 <res 00000001>      <1> MOTOR_COUNT:	resb	1
 24641 00007954 <res 00000001>      <1> DSKETTE_STATUS:	resb	1
 24642 00007955 <res 00000007>      <1> NEC_STATUS:	resb	7
 24643                              <1> 
 24644                              <1> ;----------------------------------------
 24645                              <1> ;	ADDITIONAL MEDIA DATA		:
 24646                              <1> ;----------------------------------------
 24647                              <1> 
 24648 0000795C <res 00000001>      <1> LASTRATE:	resb 	1
 24649 0000795D <res 00000001>      <1> HF_STATUS:	resb 	1
 24650 0000795E <res 00000001>      <1> HF_ERROR:	resb 	1
 24651 0000795F <res 00000001>      <1> HF_INT_FLAG:	resb 	1
 24652 00007960 <res 00000001>      <1> HF_CNTRL:	resb 	1
 24653 00007961 <res 00000004>      <1> DSK_STATE:	resb 	4
 24654 00007965 <res 00000002>      <1> DSK_TRK:	resb 	2
 24655                              <1> 
 24656                              <1> ;----------------------------------------
 24657                              <1> ;	FIXED DISK DATA AREAS		:
 24658                              <1> ;----------------------------------------
 24659                              <1> 
 24660 00007967 <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
 24661 00007968 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
 24662 00007969 <res 00000001>      <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
 24663                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
 24664                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
 24665                              <1> ;port2_off	resb	1		; Hard idsk controller 2 - port offset
 24666                              <1> 
 24667 0000796A <res 00000002>      <1> alignb 4
 24668                              <1> 
 24669                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 24670                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 24671                              <1> HF_TBL_VEC: ; 22/12/2014	
 24672 0000796C <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 24673 00007970 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 24674 00007974 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
 24675 00007978 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
 24676                              <1> 
 24677                              <1> ; 03/01/2015
 24678 0000797C <res 00000001>      <1> LBAMode:     	resb	1
 24679                              <1> 
 24680                              <1> ; *****************************************************************************
 24681                                  
 24682                                  ;;; Real Mode Data (10/07/2015 - BSS)
 24683                                  
 24684                                  ;alignb 2
 24685                                  
 24686                                  ; 10/01/2016
 24687                                  %include 'trdoskx.s'	; UNINITIALIZED KERNEL (Logical Drive & FS) DATA
 24688                              <1> ; ****************************************************************************
 24689                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - UNINITIALIZED DATA : trdoskx.s
 24690                              <1> ; ----------------------------------------------------------------------------
 24691                              <1> ; Last Update: 01/02/2016
 24692                              <1> ; ----------------------------------------------------------------------------
 24693                              <1> ; Beginning: 04/01/2016
 24694                              <1> ; ----------------------------------------------------------------------------
 24695                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 24696                              <1> ; ----------------------------------------------------------------------------
 24697                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
 24698                              <1> ; TRDOS2.ASM (09/11/2011)
 24699                              <1> ; ****************************************************************************
 24700                              <1> ; DRV_INIT.ASM [26/09/2009] Last Update: 07/08/2011
 24701                              <1> ; MAINPROG.ASM [17/01/2004] Last Update: 09/11/2011
 24702                              <1> 
 24703 0000797D <res 00000003>      <1> alignb 4
 24704                              <1> 
 24705 00007980 <res 00000002>      <1> MainProgCfg_FileSize:   resw 1
 24706 00007982 <res 00000002>      <1> MainProgCfg_LineOffset: resw 1 
 24707                              <1> 
 24708 00007984 <res 00000004>      <1> Current_VolSerial: resd 1
 24709                              <1> 
 24710 00007988 <res 00000004>      <1> Current_Dir_FCluster: resd 1
 24711                              <1> 
 24712 0000798C <res 00000001>      <1> Current_Dir_Level: resb 1
 24713 0000798D <res 00000001>      <1> Current_FATType: resb 1
 24714 0000798E <res 00000001>      <1> Current_Drv: resb 1
 24715 0000798F <res 00000001>      <1> Current_Dir_Drv:   resb 1 ; '?'
 24716 00007990 <res 00000001>      <1>                    resb 1 ; ':'
 24717 00007991 <res 00000001>      <1> Current_Dir_Root:  resb 1 ; '/' 
 24718 00007992 <res 0000005A>      <1> Current_Directory: resb 90
 24719 000079EC <res 00000001>      <1> End_Of_Current_Dir_Str: resb 1
 24720 000079ED <res 00000001>      <1> Current_Dir_StrLen: resb 1   
 24721                              <1> 
 24722 000079EE <res 00000001>      <1> CursorColumn: 	resb 1
 24723 000079EF <res 00000001>      <1> CmdArgStart:    resb 1
 24724                              <1>         
 24725 000079F0 <res 00000050>      <1> CommandBuffer: 	resb 80
 24726                              <1> 
 24727 00007A40 <res 00000100>      <1> TextBuffer: resb 256
 24728                              <1> 
 24729                              <1> MasterBootBuff:
 24730 00007B40 <res 000001BE>      <1> MasterBootCode: resb 1BEh
 24731 00007CFE <res 00000040>      <1> PartitionTable: resb 64
 24732 00007D3E <res 00000002>      <1> MBIDCode: resw 1
 24733                              <1> 
 24734                              <1> PTable_Buffer:
 24735 00007D40 <res 00000040>      <1> PTable_hd0: resb 64
 24736 00007D80 <res 00000040>      <1> PTable_hd1: resb 64
 24737 00007DC0 <res 00000040>      <1> PTable_hd2: resb 64
 24738 00007E00 <res 00000040>      <1> PTable_hd3: resb 64
 24739 00007E40 <res 00000040>      <1> PTable_ep0: resb 64
 24740 00007E80 <res 00000040>      <1> PTable_ep1: resb 64
 24741 00007EC0 <res 00000040>      <1> PTable_ep2: resb 64
 24742 00007F00 <res 00000040>      <1> PTable_ep3: resb 64
 24743                              <1> 
 24744 00007F40 <res 00000001>      <1> Last_DOS_DiskNo: resb 1
 24745 00007F41 <res 00000001>      <1> HD_LBA_yes: resb 1
 24746 00007F42 <res 00000001>      <1> PP_Counter: resb 1
 24747 00007F43 <res 00000001>      <1> EP_Counter: resb 1
 24748                              <1> 
 24749 00007F44 <res 00000004>      <1> EP_StartSector: resd 1
 24750 00007F48 <res 00000004>      <1>                 resd 1
 24751 00007F4C <res 00000004>      <1>                 resd 1
 24752 00007F50 <res 00000004>      <1>                 resd 1
 24753                              <1> 
 24754 00007F54 <res 00000200>      <1> DOSBootSectorBuff: resb 512
 24755                              <1> 
 24756                              <1> FAT_BuffDescriptor:
 24757 00008154 <res 00000004>      <1> FAT_CurrentCluster: resd 1
 24758 00008158 <res 00000001>      <1> FAT_BuffValidData: resb 1
 24759 00008159 <res 00000001>      <1> FAT_BuffDrvName: resb 1
 24760 0000815A <res 00000002>      <1> FAT_BuffOffset: resw 1
 24761 0000815C <res 00000004>      <1> FAT_BuffSector: resd 1
 24762                              <1> 
 24763 00008160 <res 00000004>      <1> FAT_ClusterCounter: resd 1
 24764 00008164 <res 00000004>      <1> LastCluster: resd 1
 24765                              <1> 
 24766 00008168 <res 00000001>      <1> resb 1
 24767                              <1> 
 24768                              <1> Dir_BuffDescriptor:
 24769 00008169 <res 00000001>      <1> DirBuff_DRV: resb 1
 24770 0000816A <res 00000001>      <1> DirBuff_FATType: resb 1
 24771 0000816B <res 00000001>      <1> DirBuff_ValidData: resb 1
 24772 0000816C <res 00000002>      <1> DirBuff_CurrentEntry: resw 1
 24773 0000816E <res 00000002>      <1> DirBuff_LastEntry: resw 1
 24774 00008170 <res 00000004>      <1> DirBuff_Cluster: resd 1 
 24775 00008174 <res 00000002>      <1> DirBuffer_Size: resw 1
 24776 00008176 <res 00000002>      <1> DirBuff_EntryCounter: resw 1
 24777                              <1> 
 24778                              <1> ; 01/02/2016
 24779                              <1> ; these are on (real mode) segment 8000h and later
 24780                              <1> ; FAT_Buffer:	resb 1536 ; 3 sectors
 24781                              <1> ; Dir_Buffer:	resb 512*32
 24782                              <1> ; Logical_DOSDisks:  resb 6656 ; 26 * 256 bytes
 24783                              <1> 
 24784                              <1> ; 18/01/2016
 24785                              <1> 
 24786 00008178 <res 00000004>      <1> FreeClusterCount: resd 1
 24787                              <1> 
 24788 0000817C <res 00000004>      <1> VolSize_Unit1:   resd 1
 24789 00008180 <res 00000004>      <1> VolSize_Unit2:   resd 1
 24790                              <1> 
 24791 00008184 <res 00000004>      <1> Vol_Tot_Sec_Str_Start:	    resd 1
 24792 00008188 <res 0000000A>      <1> Vol_Tot_Sec_Str: 	    resb 10
 24793 00008192 <res 00000001>      <1> Vol_Tot_Sec_Str_End:	    resb 1
 24794 00008193 <res 00000001>      <1> resb 1
 24795 00008194 <res 00000004>      <1> Vol_Free_Sectors_Str_Start: resd 1
 24796 00008198 <res 0000000A>      <1> Vol_Free_Sectors_Str:	    resb 10				
 24797 000081A2 <res 00000001>      <1> Vol_Free_Sectors_Str_End:   resb 1
 24798 000081A3 <res 00000001>      <1> resb 1
 24799                              <1> 
 24800                              <1> ; 24/01/2016
 24801 000081A4 <res 00000080>      <1> PATH_Array:     resb 128
 24802                              <1> 
 24803                              <1> ; 29/01/2016
 24804 00008224 <res 00000001>      <1> Program_Exit:	resb 1 ; CMD_INTR.ASM  ; 09/11/2011
 24805                              <1> 
 24806                              <1> ; 31/01/2016
 24807 00008225 <res 00000001>      <1> retry_count: 	resb 1 ; DISK_IO.ASM ; 20/07/2011 (CHS_RetryCount)
 24808 00008226 <res 00000001>      <1> disk_rw_err: 	resb 1 ; DISK_IO.ASM ; 20/07/2011 (Disk_IO_err_code)
 24809 00008227 <res 00000004>      <1> sector_count:	resd 1 ; DISK_IO.ASM ; 20/07/2011 (Disk_RW_SectorCount)
 24810                                  ; 24/01/2016
 24811                                  %include 'ubss.s'	; UNINITIALIZED KERNEL (USER) DATA
 24812                              <1> ; ****************************************************************************
 24813                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - UNINITIALIZED USER DATA : ubss.s
 24814                              <1> ; ----------------------------------------------------------------------------
 24815                              <1> ; Last Update: 24/01/2016
 24816                              <1> ; ----------------------------------------------------------------------------
 24817                              <1> ; Beginning: 24/01/2016
 24818                              <1> ; ----------------------------------------------------------------------------
 24819                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
 24820                              <1> ; ----------------------------------------------------------------------------
 24821                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
 24822                              <1> ; ux.s (04/12/2015)
 24823                              <1> ; ****************************************************************************
 24824                              <1> 
 24825                              <1> ; Retro UNIX 386 v1 Kernel - ux.s
 24826                              <1> ; Last Modification: 04/12/2015
 24827                              <1> ;
 24828                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 24829                              <1> ; (Modified from 
 24830                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 24831                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 24832                              <1> ; ----------------------------------------------------------------------------
 24833                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 24834                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 24835                              <1> ; <Bell Laboratories (17/3/1972)>
 24836                              <1> ; <Preliminary Release of UNIX Implementation Document>
 24837                              <1> ; (Section E10 (17/3/1972) - ux.s)
 24838                              <1> ; ****************************************************************************
 24839                              <1> 
 24840 0000822B <res 00000001>      <1> alignb 2
 24841                              <1> 
 24842                              <1> inode:
 24843                              <1> 	; 11/03/2013. 
 24844                              <1> 	;Derived from UNIX v1 source code 'inode' structure (ux).
 24845                              <1> 	;i.
 24846                              <1> 
 24847 0000822C <res 00000002>      <1> 	i.flgs:	 resw 1
 24848 0000822E <res 00000001>      <1> 	i.nlks:	 resb 1
 24849 0000822F <res 00000001>      <1> 	i.uid:	 resb 1
 24850 00008230 <res 00000002>      <1>         i.size:  resw 1 ; size
 24851 00008232 <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
 24852 00008242 <res 00000004>      <1> 	i.ctim:	 resd 1
 24853 00008246 <res 00000004>      <1> 	i.mtim:	 resd 1
 24854 0000824A <res 00000002>      <1> 	i.rsvd:  resw 1 ; Reserved (ZERO/Undefined word for UNIX v1.)
 24855                              <1> 
 24856                              <1> I_SIZE	equ $ - inode 
 24857                              <1> 
 24858                              <1> process:
 24859                              <1> 	; 06/05/2015
 24860                              <1> 	; 11/03/2013 - 05/02/2014
 24861                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
 24862                              <1> 	;p.
 24863                              <1> 	
 24864 0000824C <res 00000020>      <1>         p.pid:   resw nproc
 24865 0000826C <res 00000020>      <1>         p.ppid:  resw nproc
 24866 0000828C <res 00000020>      <1>         p.break: resw nproc
 24867 000082AC <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
 24868 000082BC <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
 24869 000082CC <res 00000010>      <1> 	p.link:	 resb nproc
 24870 000082DC <res 00000010>      <1> 	p.stat:	 resb nproc
 24871                              <1> 
 24872                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 fetaure only !) 
 24873 000082EC <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
 24874                              <1> 			    ; 'user' structure	
 24875                              <1> 
 24876                              <1> 
 24877                              <1> P_SIZE	equ $ - process
 24878                              <1> 
 24879                              <1> 
 24880                              <1> ; fsp table (original UNIX v1)
 24881                              <1> ;
 24882                              <1> ;Entry
 24883                              <1> ;          15                                      0
 24884                              <1> ;  1     |---|---------------------------------------|
 24885                              <1> ;        |r/w|       i-number of open file           |
 24886                              <1> ;        |---|---------------------------------------| 
 24887                              <1> ;        |               device number               |
 24888                              <1> ;        |-------------------------------------------|
 24889                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
 24890                              <1> ;        |-------------------------------------------| 
 24891                              <1> ;        |  flag that says    | number of processes  |
 24892                              <1> ;        |   file deleted     | that have file open  |
 24893                              <1> ;        |-------------------------------------------| 
 24894                              <1> ;  2     |                                           |
 24895                              <1> ;        |-------------------------------------------| 
 24896                              <1> ;        |                                           |
 24897                              <1> ;        |-------------------------------------------|
 24898                              <1> ;        |                                           |
 24899                              <1> ;        |-------------------------------------------|
 24900                              <1> ;        |                                           |
 24901                              <1> ;        |-------------------------------------------| 
 24902                              <1> ;  3     |                                           | 
 24903                              <1> ;        |                                           |  
 24904                              <1> ;
 24905                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
 24906                              <1> 
 24907                              <1> 
 24908                              <1> ; 15/04/2015
 24909 0000832C <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
 24910 00008520 <res 00000018>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
 24911 00008538 <res 00000002>      <1> ii:	 resw 1
 24912 0000853A <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
 24913 0000853C <res 00000002>      <1> cdev:    resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
 24914                              <1> ; 18/05/2015
 24915                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
 24916                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
 24917                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
 24918                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
 24919                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
 24920                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
 24921                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
 24922                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
 24923                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
 24924                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
 24925                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
 24926 0000853E <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
 24927                              <1> 	        ; as above, for physical drives numbers in following table
 24928 0000853F <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
 24929                              <1> ; 15/04/2015
 24930 00008540 <res 00000001>      <1> active:	 resb 1 
 24931 00008541 <res 00000001>      <1> 	 resb 1 ; 09/06/2015
 24932 00008542 <res 00000002>      <1> mnti:	 resw 1
 24933 00008544 <res 00000002>      <1> mpid:	 resw 1
 24934 00008546 <res 00000002>      <1> rootdir: resw 1
 24935                              <1> ; 14/02/2014
 24936                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
 24937                              <1> ;		      Single level run queue
 24938                              <1> ;		      (in order to solve sleep/wakeup lock)
 24939 00008548 <res 00000002>      <1> runq:	 resw 1
 24940 0000854A <res 00000001>      <1> imod:	 resb 1
 24941 0000854B <res 00000001>      <1> smod:	 resb 1
 24942 0000854C <res 00000001>      <1> mmod:	 resb 1
 24943 0000854D <res 00000001>      <1> sysflg:	 resb 1
 24944                              <1> 
 24945 0000854E <res 00000002>      <1> alignb 4
 24946                              <1> 
 24947                              <1> user:
 24948                              <1> 	; 04/12/2015 
 24949                              <1> 	; 18/10/2015
 24950                              <1> 	; 12/10/2015
 24951                              <1> 	; 21/09/2015
 24952                              <1> 	; 24/07/2015
 24953                              <1> 	; 16/06/2015
 24954                              <1> 	; 09/06/2015
 24955                              <1> 	; 11/05/2015
 24956                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 24957                              <1> 	; 10/10/2013
 24958                              <1> 	; 11/03/2013. 
 24959                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
 24960                              <1> 	;u.
 24961                              <1> 
 24962 00008550 <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
 24963 00008554 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
 24964 00008558 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
 24965 0000855C <res 00000002>      <1> 	u.cdir:	  resw 1
 24966 0000855E <res 0000000A>      <1> 	u.fp:	  resb 10
 24967 00008568 <res 00000004>      <1> 	u.fofp:	  resd 1
 24968 0000856C <res 00000004>      <1> 	u.dirp:	  resd 1
 24969 00008570 <res 00000004>      <1> 	u.namep:  resd 1
 24970 00008574 <res 00000004>      <1> 	u.off:	  resd 1
 24971 00008578 <res 00000004>      <1> 	u.base:	  resd 1
 24972 0000857C <res 00000004>      <1> 	u.count:  resd 1
 24973 00008580 <res 00000004>      <1> 	u.nread:  resd 1
 24974 00008584 <res 00000004>      <1> 	u.break:  resd 1 ; break
 24975 00008588 <res 00000002>      <1> 	u.ttyp:	  resw 1 
 24976 0000858A <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
 24977                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
 24978 0000859A <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
 24979 0000859B <res 00000001>      <1> 	u.pri:	  resb 1 ; 
 24980 0000859C <res 00000002>      <1> 	u.intr:	  resw 1
 24981 0000859E <res 00000002>      <1> 	u.quit:	  resw 1
 24982                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
 24983 000085A0 <res 00000002>      <1> 	u.ilgins: resw 1
 24984 000085A2 <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
 24985 000085A4 <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
 24986 000085A5 <res 00000001>      <1> 	u.ruid:	  resb 1
 24987 000085A6 <res 00000001>      <1> 	u.bsys:	  resb 1
 24988 000085A7 <res 00000001>      <1> 	u.uno:	  resb 1
 24989 000085A8 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
 24990                              <1> 	; tty number (rtty, rcvt, wtty)
 24991 000085AC <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
 24992                              <1> 	; last error number
 24993 000085AD <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
 24994                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
 24995 000085B1 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
 24996 000085B5 <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
 24997 000085B9 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
 24998 000085BD <res 00000002>      <1> 	u.pcount: resw 1 ; 20/05/2015 (byte -transfer- count for page)
 24999                              <1> 	;u.pncount: resw 1 
 25000                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
 25001                              <1> 	;u.pnbase:  resd 1 
 25002                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
 25003                              <1> 			 ; 09/06/2015
 25004 000085BF <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
 25005 000085C0 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
 25006                              <1> 			 ; 24/07/2015 - 24/06/2015
 25007                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
 25008                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
 25009                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
 25010                              <1>  			 ; 24/06/2015	  	
 25011                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
 25012                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
 25013                              <1> 			 ; 21/09/2015 (debugging - page fault analyze)
 25014 000085C1 <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
 25015                              <1> 
 25016 000085C5 <res 00000003>      <1> alignb 4
 25017                              <1> 
 25018                              <1> U_SIZE	equ $ - user
 25019                              <1> 
 25020                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
 25021 000085C8 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
 25022 000085CC <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
 25023 000085D0 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
 25024 000085D4 <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
 25025 000085D6 <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
 25026 000085D8 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
 25027                              <1> 
 25028                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
 25029                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
 25030 000085DC <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
 25031                              <1> 
 25032                              <1> ;alignb 4
 25033                              <1> 
 25034                              <1> ; 22/08/2015
 25035 000085DD <res 00000820>      <1> buffer: resb nbuf * 520
 25036                              <1> 
 25037 00008DFD <res 00000008>      <1> sb0:	resd 2
 25038                              <1> ;s:
 25039                              <1> ; (root disk) super block buffer
 25040                              <1> systm:
 25041                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
 25042                              <1> 	; 11/03/2013. 
 25043                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
 25044                              <1> 	;s.
 25045                              <1> 
 25046 00008E05 <res 00000002>      <1> 	resw 1
 25047 00008E07 <res 00000168>      <1> 	resb 360 ; 2880 sectors ; original UNIX v1 value: 128
 25048 00008F6F <res 00000002>      <1> 	resw 1
 25049 00008F71 <res 00000020>      <1> 	resb 32	 ; 256+40 inodes ; original UNIX v1 value: 64
 25050 00008F91 <res 00000004>      <1> 	s.time:	 resd 1
 25051 00008F95 <res 00000004>      <1> 	s.syst:	 resd 1
 25052 00008F99 <res 00000004>      <1>         s.wait_: resd 1 ; wait
 25053 00008F9D <res 00000004>      <1> 	s.idlet: resd 1
 25054 00008FA1 <res 00000004>      <1> 	s.chrgt: resd 1
 25055 00008FA5 <res 00000002>      <1> 	s.drerr: resw 1
 25056                              <1> 
 25057                              <1> S_SIZE	equ $ - systm
 25058                              <1> 
 25059 00008FA7 <res 0000005E>      <1> 	resb 512-S_SIZE ; 03/06/2015	 
 25060                              <1> 
 25061 00009005 <res 00000008>      <1> sb1:	resd 2
 25062                              <1> ; (mounted disk) super block buffer
 25063                              <1> mount:	
 25064 0000900D <res 00000200>      <1> 	resb 512  ; 03/06/2015
 25065                              <1> 
 25066                              <1> ;/ ux -- unix
 25067                              <1> ;
 25068                              <1> ;systm:
 25069                              <1> ;
 25070                              <1> ;	.=.+2
 25071                              <1> ;	.=.+128.
 25072                              <1> ;	.=.+2
 25073                              <1> ;	.=.+64.
 25074                              <1> ;	s.time: .=.+4
 25075                              <1> ;	s.syst: .=.+4
 25076                              <1> ;	s.wait: .=.+4
 25077                              <1> ;	s.idlet:.=.+4
 25078                              <1> ;	s.chrgt:.=.+4
 25079                              <1> ;	s.drerr:.=.+2
 25080                              <1> ;inode:
 25081                              <1> ;	i.flgs: .=.+2
 25082                              <1> ;	i.nlks: .=.+1
 25083                              <1> ;	i.uid:  .=.+1
 25084                              <1> ;	i.size: .=.+2
 25085                              <1> ;	i.dskp: .=.+16.
 25086                              <1> ;	i.ctim: .=.+4
 25087                              <1> ;	i.mtim: .=.+4
 25088                              <1> ;	. = inode+32.
 25089                              <1> ;mount:	.=.+1024.
 25090                              <1> ;proc:
 25091                              <1> ;	p.pid:  .=.+[2*nproc]
 25092                              <1> ;	p.dska: .=.+[2*nproc]
 25093                              <1> ;	p.ppid: .=.+[2*nproc]
 25094                              <1> ;	p.break:.=.+[2*nproc]
 25095                              <1> ;	p.link: .=.+nproc
 25096                              <1> ;	p.stat: .=.+nproc
 25097                              <1> ;tty:
 25098                              <1> ;	. = .+[ntty*8.]
 25099                              <1> ;fsp:	.=.+[nfiles*8.]
 25100                              <1> ;bufp:	.=.+[nbuf*2]+6
 25101                              <1> ;sb0:	.=.+8
 25102                              <1> ;sb1:	.=.+8
 25103                              <1> ;swp:	.=.+8
 25104                              <1> ;ii:	.=.+2
 25105                              <1> ;idev:	.=.+2
 25106                              <1> ;cdev:	.=.+2
 25107                              <1> ;deverr: .=.+12.
 25108                              <1> ;active: .=.+2
 25109                              <1> ;rfap:	.=.+2
 25110                              <1> ;rkap:	.=.+2
 25111                              <1> ;tcap:	.=.+2
 25112                              <1> ;tcstate:.=.+2
 25113                              <1> ;tcerrc: .=.+2
 25114                              <1> ;mnti:	.=.+2
 25115                              <1> ;mntd:	.=.+2
 25116                              <1> ;mpid:	.=.+2
 25117                              <1> ;clockp: .=.+2
 25118                              <1> ;rootdir:.=.+2
 25119                              <1> ;toutt:	.=.+16.
 25120                              <1> ;touts: .=.+32.
 25121                              <1> ;runq:	.=.+6
 25122                              <1> ;
 25123                              <1> ;wlist:	.=.+40.
 25124                              <1> ;cc:	.=.+30.
 25125                              <1> ;cf:	.=.+31.
 25126                              <1> ;cl:	.=.+31.
 25127                              <1> ;clist:	.=.+510.
 25128                              <1> ;imod:	.=.+1
 25129                              <1> ;smod:	.=.+1
 25130                              <1> ;mmod:	.=.+1
 25131                              <1> ;uquant: .=.+1
 25132                              <1> ;sysflg: .=.+1
 25133                              <1> ;pptiflg:.=.+1
 25134                              <1> ;ttyoch: .=.+1
 25135                              <1> ; .even
 25136                              <1> ; .=.+100.; sstack:
 25137                              <1> ;buffer: .=.+[ntty*140.]
 25138                              <1> ;	.=.+[nbuf*520.]
 25139                              <1> ;
 25140                              <1> ; . = core-64.
 25141                              <1> ;user:
 25142                              <1> ;	u.sp:    .=.+2
 25143                              <1> ;	u.usp:   .=.+2
 25144                              <1> ;	u.r0:    .=.+2
 25145                              <1> ;	u.cdir:  .=.+2
 25146                              <1> ;	u.fp:    .=.+10.
 25147                              <1> ;	u.fofp:  .=.+2
 25148                              <1> ;	u.dirp:  .=.+2
 25149                              <1> ;	u.namep: .=.+2
 25150                              <1> ;	u.off:   .=.+2
 25151                              <1> ;	u.base:  .=.+2
 25152                              <1> ;	u.count: .=.+2
 25153                              <1> ;	u.nread: .=.+2
 25154                              <1> ;	u.break: .=.+2
 25155                              <1> ;	u.ttyp:  .=.+2
 25156                              <1> ;	u.dirbuf:.=.+10.
 25157                              <1> ;	u.pri:   .=.+2
 25158                              <1> ;	u.intr:  .=.+2
 25159                              <1> ;	u.quit:  .=.+2
 25160                              <1> ;	u.emt:   .=.+2
 25161                              <1> ;	u.ilgins:.=.+2
 25162                              <1> ;	u.cdev:  .=.+2
 25163                              <1> ;	u.uid:   .=.+1
 25164                              <1> ;	u.ruid:  .=.+1
 25165                              <1> ;	u.bsys:  .=.+1
 25166                              <1> ;	u.uno:   .=.+1
 25167                              <1> ;. = core
 25168                                  
 25169                                  ;; Memory (swap) Data (11/03/2015)
 25170                                  ; 09/03/2015
 25171 0000920D <res 00000002>          swpq_count: resw 1 ; count of pages on the swap queue
 25172 0000920F <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
 25173 00009213 <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 25174 00009217 <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 25175 0000921B <res 00000004>          swpd_next:  resd 1 ; next free page block
 25176 0000921F <res 00000004>          swpd_last:  resd 1 ; last swap page block	
 25177                                  
 25178 00009223 <res 00000001>          alignb 4
 25179                                  
 25180                                  ; 10/07/2015
 25181                                  ; 28/08/2014
 25182 00009224 <res 00000004>          error_code:	resd 1
 25183                                  ; 29/08/2014
 25184 00009228 <res 00000004>          FaultOffset: 	resd 1
 25185                                  ; 21/09/2015
 25186 0000922C <res 00000004>          PF_Count:	resd 1	; total page fault count
 25187                                  		       	; (for debugging - page fault analyze)
 25188                                  		 	; 'page_fault_handler' (memory.inc)
 25189                                  			; 'sysgeterr' (u9.s)
 25190                                  ;; 21/08/2015
 25191                                  ;;buffer: resb (nbuf*520) ;; sysdefs.inc, ux.s
 25192                                  ;; ((NOTE: nbuf = 6, buffer r/w problem/bug here !? when nbuf > 4))
 25193                                  
 25194                                  bss_end:
 25195                                  
 25196                                  ; 27/12/2013
 25197                                  _end:  ; end of kernel code
